From 6015755a01f5bffb0ec10ad8addc31fd41d8bf9a Mon Sep 17 00:00:00 2001
From: AcideFluorhydrique
<139669368+AcideFluorhydrique@users.noreply.github.com>
Date: Tue, 22 Sep 2026 15:42:04 +0800
Subject: [PATCH 01/11] Fix the world map's topology, and refuse saves made on
an older map
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The world map is stretched on purpose — Europe and Japan wide, the oceans
narrow — and the stretch itself cannot break topology: longitude and
latitude each map to the grid monotonically. What broke it was elsewhere.
Finland had no polygon. Scandinavia's east edge ran up the Gulf of Bothnia
and Europe's west edge ran north from St Petersburg, and everything between
21°E and 29°E came out as sea. Helsinki was one anchored hex, St Petersburg
and Murmansk took the rest, and Finland touched Latvia and Belarus across a
gulf that was not there. Finland is now drawn, the Gulf of Bothnia is sea,
the Gulf of Finland is carved as a strait, and 60–72°N gets proper rows
instead of 2.6° each. Kiruna, Sundsvall, Gothenburg and Oulu give Sweden and
Finland their own ground, so Oslo no longer owns central Sweden and
Copenhagen no longer owns the Swedish coast.
Straits were carved everywhere except on city hexes, so two cities facing
each other across one became a land bridge: Busan and Fukuoka were
neighbours and Japanese infantry could walk into Korea. The same happened
across Florida, the Irish Sea, Hormuz, Bab-el-Mandeb and the Red Sea. Island
groups (geodata.ISLANDS) now never touch other land, and pairs of mainland
polygons that a sea divides (geodata.SEAS: Arabia against Africa, Iran and
South Asia) never touch each other. When two cities would, the island city
moves to the nearest hex of its own island. Cities also snap only to land
on their own side of the water.
Several regions were simply missing: Jutland, the Indus valley and the
Himalayan border between India and China. The Middle East polygon started
off the Libyan coast, turning the Levantine Sea into land that joined
Alexandria to Syria. Those are drawn now. Hamhung gives North Korea its
north-east, which Shenyang used to own, and Guwahati gives India its
north-east, which Dhaka used to own. An island with no city goes to one
owner whole instead of being split tile by tile.
tools/topology.py writes the geography down as two lists, borders that must
exist and seas that must stay seas, and genworld now fails when the world
map breaks either one. CI regenerates the maps, so a coastline edit that
reopens a land bridge fails the build.
Every map changed, so tile and province indices in old saves point at the
wrong places. A save now records the map's fingerprint, and one that does
not match is refused with its own message instead of loading units into
the sea.
---
app/src/main/assets/maps/east_europe.map | 24 +-
app/src/main/assets/maps/europe.map | 148 ++--
app/src/main/assets/maps/north_africa.map | 68 +-
app/src/main/assets/maps/sea_asia.map | 26 +-
app/src/main/assets/maps/world.map | 781 +++++++++---------
.../assets/scenarios/campaign_cw_01_suez.scn | 20 +-
.../scenarios/campaign_cw_01_suez_west.scn | 20 +-
.../campaign_cw_03_central_front.scn | 44 +-
.../campaign_cw_03_central_front_pact.scn | 44 +-
.../scenarios/campaign_ww2_01_poland.scn | 27 +-
.../scenarios/campaign_ww2_01_poland_axis.scn | 27 +-
.../scenarios/campaign_ww2_02_france.scn | 28 +-
.../campaign_ww2_02_france_allies.scn | 28 +-
.../scenarios/campaign_ww2_03_desert.scn | 4 +-
.../scenarios/campaign_ww2_03_desert_axis.scn | 4 +-
.../scenarios/campaign_ww2_06_philippines.scn | 20 +-
.../campaign_ww2_06_philippines_axis.scn | 20 +-
.../main/assets/scenarios/conquest_1939.scn | 345 ++++----
.../main/assets/scenarios/conquest_1943.scn | 328 ++++----
.../main/assets/scenarios/conquest_1950.scn | 475 ++++++-----
.../main/assets/scenarios/conquest_1980.scn | 649 ++++++++-------
.../acidefluorhydrique/mapconquer/GameView.kt | 17 +-
.../mapconquer/game/SaveGame.kt | 29 +-
.../mapconquer/world/WorldMap.kt | 33 +
app/src/main/res/values-b+zh+Hans/strings.xml | 8 +
app/src/main/res/values-b+zh+Hant/strings.xml | 8 +
app/src/main/res/values/strings.xml | 8 +
.../mapconquer/world/MapAssetTest.kt | 52 ++
tools/genstrings.py | 2 +
tools/genworld.py | 70 +-
tools/geodata.py | 131 ++-
tools/hexraster.py | 151 +++-
tools/places.py | 9 +-
tools/scenarios.py | 6 +-
tools/topology.py | 114 +++
35 files changed, 2156 insertions(+), 1612 deletions(-)
create mode 100644 tools/topology.py
diff --git a/app/src/main/assets/maps/east_europe.map b/app/src/main/assets/maps/east_europe.map
index 7441ba6..a6f62b5 100644
--- a/app/src/main/assets/maps/east_europe.map
+++ b/app/src/main/assets/maps/east_europe.map
@@ -7,14 +7,14 @@ cols 48
rows 34
[terrain]
-ffffff-~~~~~~~~-----ffffffffffffffffffffffffffff
-fffff-~~~~~~~~-fffffffffffffffffffffffffffffffff
-fffff-~~~~~~~--fffffffffffffffffffffffffffffffff
-ffff-~~~~~~~-fffffffffffffffffffffffffffffffffff
--fff-~~~~~~--ffffffffffffffffffffffffrrrrfffffff
+ffffff-~~~~~~-------ffffffffffffffffffffffffffff
+fffff-~~~~~~-fffffffffffffffffffffffffffffffffff
+fffff-~~~~~~-fffffffffffffffffffffffffffffffffff
+ffff-~~~~~~-ffffffffffffffffffffffffffffffffffff
+-fff-~~~~~~-fffffffffffffffffffffffffrrrrfffffff
fff-~~~~~~-fffffffffffffffffffffffffrrrrrfffffff
-----~~~~~~-ffffffffffffffffffffffffffrrrrrffffff
-~~~~~~~~--fffffffffffffffffffffffffffrrrrrffffff
+----~~~~~--ffffffffffffffffffffffffffrrrrrffffff
+~~~~~~~~-ffffffffffffffffffffffffffffrrrrrffffff
---------fffffffffffffffffffffffffffffrrrrrfffff
ffffffffffffffffff::::::::::::::::::ffrrrrrfffff
-fffff:::::::::::::::::::::::::::::::::rrrrfffff
@@ -44,13 +44,13 @@ hhhrrr^^^^^^^^^^^^^-~~~~----~~~~-----hhhhhh--~~~
[provinces]
6:9 14:-1 8:16 7:15 9:17 4:18
-5:9 10:-1 1:10 11:16 8:15 8:17 5:18
-5:9 10:-1 2:10 10:16 8:15 9:17 4:18
-4:9 9:-1 4:10 9:16 9:15 8:17 5:18
-1:-1 3:9 9:-1 5:10 8:16 9:15 9:17 4:18
+5:9 8:-1 3:10 11:16 8:15 8:17 5:18
+5:9 8:-1 4:10 10:16 8:15 9:17 4:18
+4:9 8:-1 5:10 9:16 9:15 8:17 5:18
+1:-1 3:9 8:-1 6:10 8:16 9:15 9:17 4:18
3:9 8:-1 7:10 3:14 4:16 10:15 8:17 5:18
11:-1 6:10 6:14 2:16 10:15 9:17 4:18
-10:-1 6:10 8:14 11:15 8:17 5:18
+9:-1 7:10 8:14 11:15 8:17 5:18
9:-1 1:3 6:10 9:14 11:15 7:17 5:18
4:2 7:3 4:10 9:14 1:11 10:15 8:17 5:18
1:-1 3:2 9:3 1:10 10:14 2:11 1:13 9:15 7:17 5:18
diff --git a/app/src/main/assets/maps/europe.map b/app/src/main/assets/maps/europe.map
index e8599af..79bdc0f 100644
--- a/app/src/main/assets/maps/europe.map
+++ b/app/src/main/assets/maps/europe.map
@@ -7,18 +7,18 @@ cols 54
rows 42
[terrain]
-~~~~~~~~~~~~~~~~-^^^^^^^^hhhhfff-~~~~~~~~-ffffffffffff
-~~~~~~~~~~~~~~~-^^^^^^^hhhhffff-~~~--~~~-fffffffffffff
-~~~~~~~~~~~~~~~~-^^^^^hhhhfffff-~~~-f-~~--ffffffffffff
-~~~~~~~~~~~~~~~-^^^^hhhhffffff-~~~~-----ffffffffffffff
-~~~~~~~---~~~~~~-hhhhhhfffffff-~~~~~-fffffffffffffffff
-~~~~~--ff-~~~~~~-------ffffff-~~~~~-ffffffffffffffffff
-~~~~~-ffff-~~~~~~~~~~~~-fffff-~~~~~-ffffffffffffffffff
-~~~~~-ffff-~~~~~~~~~~~~-ffff-~~~~~-ffffffffffffffffffr
-~~~~~~-fff-~~~~~~~~~~~~~-ff--~~~~--fffffffffffffffffff
-~~~~---fff-~~~~~~~~~~~~-f--~~~~~-fffffffffffffffffffff
-~~---f-fff-~~~~~~~~~~~-----------fffffffffffffffffffff
-~-fff--ff-~~~~~~~~~~--ff-fffffffffffff:::::::::::::::f
+~~~~~~~~~~~~~~~~-^^^^^^^^hhhhf-~-fffffffffffffffffffff
+~~~~~~~~~~~~~~~-^^^^^^^hhhhff--~-fffffffffffffffffffff
+~~~~~~~~~~~~~~~~-^^^^^hhhhfffff-~-ffff----ffffffffffff
+~~~~~~~~~~~~~~~-^^^^hhhhffffff-~~-------ffffffffffffff
+~~~~~~~---~~~~~~-hhhhhhfffffff-~~~~-ffffffffffffffffff
+~~~~~--ff-~~~~~~-------ffffff-~~~~-fffffffffffffffffff
+~~~~~-ffff-~~~~~~~~~~-fffffff-~~~~-fffffffffffffffffff
+~~~~~-ffff-~~~~~~~~-----ffff-~~~~-fffffffffffffffffffr
+~~~~~~-fff-~~~~~~~~-fff--ff--~~~~-ffffffffffffffffffff
+~~~~---fff-~~~~~~~~-ff--f--~~~~~-fffffffffffffffffffff
+~~---f-fff-~~~~~~~~~-f-----------fffffffffffffffffffff
+~-fff--ff-~~~~~~~~~-f-ff-fffffffffffff:::::::::::::::f
~-ffff-fff-~~~~~~----ffffffff:::::::::::::::::::::::::
-ffff--ff-~--~~--ffff:::::::::::::::::::::::::::::::::
~-fff-~-ff--f-~-r:::::::::::::::::::::::::::::::::::::
@@ -46,53 +46,53 @@ rows 42
~~-........-~~----------...--~~~-...-~-..............h
~-.......-----hh^^^^^h----.-~~~~-..-~~--............hh
~~----------hh^^^^^^^^h-~~--~~~~~---~~~~---..........h
-~~~~------hh^^^^^^^^^hh-~~~~~~~~~~~---~~~~---.......hh
-~~~~-hhhhhh^^^^^^^^^^^h-~~~~~~~~~~~-..-~~~--.........h
-~~~-hhhhh^^^^^^^^^^hhh.-~~~~~~~~~~~---~~~-...........-
+~~~~------hh^^^^^^^^^hh-~~~~~~~~~~~---~~~~-----.....hh
+~~~~-hhhhhh^^^^^^^^^^^h-~~~~~~~~~~~-..-~~~~~~~~-.....h
+~~~-hhhhh^^^^^^^^^^hhh.-~~~~~~~~~~~---~~~~~~~~-......-
[provinces]
-17:-1 9:31 6:30 10:-1 7:40 5:39
-16:-1 10:31 5:30 10:-1 7:40 6:39
-17:-1 9:31 5:30 5:-1 1:33 5:-1 6:40 6:39
-16:-1 10:31 4:30 10:-1 7:40 7:39
-17:-1 9:31 4:30 7:-1 2:34 8:40 7:39
-7:-1 2:2 14:-1 3:31 3:30 7:-1 3:34 7:40 8:39
-6:-1 4:2 14:-1 1:31 2:32 2:30 7:-1 4:34 6:40 8:39
-6:-1 4:2 14:-1 3:32 1:30 7:-1 5:34 5:40 9:39
-7:-1 3:2 15:-1 2:32 8:-1 5:34 3:38 2:40 9:39
-7:-1 3:2 14:-1 1:32 8:-1 5:34 6:38 10:39
-5:-1 1:3 1:-1 3:2 23:-1 1:23 4:34 7:38 9:39
-2:-1 3:3 2:-1 2:1 13:-1 1:18 1:17 1:-1 4:17 6:23 1:34 8:38 1:35 9:39
-2:-1 4:3 1:-1 3:1 11:-1 3:18 5:17 7:23 8:38 1:35 2:37 7:39
-1:-1 4:3 2:-1 2:1 8:-1 2:8 4:18 6:17 7:23 6:38 3:35 5:37 4:39
-2:-1 3:3 3:-1 2:1 2:-1 1:0 3:-1 3:8 1:20 3:18 6:17 8:23 4:38 4:35 7:37 2:39
-1:-1 1:3 5:-1 1:1 5:0 2:-1 2:7 3:20 2:18 7:17 7:23 3:38 6:35 9:37
-7:-1 1:1 5:0 2:-1 3:7 4:20 3:17 4:22 4:24 4:23 1:38 7:35 9:37
-14:-1 1:4 2:7 4:20 2:19 5:22 1:21 8:24 8:35 8:37 1:41
-12:-1 4:4 2:7 2:20 2:16 3:19 2:22 3:21 7:24 8:35 7:37 2:41
-8:-1 9:4 1:7 3:16 4:19 1:22 4:21 7:24 8:35 5:37 4:41
-7:-1 10:4 5:16 4:19 4:21 3:25 4:24 1:26 6:35 2:36 4:37 4:41
-8:-1 2:6 6:4 1:5 5:16 4:19 3:21 7:25 3:26 1:35 6:36 2:37 6:41
-9:-1 3:6 3:4 3:5 3:16 2:14 3:19 4:21 6:25 4:26 7:36 7:41
-10:-1 3:6 5:5 1:16 5:14 2:19 3:21 3:25 3:27 5:26 7:36 7:41
-10:-1 3:6 6:5 7:14 3:21 1:25 5:27 6:26 4:-1 2:36 4:-1 3:41
-10:-1 3:6 6:5 6:14 1:13 1:21 8:27 5:26 13:-1 1:41
-10:-1 4:6 5:5 3:14 2:-1 2:13 1:-1 7:27 2:28 4:26 11:-1 2:43 1:-1
-10:-1 3:6 1:10 5:5 3:-1 4:13 1:-1 6:27 3:28 3:26 12:-1 3:43
-2:-1 1:12 6:9 4:6 4:10 6:-1 3:13 3:-1 4:27 4:28 3:26 12:-1 2:43
-2:-1 1:12 7:9 1:6 4:10 8:-1 3:13 5:-1 1:27 5:28 2:26 14:-1 1:43
-3:-1 1:12 7:9 4:10 9:-1 2:13 2:15 3:-1 1:27 6:28 2:26 13:-1 1:43
-2:-1 2:12 7:9 3:10 6:-1 1:13 4:-1 4:15 2:-1 7:28 1:26 1:-1 3:42 11:43
-3:-1 2:12 7:9 2:10 6:-1 1:45 1:13 4:-1 4:15 2:-1 6:28 3:-1 2:42 11:43
-2:-1 3:12 7:9 8:-1 1:45 5:-1 3:15 2:-1 6:29 1:-1 2:44 2:42 12:43
-3:-1 2:12 1:11 6:9 8:-1 1:45 6:-1 2:15 3:-1 5:29 4:44 2:42 11:43
-2:-1 2:12 3:11 4:9 16:-1 1:15 4:-1 4:29 2:-1 4:44 12:43
-3:-1 1:12 5:11 2:9 13:-1 1:45 2:15 6:-1 3:29 3:-1 3:44 12:43
-2:-1 1:12 6:11 5:-1 4:46 4:45 4:-1 1:15 6:-1 2:29 5:-1 2:44 12:43
-12:-1 6:46 5:45 20:-1 11:43
-10:-1 8:46 5:45 22:-1 9:43
-5:-1 13:46 5:45 13:-1 2:29 6:-1 10:43
-4:-1 14:46 5:45 19:-1 11:43 1:-1
+17:-1 9:32 4:30 3:-1 7:35 9:42 5:41
+16:-1 10:32 3:30 4:-1 7:35 8:42 6:41
+17:-1 9:32 5:30 3:-1 4:35 4:-1 6:42 6:41
+16:-1 10:32 4:30 10:-1 7:42 7:41
+17:-1 7:32 2:31 4:30 6:-1 3:36 8:42 7:41
+7:-1 2:2 14:-1 3:31 3:30 6:-1 4:36 7:42 8:41
+6:-1 4:2 12:-1 5:31 2:30 6:-1 5:36 6:42 8:41
+6:-1 4:2 14:-1 1:31 2:33 1:30 6:-1 6:36 5:42 9:41
+7:-1 3:2 10:-1 3:34 2:-1 2:33 7:-1 6:36 3:40 2:42 9:41
+7:-1 3:2 10:-1 2:34 2:-1 1:33 8:-1 5:36 6:40 10:41
+5:-1 1:3 1:-1 3:2 11:-1 1:18 11:-1 1:23 4:36 7:40 9:41
+2:-1 3:3 2:-1 2:1 11:-1 1:18 1:-1 1:18 1:17 1:-1 4:17 6:23 1:36 8:40 1:37 9:41
+2:-1 4:3 1:-1 3:1 11:-1 3:18 5:17 7:23 8:40 1:37 2:39 7:41
+1:-1 4:3 2:-1 2:1 8:-1 2:8 4:18 6:17 7:23 6:40 3:37 5:39 4:41
+2:-1 3:3 3:-1 2:1 2:-1 1:0 3:-1 3:8 1:20 3:18 6:17 8:23 4:40 4:37 7:39 2:41
+1:-1 1:3 5:-1 1:1 5:0 2:-1 2:7 3:20 2:18 7:17 7:23 3:40 6:37 9:39
+7:-1 1:1 5:0 2:-1 3:7 4:20 3:17 4:22 4:24 4:23 1:40 7:37 9:39
+14:-1 1:4 2:7 4:20 2:19 5:22 1:21 8:24 8:37 8:39 1:43
+12:-1 4:4 2:7 2:20 2:16 3:19 2:22 3:21 7:24 8:37 7:39 2:43
+8:-1 9:4 1:7 3:16 4:19 1:22 4:21 7:24 8:37 5:39 4:43
+7:-1 10:4 5:16 4:19 4:21 3:25 4:24 1:26 6:37 2:38 4:39 4:43
+8:-1 2:6 6:4 1:5 5:16 4:19 3:21 7:25 3:26 1:37 6:38 2:39 6:43
+9:-1 3:6 3:4 3:5 3:16 2:14 3:19 4:21 6:25 4:26 7:38 7:43
+10:-1 3:6 5:5 1:16 5:14 2:19 3:21 3:25 3:27 5:26 7:38 7:43
+10:-1 3:6 6:5 7:14 3:21 1:25 5:27 6:26 4:-1 2:38 4:-1 3:43
+10:-1 3:6 6:5 6:14 1:13 1:21 8:27 5:26 13:-1 1:43
+10:-1 4:6 5:5 3:14 2:-1 2:13 1:-1 7:27 2:28 4:26 11:-1 2:45 1:-1
+10:-1 3:6 1:10 5:5 3:-1 4:13 1:-1 6:27 3:28 3:26 12:-1 3:45
+2:-1 1:12 6:9 4:6 4:10 6:-1 3:13 3:-1 4:27 4:28 3:26 12:-1 2:45
+2:-1 1:12 7:9 1:6 4:10 8:-1 3:13 5:-1 1:27 5:28 2:26 14:-1 1:45
+3:-1 1:12 7:9 4:10 9:-1 2:13 2:15 3:-1 1:27 6:28 2:26 13:-1 1:45
+2:-1 2:12 7:9 3:10 6:-1 1:47 4:-1 4:15 2:-1 7:28 1:26 1:-1 3:44 11:45
+3:-1 2:12 7:9 2:10 6:-1 2:47 4:-1 4:15 2:-1 6:28 3:-1 2:44 11:45
+2:-1 3:12 7:9 8:-1 1:47 5:-1 3:15 2:-1 6:29 1:-1 2:46 2:44 12:45
+3:-1 2:12 1:11 6:9 8:-1 1:47 6:-1 2:15 3:-1 5:29 4:46 2:44 11:45
+2:-1 2:12 3:11 4:9 16:-1 1:15 4:-1 4:29 2:-1 4:46 12:45
+3:-1 1:12 5:11 2:9 13:-1 3:47 6:-1 3:29 3:-1 3:46 12:45
+2:-1 1:12 6:11 5:-1 4:48 4:47 4:-1 1:47 6:-1 2:29 5:-1 2:46 12:45
+12:-1 6:48 5:47 20:-1 11:45
+10:-1 8:48 5:47 24:-1 7:45
+5:-1 13:48 5:47 13:-1 2:29 10:-1 6:45
+4:-1 14:48 5:47 24:-1 6:45 1:-1
[meta]
0|prov_london|4|11,15
@@ -126,19 +126,21 @@ rows 42
28|prov_sofia|1|35,28
29|prov_athens|2|35,36
30|prov_stockholm|2|29,3
-31|prov_oslo|2|22,3
-32|prov_copenhagen|2|24,9
-33|prov_helsinki|2|36,2
-34|prov_riga|1|35,7
-35|prov_kyiv|3|41,17
-36|prov_odesa|2|42,23
-37|prov_kharkiv|2|47,17
-38|prov_minsk|2|39,12
-39|prov_moscow|4|49,9
-40|prov_petersburg|3|41,3
-41|prov_rostov|2|51,22
-42|prov_istanbul|3|40,31
-43|prov_ankara|2|44,33
-44|prov_izmir|2|38,35
-45|prov_tunis|2|21,37
-46|prov_algiers|2|14,37
+31|prov_gothenburg|1|23,6
+32|prov_oslo|2|22,3
+33|prov_copenhagen|2|24,9
+34|prov_aarhus|1|22,8
+35|prov_helsinki|2|36,2
+36|prov_riga|1|35,7
+37|prov_kyiv|3|41,17
+38|prov_odesa|2|42,23
+39|prov_kharkiv|2|47,17
+40|prov_minsk|2|39,12
+41|prov_moscow|4|49,9
+42|prov_petersburg|3|41,3
+43|prov_rostov|2|51,22
+44|prov_istanbul|3|40,31
+45|prov_ankara|2|44,33
+46|prov_izmir|2|38,35
+47|prov_tunis|2|21,37
+48|prov_algiers|2|14,37
diff --git a/app/src/main/assets/maps/north_africa.map b/app/src/main/assets/maps/north_africa.map
index 3197cc3..c7fa970 100644
--- a/app/src/main/assets/maps/north_africa.map
+++ b/app/src/main/assets/maps/north_africa.map
@@ -7,19 +7,19 @@ cols 54
rows 36
[terrain]
-~~~~-..-------~~~~~~~~~~~~~-..-~-.....----............
+~~~~-..-------~~~~~~~~~~~~~-..-~-.--------............
~~~-.........-~~~~~~~~~~~---.-~~-....-..............hh
~~~~-........-~-----------..--~~~-...---.............h
~~~~-....------h^^^^^^hh----~~~~~-.--~~-............hh
-~~~~~-------hh^^^^^^^^^h-~~~~~~~~~--~~~~------.......h
-~~~~~--hhhh^^^^^^^^^^^hh-~~~~~~~~~~~~~~~~--..........-
-~~~~~-hh^^^^^^^^^^^hhhh..---~~~~~~~~~~~~--............
-~~~~-^^^^^^^^^^hhhhh.......--~~~~~~~~~--.............-
-~~~~-^^^^^^^^^hhh............--~~~~----...............
-~~~-^^^^^^^hhh................-----.......rr--........
-~~--hhhhhhdddddddddddddddddddddddddd......rr:--.......
-~-...hdddddddddddddddddddddddddddddddd....rr:.-..ddddd
---.ddddddddddddddddddddddddddddddddddddd..rr:.-.dddddd
+~~~~~-------hh^^^^^^^^^h-~~~~~~~~~--~~~~--------.....h
+~~~~~--hhhh^^^^^^^^^^^hh-~~~~~~~~~~~~~~~~~~~~~-......-
+~~~~~-hh^^^^^^^^^^^hhhh..---~~~~~~~~~~~~~~~~~~~-......
+~~~~-^^^^^^^^^^hhhhh.......--~~~~~~~~~~~~~~~~~-......-
+~~~~-^^^^^^^^^hhh............--~~~~------------.......
+~~~-^^^^^^^hhh................-----.......rr..........
+~~--hhhhhhdddddddddddddddddddddddddd......rr:.........
+~-...hdddddddddddddddddddddddddddddddd....rr:....ddddd
+--.ddddddddddddddddddddddddddddddddddddd..rr:.--dddddd
ddddddddddddddddddddddddddddddddddddddddd.rr:.-.dddddd
ddddddddddddddddddddddddddddddddddddddddddrr:..-dddddd
ddddddddddddddddddddddddddddddddddddddddddrr:..-ddddd-
@@ -27,13 +27,13 @@ ddddddddddddddddddddddddddddddddddddddddddrr:..-ddddd-
dddddddddddddddddddddddddddddddddddddddddddrrd..-ddddd
ddddddddddddddddddddddddddddddddddddddddddd:rdd..-dddd
dddddddddddddddddddddddddddddddddddddddddddrrdd..-dddd
-.dddddddddddddddddddddddddddddddddddddddddddrrdd..-ddd
-..ddddddddddddddddddddddddddddddddddddddddddrrd..--ddd
-.....dddddddddddddddddddddddddddddddddddddddrr....--dd
-......ddddddddddddddddddddddddddddddddddddd.rr....--dd
-..........dddddddddddddddddddddddddddddddd..rr.....--.
-................ddddddddddddddddddddddd.....rr.h..-~-.
-............................................rrhhhhh---
+.dddddddddddddddddddddddddddddddddddddddddddrrdd..--dd
+..ddddddddddddddddddddddddddddddddddddddddddrrd..-~-dd
+.....dddddddddddddddddddddddddddddddddddddddrr....-~-d
+......ddddddddddddddddddddddddddddddddddddd.rr....-~-d
+..........dddddddddddddddddddddddddddddddd..rr.....-~-
+................ddddddddddddddddddddddd.....rr.h..-~~~
+............................................rrhhhhh--~
............................................rrh^^hh.-~
............................................rr^^^^hhh-
...........................................rrh^^^^^hh.
@@ -45,19 +45,19 @@ dddddddddddddddddddddddddddddddddddddddddddrrdd..-dddd
~~-jjjjjjjjjjjjjjjjjj...........................hh^^^-
[provinces]
-5:-1 1:1 1:0 21:-1 2:12 3:-1 5:2 4:-1 12:3
-4:-1 2:1 7:0 15:-1 1:11 4:-1 4:2 1:-1 4:4 8:3 4:5
+5:-1 1:1 1:0 21:-1 2:12 3:-1 1:2 8:-1 12:3
+4:-1 2:1 7:0 15:-1 1:12 4:-1 4:2 1:-1 4:4 8:3 4:5
5:-1 1:1 7:0 13:-1 2:12 6:-1 3:2 3:-1 3:4 6:3 5:5
5:-1 4:0 6:-1 4:13 5:12 10:-1 1:2 5:-1 2:4 5:3 7:5
-12:-1 7:13 5:12 22:-1 8:5
-7:-1 4:15 8:13 5:12 19:-1 1:9 9:5 1:-1
-6:-1 6:15 7:13 4:12 2:11 17:-1 2:9 10:5
-5:-1 6:15 8:13 2:12 6:11 13:-1 3:9 1:8 3:6 6:5 1:-1
-5:-1 7:15 7:13 2:12 8:11 10:-1 4:9 2:8 4:6 5:5
-4:-1 7:15 8:13 1:12 10:11 5:-1 7:9 2:8 2:-1 3:6 5:5
-4:-1 8:15 7:13 1:12 13:11 9:9 3:8 2:-1 3:6 4:5
-2:-1 9:15 3:13 6:14 13:11 8:9 5:8 1:-1 3:6 4:5
-2:-1 10:15 1:13 9:14 11:11 8:9 5:8 1:-1 4:6 2:5 1:7
+12:-1 7:13 5:12 24:-1 6:5
+7:-1 4:15 8:13 5:12 23:-1 6:5 1:-1
+6:-1 6:15 7:13 4:12 2:11 23:-1 6:5
+5:-1 6:15 8:13 2:12 6:11 20:-1 6:5 1:-1
+5:-1 7:15 7:13 2:12 8:11 18:-1 2:6 5:5
+4:-1 7:15 8:13 1:12 10:11 5:-1 7:9 3:8 4:6 5:5
+4:-1 8:15 7:13 1:12 13:11 9:9 4:8 4:6 4:5
+2:-1 9:15 3:13 6:14 13:11 8:9 4:8 5:6 4:5
+2:-1 10:15 1:13 9:14 11:11 8:9 5:8 2:-1 3:6 2:5 1:7
11:15 11:14 11:11 7:9 5:8 1:10 1:-1 4:6 3:7
11:15 12:14 10:11 7:9 3:8 4:10 1:-1 6:7
10:15 14:14 9:11 6:9 2:8 6:10 1:-1 5:7 1:-1
@@ -65,12 +65,12 @@ dddddddddddddddddddddddddddddddddddddddddddrrdd..-dddd
3:15 8:17 16:14 6:11 5:9 10:10 1:-1 5:7
3:16 9:17 17:14 3:11 2:20 4:9 11:10 1:-1 4:7
3:16 10:17 15:14 6:20 3:9 12:10 1:-1 4:7
-4:16 10:17 13:14 8:20 2:9 13:10 1:-1 3:7
-4:16 10:17 11:14 1:19 9:20 12:21 2:10 2:-1 3:7
-5:16 10:17 9:14 2:19 10:20 14:21 2:-1 2:7
-5:16 10:17 7:14 3:19 10:20 15:21 2:-1 2:7
-6:16 10:17 3:14 6:19 11:20 15:21 2:-1 1:7
-7:16 9:17 1:14 8:19 10:20 15:21 3:-1 1:7
+4:16 10:17 13:14 8:20 2:9 13:10 2:-1 2:7
+4:16 10:17 11:14 1:19 9:20 12:21 2:10 3:-1 2:7
+5:16 10:17 9:14 2:19 10:20 14:21 3:-1 1:7
+5:16 10:17 7:14 3:19 10:20 15:21 3:-1 1:7
+6:16 10:17 3:14 6:19 11:20 15:21 3:-1
+7:16 9:17 1:14 8:19 10:20 15:21 4:-1
8:16 9:17 8:19 11:20 15:21 3:-1
8:16 8:17 9:19 11:20 13:21 3:22 2:-1
10:16 6:17 9:19 12:20 11:21 5:22 1:-1
diff --git a/app/src/main/assets/maps/sea_asia.map b/app/src/main/assets/maps/sea_asia.map
index 62010fd..725a58f 100644
--- a/app/src/main/assets/maps/sea_asia.map
+++ b/app/src/main/assets/maps/sea_asia.map
@@ -33,14 +33,14 @@ rows 40
~-jj--jjj-~~~~--jjjjjj-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~-jjj-jj-~~~~-jjjjjjj-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~-jjj--j-~~~-jjjjjjjj-------~~~~~~~~~~~~~~~~~~~~~~~~~
-~~~-jjj---~~~-jjjjjjjjjjj....-~~~~~~~~~~~~~~~~~~~~~~~~
-~~~-jjj--~~~~-jjjjjjjjjjj...-~~~~--~~~~~~~~~~~~~~~~~~~
-~~~~-jjjj-~~~~-jjjjjjjjjj....-~~~-j------~~~~~~~~~~~~~
+~~~-jjj---~~~-jjjjjjjj-jj....-~~~~~~~~~~~~~~~~~~~~~~~~
+~~~-jjj--~~~~-jjjjjjjj-jj...-~~~~--~~~~~~~~~~~~~~~~~~~
+~~~~-jjjj-~~~~-jjjjjjj-jj....-~~~-j------~~~~~~~~~~~~~
~~~~-jjjj-~~~-jjjjjjjj-jj...-~~~~-jjjhhh-----~~~~~~~~~
~~~~~-jjjj-~~~-jjjjjjj--jj..-~~~~-jjj^^^^^hhh--~~~~~~~
~~~~~--jjj-~~~---------jjj.-~~~~~-jj^^^^^^^^^^--~~~~~~
~~~~~~~-jjj--~~~~~~~~~-....-~~~~~-jjj^^^^^^^^^^^--~~~~
-~~~~~~~---jj------~~~~-----~~~~~~--jjjj^^^^^^^^^^-~~~~
+~~~~~~~----j------~~~~-----~~~~~~--jjjj^^^^^^^^^^-~~~~
~~~~~~~~~~-:::::-.-~~~~~~~~~~~~~~~~--jjjjjjjj^^^^^-~~~
~~~~~~~~~~--::::::-~~~~~~~~~~~~~~~~~--.jjjjjjjj^^^--~~
~~~~~~~~~~~~------.-~~~~~~~~~~~~~~~~~~----jjjjjjjhhh-~
@@ -75,20 +75,20 @@ rows 40
2:-1 2:17 2:-1 3:12 7:-1 6:18 32:-1
3:-1 3:17 1:-1 2:12 6:-1 7:18 32:-1
3:-1 3:17 2:-1 1:14 5:-1 8:18 32:-1
-4:-1 3:17 7:-1 10:18 5:19 25:-1
-4:-1 3:17 7:-1 9:18 5:19 26:-1
-5:-1 3:17 1:15 6:-1 8:18 6:19 5:-1 1:22 19:-1
-5:-1 2:17 2:15 5:-1 8:18 1:-1 5:19 6:-1 6:22 14:-1
-6:-1 4:15 5:-1 7:18 2:-1 4:19 6:-1 11:22 9:-1
-7:-1 3:15 13:-1 4:19 7:-1 12:22 8:-1
-8:-1 3:15 12:-1 4:19 7:-1 14:22 6:-1
-10:-1 2:15 23:-1 14:22 5:-1
+4:-1 3:17 7:-1 8:18 1:-1 6:19 25:-1
+4:-1 3:17 7:-1 8:18 1:-1 5:19 26:-1
+5:-1 4:17 6:-1 7:18 1:-1 6:19 5:-1 1:22 19:-1
+5:-1 4:17 5:-1 8:18 1:-1 5:19 6:-1 6:22 14:-1
+6:-1 4:17 5:-1 7:18 2:-1 4:19 6:-1 11:22 9:-1
+7:-1 3:17 13:-1 4:19 7:-1 12:22 8:-1
+8:-1 3:17 12:-1 4:19 7:-1 14:22 6:-1
+11:-1 1:15 23:-1 14:22 5:-1
11:-1 4:15 1:16 1:-1 1:16 19:-1 13:22 4:-1
12:-1 2:15 4:16 20:-1 12:22 4:-1
18:-1 1:16 23:-1 10:22 2:-1
49:-1 3:22 2:-1
54:-1
-35:-1 1:19 1:22 5:-1 3:22 9:-1
+35:-1 2:22 5:-1 3:22 9:-1
[meta]
0|prov_guangzhou|3|17,3
diff --git a/app/src/main/assets/maps/world.map b/app/src/main/assets/maps/world.map
index 32f0cad..cc5c1fe 100644
--- a/app/src/main/assets/maps/world.map
+++ b/app/src/main/assets/maps/world.map
@@ -8,399 +8,406 @@ rows 76
wrap x
[terrain]
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-**********-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-------------~~~~~~~~~~~~~~~~~~~~~
-~~~~~~~~~~~~~~~~~~~~~~~--~~~~--********-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~------************-----------------~~~~~
-~~--------~~~~~~~~~~~---t---~~~-ttttttt-~~~~~~~~~~~~~~~~~--------~--~~~~~~~~~----tttttttttttttttttttttttttttttttttt----~
-~-ttttttt------------tttttt--~~-tttttt-~~~~~~~~~~~~~~~---^^^^^^t--t----------^^ttttttttttttttttttttttttttttttttttttttt--
-~-ttttttttttttttttttttttttttt-~-ttttt----~~~~~~~~~~~~--^^^^^tt--ttttttt-tttttt^^ttrrtttttttttttttttttttttttttttttttttttt
--fh^^hhffffffffffff----ffffff-~-fff---ff-~~~~~~~~~---^^^^hhf--~-ffffffffffffh^^hffrrfffffffffffffffffffffffffffffffffff-
-~-fh^^^hfffffffffff-~~~-fffff-~~--f-~~---~~~~~~~~~-^^^^hhfff-~----fffffffffffh^^hffrffffffffffffffffffffhhhhhhhhfffff^f-
--ffh-^^hffffffffff-~~~~-fffff-~~~--~~~~~~~~~--~~~-^^hhfffff-~-ffffffffffffffh^^hfffrffffffffffffffhhhhhhhhhhhhhhhhffh--~
-~-fh--^^hffffffffff-----ffffff-~~~~~~~~~~~~~-f-~~~----ffff--~--ffffffffffffffh^hffffrffffffffffhhhhhh^^^^^^^^^^^^hhff^-~
--ff-~-^hhfffffffffffffffffffff-~~~~~~~~~~~~-ff-~~~~~~-fff-~~-fffffffffffrrffh^^hffffrffffffhhhhhh^^^^^^^^^^^^^^^^hh-h-~~
-~-f-~~-^hhffffffffffffffffffff-~~~~~~~~~~~~~-ff-~~~~~~--f-~~-ffffffffffffrrffh^hffffrrffffhhhhh^^^^^^^^^^^^^^^^^^h----~~
--f-~~-^^hhffffffffffffffffffff-~~~~~~~~~~----f-~~~~~~-f-----ffffffffffffrrffh^^-ffffrffffhh^^^^^^^^^^^^^^^^^^^^^h-~-h-~~
-~--~~~-^^hfffffffffffffffffffff-~~~~~~~~~-ff-ff-~~~---fffffffff::::::::::rrffh^hf-fffrffffh^^^^^^^^^^^^^hhhhhhhhh-~~--~~
-~~~~~~-^hhfffffffffffffffffffff-~~~~~~~~-fffff-~~--ffff::::::::::::::::::rffh^^fff-fffffhh^^^^^^^^^^hhhhhhhhhhhh-~~-h-~~
-~~~~~~~-^hhffffffffffffffffffff--~~~~~~~~-f--ff---r:::::::::::::::::::::::rffh^hffffffhhhhh^^^^^^hhhhhhhfffffffff-~~-h-~
-~~~~~~-^^hhfffffffffffffffffffff-~~~~~~~~--~-ff:-rr:::::::hh::::::::::::::rff^^ffffffhh^^^^^^^hhhhhhfffffffffffff-~~--~~
-~~~~~~~-^^hhffffffffffffffffffff-~~~~~~~~~~~~----::rr:hhhhh^hhh:::::::::ffrffh^hffffffh^^------hhffffffffffffffff-~~~~~~
-~~~~~~~-^^hhffffffffffffffffffff-~~~~~~~~~~~--f:::hrrhhhhh^^^^hh::::::::ffrffhhffffffh^^--^^hffffffffffffffffffff-~~~~~~
-~~~~~~~-^^^hhfffffffffffffffffff-~~~~~~~~~~~-fff:hhh^^^^^^^^^^^hh::::::::fffffffffffff^^^^^^hffffffffffffffffff---~~~~~~
-~~~~~~~-^^^hhfffffffffffffhfff--~~~~~~~~~~~~--ffhh^^^^^^^^^^^^^^h::::::::frffffffffffhhhhhhhfffffffffffffffff--~~~~~~~~~
-~~~~~~~-^^^^hhfff:::fffffhhhff-~~~~~~~~~~~~~~~-ffh^^^^^^^^^^^^^^hh-:::fhfff-ffffffffffhhhffffffffffffffffffff-~~--~~~~~~
-~~~~~~~-^^^^hhff::r---ffh^^hf-~~~~~~~~~~~~~~~-ffhh^^^hh-hr^^^^^^--------hhf--ffffhhhhhhhhfdddddddfffffffffff-~~-f--~~~~~
-~~~~~~~-h^^^^hh.:::r-~---^^h-.-~~~~~~~~~~~-----hhhhh--hh-hhrrr^^-~~~~~-^^^---....h^^^^^^^.dddddddd.........-.-~~-..-~~~~
-~~~~~~~-^^^^^hh.:::r---h-^^---~~~~~~~~~~~-...^^^^h--~-..--..hhhh-~~~~~-^^^-~-....^^^-^^^h.dddddddd.........--~~-..-~~~~~
-~~~~~~~-h^^^^^^h:::r:::-^^^-~~~~~~~~~~~~~-...h^^^--~---..--...hh--------^^^--.dddh^^-^^^h.ddddddddd.........-~~-.h-~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~---~~~~-********-~~~~~~~~~~~~~~~~~~~~~--~~~~~~~~~~~~~~~~----------*********------------------~~~~
+~--------~~~~~~~~~~~~--tt---~~-ttttttt-~~~~~~~~~~~~~~~~~-----t---~--~~~~~~~~~--tttttttttttttttttttttttttttttttttttt---~~
+~-ttttttt-------------tttttt-~~-tttttt-~~~~~~~~~~~~~~~~--^^^^^^tt--t---~~-----^^tttttttttttttttttttttttttttttttttttttt--
+-ttttttttttttttttttttttttttt-~~-ttttt---~~~~~~~~~~~~~~-^^^^^^ttttttttt---tttt^^tttttttttttttttttttttttttttttttttttttttt-
+~-fh^hhffffffffffffffffffffff-~~-ffff--f-~~~~~~~~~~~~~-^^^^hh-fffffffffffffffh^^hfrrffffffffffffffffffffffffffffffffffff
+-fh^^hfffffffffffffff--ffffff-~--fff-~-f-~~~~~~~~~~~--^^^^hh--ffffffffffffffh^^hffrffffffffffffffffffffffffffffffffffff-
+~-h^^^hfffffffffffff--~-fffff-~-ffff-~-f-~~~~~~~~~~--^^^^hh--ffffffffffffffffh^^hffrfffffffffffffffffffffffffffffffffhff
+-fh^^^hffffffffffff-~~~-fffff-~--ff-~~--~~~~~~~~~~-^^^^^hh--ffffffffffffffffh^^hffrrfffffffffffffffffffffffffffffffffhf-
+~-fh^^^hfffffffffff-~~~-fffff-~~~-f-~~~~~~~~~~~~~~-^^^^hhf---ffffffffffffffffh^^hffrfffffffffffffffffffffhhhhhhhfffff^f-
+-fh^^^^hffffffffff-~~~~-fffff-~~~--~~~~~~~~~~~~~~-^^^hhffff---f--fffffffffffh^^hfffrffffffffffffffffhhhhhhhhhhhhhhffh^-~
+~-fh--^hhffffffffff-~~~-ffffff-~~~~~~~~~~~~~---~~~-hhhhffff-~----ffffffffffffh^^ffffrffffffffffffhhhhhhh^^^^^^^^hhhff^-~
+-ff-~-^hhfffffffff-----ffffff-~~~~~~~~~~~~~-ff-~~~----ffff-~-fffffffffffffffh^^hfffrrffffffffhhhhhhh^^^^^^^^^^^^^hh-h-~~
+~-ff-~-^hfffffffffffffffffffff-~~~~~~~~~~~~~-ff-~~~~---fff-~-fffffffffffrrfffh^hffffrffffffhhhhhh^^^^^^^^^^^^^^^^hh---~~
+-ff-~-^hhfffffffffffffffffffff-~~~~~~~~~~~--ff-~~~~-fff-----ffffffffffffrrffh^^-ffffrfffffhhh^^^^^^^^^^^^^^^^^^^^---h-~~
+~---~~-^hhfffffffffffffffffffff-~~~~~~~~~--f-ff-~~~~-f-----fffffffffff::frrffh^--ffffrffffh^^^^^^^^^^^^^^^^^^^^^h-~~--~~
+~~~~~~-^hhfffffffffffffffffffff-~~~~~~~~-fff-f-~~----fffff:::::::::::::::rffh^^ffffffffffh^^^^^^^^^^^^hhhhhhhhhh-~~-^-~~
+~~~~~~~-^hhffffffffffffffffffff-~~~~~~~~~-ff-ff---ff::::::::::::::::::::::rffh^hfff-fffhhhh^^^^^^^^hhhhhhhhhhhhhf-~~-^-~
+~~~~~~-^^hhfffffffffffffffffff--~~~~~~~~-f---ff:-rr::::::::::::::::::::::rrff^^fffffffhh^^^^^^^hhhhhhffffffffffff-~~--~~
+~~~~~~~-^^hhffffffffffffffffff-f-~~~~~~~~--~~-----:r::::::hhhh:::::::::::frffh^hffffffh^^^---hhhhhfffffffffffffff-~~~~~~
+~~~~~~-^^^hhfffffffffffffffff-ff-~~~~~~~~~~~---::::rhhhhhh^^^^h:::::::::ffrffhhffffffh^^--^^hhfffffffffffffffffff-~~~~~~
+~~~~~~~-^^^hhfffffffffffffffff-f-~~~~~~~~~~~-fff:hhhr^^^^^^^^^^h:::::::::fffffhfffffff^^-^^^hhffffffffffffffffff--~~~~~~
+~~~~~~~-^^^hhfffffffffffffffff--~~~~~~~~~~~~-fffhh^^^^^^^^^^^^^hh::::::::frffffffffffh^^hhhhfffffffffffffffff---~~~~~~~~
+~~~~~~~-^^^^hhfff::ffffffhhhff-~~~~~~~~~~~~~~--ffh^^^^^^^^^^^^^^hh-::::ffff-ffffffffffhhhffffffffffffffffffff-~~--~~~~~~
+~~~~~~~-^^^^hhff::r--fffh^^hf-~~~~~~~~~~~~~~~-ffh^^^^^hhhr^^^^^^--------hhf-fffffhhhhhhhhfdddddfffffffffffff-~~-f--~~~~~
+~~~~~~~-^^^^^hhf:::r-----^^h-f-~~~~~~~~~~~-----hhhhhh-hh-hhrr^^^-~~~~~-^^----ffffhhhh^^^hfddddddddffffffffff--~~-ff-~~~~
+~~~~~~~-^^^^^hh.::::---h-^^---~~~~~~~~~~~-...^^^^h----..--..hhhh-~~~~~-^^^-~-....^^^-^^^h.dddddddd.........-.-~-..-~~~~~
+~~~~~~~-h^^^^^^h:::r:::-^^^-~~~~~~~~~~~~~-...h^^^^-~---..--...hh--------^^^--.dddh^^-^^^h.ddddddddd.........--~-.h-~~~~~
~~~~~~~-^^^^^^hh:::r::h^^^-~~~~~~~~~~~~~~-....hhh-~-.--...-....-.......hhh^h-ddd.h--^^^d...ddddddd.........-~~--^-~~~~~~
-~~~~~~~~-^d^^^^h::::::h^^^-~~~~~~~~~~~~~~-......--~~--~-..-....--........hh--.ddd--~-dddh..........:.......-~~-.^^-~~~~~
-~~~~~~~-^^d^^^^h:::r::^^^-~~~~~~~~~~~~~~-......-~~~~~~--.---..-.........h^h--ddd--~-ddddhhh.......::::.-...-~-.^^-~~~~~~
-~~~~~~~~-^dd^^^hh:::r:^^^-~~~~~~~~~~~~~~~-.....--------..-~-..--........h^^-.-dd-h--ddddhhhh.......::r---..-~-hh^h-~~~~~
-~~~~~~~~-^dd^^^h:::r:h^^h-~~~~~~~~~~~~~~~-.-----h^^^^h---~~-.-~-.......hh^^h.d--^^^^^^^^hhhh.r....:rr-~~-..--h^^^-~~~~~~
-~~~~~~~~~-^dd^^^h:::rh^^h-~~~~~~~~~~~~~~~~-----h^^^^^^-~~~~~--~~----....h^^^...-^^^-^^^^^^^hhrrrrrrrr:-~~-.--.^^h-~~~~~~
-~~~~~~~~~-^d^^^h.:.rh^^h-~~~~~~~~~~~~~~~~~-hhh^^^^^^^h--~~~~~~~~--......h^^hd..h^^^-^^^^^^^hh.rrrrr:::-~~-.-..hh.-~~~~~~
-~~~~~~~~~-^dd^^^h...r^^h-~~~~~~~~~~~~~~~~~-^^^^^^^hhhh..-~~~~~~--........h^^hdd.^^h--^^^^^^^hh.....::::-~~-.-..---~~~~~~
-~~~~~~~~~-ddh^^hh..r^^h-~~~~~~~~~~~~~~~~~-^^^^^^hhh.....--~~~--..........h^^dddhhh---^^^^^^hh.....::::.-~~-.---~~~~~~~~~
-~~~~~~~~~~-.h^^^h...r^h-~~~~~~~~~~~~~~~~~~-^^^^hh.........----.--.r.......h^^dd.h.-h^-^^^^^^hh.....:rrr.-~~-.-~~~~~~~~~~
--~~~~~~~~~-.h^^hh..rhh.-~~~~~~~~~~~~~~~~--^hhhh..ddddddddd-......r:-......h^^dd..:-h^-^^^^^hh.rrrrrrrr.-~~~--~~~~~~~~~~~
-.-~~~~~~~~~-.h^^h..----.-~~~~~~~~~~~~~~~-..dddddddddddddddddddd...r.-.ddddd-^^d.---hr^-^^^^^hrrr.......-~~~~~~~~~~~~~~~~
--~~~~~~~~~~-h^^d..-~~-..-~~~~~~~~~~~~~~-dddddddddddddddddddddddddr:..ddddddd-^h--::hrh^^^^^h..........--~~~~~~~~~~~~~~~~
-~~~~~~~~~~~~-.^^h.-~~~-.-~~~~~~~~~~~~~~-ddddddddddddddddddddddddddr..ddddddddh^--.d..:rhhh-h.........--.-~~~~~~~~~~~~~~~
-~~~~~~~~~~~~-h^^h-~---.--~~~~~~~~~~~~~~-ddddddddddddddddddddddddddr..ddddddddh.--....::r.--.........--.-~~~~~~~~~~~~~~~~
-~~--~~~~~~~~~-h^^h--.-...-~~~~~~~~~~~~~-ddddddddddddddddddddddddddrr..-ddddddd--~-......--.-.-::..-.--.-~~~~~~~~~~~~~~~~
-~-.-~~~~~~~~~--^^h--.---.---~~~~~~~~~~-.ddddddddddddddddddddddddddrdd.-dddddd-~~~-.....-~-j-j::.----~--~~~~~~~~~~~~~~~~~
-~~--~~~~~~~~~~~--^^h.-~~--..-~~~~~~~~~~-...ddddddddddddddddddddddddr..--dddd.-~~~~-...--~~-jjj::.-~~~-.--~~~~~~~~~~~~~~~
-~~~~~~~~~~~~~~~~-^^hj-~~~---~~~~~~~~~~-........ddddddddddddddddd..r...--..d.-~~~~-...-~~~-jjj::.-~~~~-..-~~~~~~~~~~~~~~~
-~~~~~~~~~~~~~~~~~---.j-~~~~~~~~~~~~~~~~-...........................rhhh--...-~~~~~-...-~~~-jjj::.-~~~-...-~~~~~~~~~~~~~~
-~~~~~~~~~~~~~~~~~~~--j-~~----~~~~~~~~~~-..........................r^^^hh----~~~~~~-..-~~~~--j::j-~~~~-...-~~~~~~~~~~~~~~
-~~~~~~~~~~~~~~~~~~~~~-j---hh.--~~~~~~~~-..........................rh^^^^h...-~~~~~~-.-~~~~~-jj::-~~~~-....-~~~~~~~~~~~~~
-~~~~~~~~~~~~~~~~~~~~~-.j-^^h..-~~~~~~~~-...........................h^^^^h...-~~~~~~---~~~~~-j.--~~~~~-...-~~~~~~~~~~~~~~
-~~~~~~~~~~~~~~~~~~~~~~---^^^...--~~~~~~~-jjjjjjjjj...................h^^^h..-~~~~~~~-.-~~~~-.--~~~~--~-...-~~~~~~~~~~~~~
-~~~~~~~~~~~~~~~~~~~~~~~-h^^h....-~~~~~~~--jjjjjj-j-jj................h^^^h.-~~~~~~~~--~~~~--j-~~~--.-~----~~~~~~~~~~~~~~
-~~~~~~~~~~~~~~~~~~~~~~~-h^^h..j..-~~~~~~~~-----------.....jj..........hhhh.-~~~~~~~~~~~~~~-jjj-~--jjj-~~~~~~~~~~~~~~~~~~
-~~~~~~~~~~~~~~~~~~~~~~~-^^jjjjj.--~~~~~~~~~~~~~~~~~~-jjjjjjjjjjj..........-~~~~~~~~~~~~~~~-j-j--jjjjj----~~~~~~~~~~~~~~~
-~~~~~~~~~~~~~~~~~~~~~~~-^^jjjjjjj.-~~~~~~~~~~~~~~~~~-.jjjjjjjjjr..........-~~~~~~~~~~~~~~~~-j--~-jjjjjj..-~~----~~~~~~~~
-~~~~~~~~~~~~~~~~~~~~~~-h^hjjjjjrr.--~~~~~~~~~~~~~~~~-jjjjjjjrrjj........--~~~~~~~~~~~~~~~~~-jj-~-jjjj-j.-~~-jhh----~~~~~
-~~~~~~~~~~~~~~~~~~~~~~-h^^jrrrrjjj..-~~~~~~~~~~~~~~~~-jjjrrrjjjj........-~~~~~~~~~~~~~~~~~~~-jj----j--j.-~~-j^^^^^^--~~~
-~~~~~~~~~~~~~~~~~~~~~~-^^jjjjjjjj...--~~~~~~~~~~~~~~~-rrjjjjjjj........-~~~~~~~~~~~~~~~~~~~~--:j-----.--~~~--jjj^^^^-~~~
-~~~~~~~~~~~~~~~~~~~~~~~-^^hjjjjjj.....-~~~~~~~~~~~~~~~-.................-~~~~~~~~~~~~~~~~~~~~~----..---~~~~~~--jjjjj-~~~
-~~~~~~~~~~~~~~~~~~~~~~~-^^hjjjjj....--~~~~~~~~~~~~~~~~-................-~~~~~~~~~~~~~~~~~~~~~~~~~---~~~~~~---------.-~~~
-~~~~~~~~~~~~~~~~~~~~~~~-h^^h.....::..-~~~~~~~~~~~~~~~~-................-~---~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-.......---~~~
-~~~~~~~~~~~~~~~~~~~~~~~--^^h....::..-~~~~~~~~~~~~~~~~-...............--~-..-~~~~~~~~~~~~~~~~~~~~~~~~~~~~---.......-~~~~~
-~~~~~~~~~~~~~~~~~~~~~~~~~--^h....::.-~~~~~~~~~~~~~~~~~-..............-~~~-..-~~~~~~~~~~~~~~~~~~~~~~~~~---..........-~~~~
-~~~~~~~~~~~~~~~~~~~~~~~~~~-^h...::.-~~~~~~~~~~~~~~~~~~-d............-~~~-..-~~~~~~~~~~~~~~~~~~~~~~~---............h-~~~~
-~~~~~~~~~~~~~~~~~~~~~~~~~~-^h...r::.-~~~~~~~~~~~~~~~~~~-d.ddddd......-~~~-..-~~~~~~~~~~~~~~~~~~~~~--..ddddddddd...h^-~~~
-~~~~~~~~~~~~~~~~~~~~~~~~~-^^h..r...-~~~~~~~~~~~~~~~~~~~-dddddd..h^^--~~~~-.-~~~~~~~~~~~~~~~~~~~~~-...dddddddddd...h^-~~~
-~~~~~~~~~~~~~~~~~~~~~~~~~~-^^..r..--~~~~~~~~~~~~~~~~~~~~-dddddd.h^^h-~~~~~--~~~~~~~~~~~~~~~~~~~~~~-..ddddddddddd...hh-~~
-~~~~~~~~~~~~~~~~~~~~~~~~~~-^h.r..-~~~~~~~~~~~~~~~~~~~~~~-.ddd..h^^--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-...ddddddddd....h.-~~
-~~~~~~~~~~~~~~~~~~~~~~~~~~-^^....-~~~~~~~~~~~~~~~~~~~~~~~-....h^^^-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-...dddddddd.....^-~~
-~~~~~~~~~~~~~~~~~~~~~~~~~-^^h:r.-~~~~~~~~~~~~~~~~~~~~~~~~-....hh--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-................h-~~~
-~~~~~~~~~~~~~~~~~~~~~~~~~~-^^::.-~~~~~~~~~~~~~~~~~~~~~~~~-....---~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-...-------.....h^-~~
-~~~~~~~~~~~~~~~~~~~~~~~~~-^^h::-~~~~~~~~~~~~~~~~~~~~~~~~~-----~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~----~~~~~~--...h^-~--
-~~~~~~~~~~~~~~~~~~~~~~~~~-^^h.--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~------~-h
-~~~~~~~~~~~~~~~~~~~~~~~~~-^^h-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-.--^-
+~~~~~~~~-^d^^^^h::::::h^^^-~~~~~~~~~~~~~~-......--~~--~--.-....--........hh--.ddd--~-dddh..........:.......-~~-.^^-~~~~~
+~~~~~~~-^^d^^^^h:::r::^^^-~~~~~~~~~~~~~~-......-~~~~~~--.---..-.........h^h--ddd----ddddhhh.......::::.--..-~-.^^-~~~~~~
+~~~~~~~~-^dd^^^hh:::r:^^^-~~~~~~~~~~~~~~~-.....--------..-~-..--........h^^-..dd-h^-ddddhhhh.......::r---..-~-h^^h-~~~~~
+~~~~~~~~-^dd^^^h.::r:^^^h-~~~~~~~~~~~~~~~-------h^^^^h---~~---~-.......hh^^h.d--^^^^^^^^^hhhhr....:rr:-~-..--h^^h-~~~~~~
+~~~~~~~~~-^dd^^^h:::rh^^h-~~~~~~~~~~~~~~~~~----h^^^^^^-~~~~~~~~~-----...h^^^...-^^^^^^^^^^^hhrrrrrrrr:-~~-..-.h^h-~~~~~~
+~~~~~~~~~-^d^^^h.:.rh^^h-~~~~~~~~~~~~~~~~~-hhh^^^^^^hh--~~~~~~~~~~~-....h^^hdd.h^^^^^^^^^^^hh..rrrr:::-~~---..hh.-~~~~~~
+~~~~~~~~~-^dd^^^h...r^^h-~~~~~~~~~~~~~~~~~-^^^^^^^hhh...-~~~~~~~~~~~-....h^^hdd.^hh^^^^^^^^^hh.....::::-~~-.-..---~~~~~~
+~~~~~~~~~-d.h^^hh..rh^h-~~~~~~~~~~~~~~~~~-^^^^^^hh......--~~--------.....h^^ddd.hhh^^^^^^^^hh.....::::r-~~-.---~~~~~~~~~
+~~~~~~~~~~-.h^^^h...rhh.-~~~~~~~~~~~~~~~~-^^^^^hh.........---.....-.......h^^dd...:h^^^^^^^^hh....rrrrr.-~~--~~~~~~~~~~~
+-~~~~~~~~~-.h^^dh..r.h.-~~~~~~~~~~~~~~~~-hhhhdddddddddddddddd....r:.......h^^dd..:hh^^^^^^^hhrrrrrrrr..-~~~~~~~~~~~~~~~~
+.-~~~~~~~~~-.h^^h..----.-~~~~~~~~~~~~~~~-.dddddddddddddddddddddd..r.-dddddd-^^^...:hr^^^^^^^hr.........-~~~~~~~~~~~~~~~~
+-~~~~~~~~~~-.h^^.--~~~-.-~~~~~~~~~~~~~~-dddddddddddddddddddddddddr:.-dddddd----..:::hr^^^^hh.........---~~~~~~~~~~~~~~~~
+~~--~~~~~~~~-.h^^.-~~~---~~~~~~~~~~~~~~-ddddddddddddddddddddddddddrd.-dddddddhh--.d..:hrhh-..........--.-~~~~~~~~~~~~~~~
+~-.-~~~~~~~~-.^^^-~---.--~~~~~~~~~~~~~~-ddddddddddddddddddddddddddrd.-ddddddd.-~--.....r.-.........---.-~~~~~~~~~~~~~~~~
+~~--~~~~~~~~~--^^^--.--..---~~~~~~~~~~~-dddddddddddddddddddddddddddrd.-dddddd..-~~-....---..-.::.---~~--~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~--^^-..----..-~~~~~~~~~~-...ddddddddddddddddddddddddr...-ddddd..-~~-....-~~-jjj::.-~~~~----~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~--^^j-~~~---~~~~~~~~~~~-.....dddddddddddddddddddd..r...--.dd.--~~~-...-~~-.jjj::.-~~~-...-~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~--hj-~~~~~~~~~~~~~~~~-..............ddddddddd....rhhh--....-~~~~~-..-~~~--jj::j-~~~~-...-~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~-----~~--~~~~~~~~~~~-...........................r^^hh--.--~~~~~-...-~~~-jjj::-~~~~-....-~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~-j-~-h---~~~~~~~~~-..........................r^^^^h.--.-~~~~~-.--~~~~--jj:.-~~~~-...-~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~-.--^h..-~~~~~~~~-..........................rhh^^^hh..-~~~~~~--.-~~~~-jj:--~~~~-....-~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~-.h^^h..--~~~~~~~--jjjjjjjj...................h^^^^h.-~~~~~~~-.-~~~~~-.--~~~~---...-~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~-h^^h....-~~~~~~~~-jjjjjjjj-jj................hh^^h.-~~~~~~~~--~~~~---j-~~~--.--.--~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~-^^h.....-~~~~~~~~------------.....jj..........hhhh.-~~~~~~~~~~~~~-j-jj-~--jjj---~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~-h^^jjjjj.-~~~~~~~~~~~~~~~~~~-jjjjjjjjjjj...........-~~~~~~~~~~~~~~-j--j--jjjj----~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~-h^^jjjjjjj-~~~~~~~~~~~~~~~~~~-jjjjjjjjjrj.........--~~~~~~~~~~~~~~~-jj---jjjj-j..-~~-----~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~-h^^jjjjjrrj--~~~~~~~~~~~~~~~~~-jjjjjjrrrj.........-~~~~~~~~~~~~~~~~~-jj-~-jjjj-j..-~-jjhh---~~~~~
+~~~~~~~~~~~~~~~~~~~~~~-^^jjrrrjjjj.--~~~~~~~~~~~~~~~~-jjrrrjjjjj........-~~~~~~~~~~~~~~~~~~--j-------j.--~~-j^^^^^--~~~~
+~~~~~~~~~~~~~~~~~~~~~~~-^^jjjjjjjj...-~~~~~~~~~~~~~~~~-..jjjjjj.........-~~~~~~~~~~~~~~~~~~~~--:::.-~---~~~~--jjjj^^-~~~
+~~~~~~~~~~~~~~~~~~~~~~~-^hjjjjjj.....-~~~~~~~~~~~~~~~~-................-~~~~~~~~~~~~~~~~~~~~~~-----~~~~~~~~~~----jjh-~~~
+~~~~~~~~~~~~~~~~~~~~~~~~-^^.jjjj.....-~~~~~~~~~~~~~~~~~-...............-~--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~----------~~~
+~~~~~~~~~~~~~~~~~~~~~~~-^^^h....::..-~~~~~~~~~~~~~~~~~-...............-~-.--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~--.......-~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~--^^h....::.-~~~~~~~~~~~~~~~~~-..............--~~-..-~~~~~~~~~~~~~~~~~~~~~~~~~~---.........-~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~-^^h...::..-~~~~~~~~~~~~~~~~~-.............-~~~-..-~~~~~~~~~~~~~~~~~~~~~~~~---...........h-~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~-^h...r::.-~~~~~~~~~~~~~~~~~~-d..dddd......-~~~-..-~~~~~~~~~~~~~~~~~~~~~---.............h^-~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~-^h..r...-~~~~~~~~~~~~~~~~~~~-dddddd..hhh.-~~~~-.-~~~~~~~~~~~~~~~~~~~~~-...dddddddddd...h^-~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~-^^..r..--~~~~~~~~~~~~~~~~~~~~-dddddd.h^^--~~~~~--~~~~~~~~~~~~~~~~~~~~~~-..ddddddddddd...hh-~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~-^h.r..-~~~~~~~~~~~~~~~~~~~~~-d.dddd.h^^h-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-..ddddddddddd...^-~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~-^^....-~~~~~~~~~~~~~~~~~~~~~~-..d...h^^--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-....dddddddd.....^-~~
+~~~~~~~~~~~~~~~~~~~~~~~~~-^^h.r..-~~~~~~~~~~~~~~~~~~~~~~-.....h^^-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-................h-~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~-^^::.--~~~~~~~~~~~~~~~~~~~~~~~-......--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-....------......^-~~
+~~~~~~~~~~~~~~~~~~~~~~~~~-^^h::-~~~~~~~~~~~~~~~~~~~~~~~~~-------~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-----~~~~~--...h^-~--
+~~~~~~~~~~~~~~~~~~~~~~~~~-^^h:.-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~------~-.
+~~~~~~~~~~~~~~~~~~~~~~~~~-^^h--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-.--^-
~~~~~~~~~~~~~~~~~~~~~~~~~-^^d-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~---^-
~~~~~~~~~~~~~~~~~~~~~~~~-^^d-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~--~
~~~~~~~~~~~~~~~~~~~~~~~~~-^^-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~-^-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[provinces]
-30:-1 10:197 80:-1
-31:-1 8:197 47:-1 12:56 22:-1
-24:-1 1:195 7:-1 7:197 42:-1 17:56 15:54 2:55 5:-1
-2:-1 6:188 1:196 12:-1 6:195 5:-1 6:197 19:-1 6:36 1:48 2:-1 1:48 10:-1 4:47 17:56 14:54 6:55 2:-1
-2:-1 6:188 12:196 9:195 3:-1 5:197 18:-1 1:31 4:36 2:30 2:-1 6:48 1:49 1:-1 5:49 6:47 14:56 2:53 14:54 7:55
-1:-1 7:188 11:196 4:-1 6:195 3:-1 3:197 3:-1 2:35 13:-1 3:31 1:36 3:30 4:-1 3:42 2:48 7:49 7:47 8:56 5:52 3:53 13:54 7:55 1:-1
-2:-1 7:188 10:196 5:-1 5:195 5:-1 1:197 16:-1 5:31 4:30 6:-1 3:42 6:49 2:43 6:47 2:50 5:56 6:52 3:53 14:54 6:55 1:-1
-1:-1 3:188 1:-1 3:188 10:196 6:-1 5:195 21:-1 6:31 3:30 3:-1 2:33 5:42 4:49 3:43 1:44 5:47 3:50 2:51 8:52 4:53 13:54 5:55 3:-1
-2:-1 2:188 2:-1 3:188 9:196 1:193 5:-1 6:195 15:-1 1:2 8:-1 2:31 2:30 5:-1 2:33 3:42 4:41 4:43 2:44 4:47 3:50 3:51 7:52 5:53 12:54 6:55 2:-1
-1:-1 2:188 3:-1 2:188 8:196 6:193 8:195 14:-1 2:2 8:-1 2:31 1:30 4:-1 2:34 1:33 3:42 4:41 4:43 2:44 4:47 3:50 3:51 7:52 6:53 11:54 4:55 1:-1 1:55 3:-1
-2:-1 1:188 4:-1 2:188 7:192 7:193 7:195 15:-1 2:2 9:-1 1:30 4:-1 3:34 3:40 5:41 3:43 3:44 4:47 3:50 3:51 6:52 7:53 11:54 2:55 6:-1
-1:-1 1:188 4:-1 2:188 7:192 8:193 7:195 15:-1 1:2 8:-1 1:32 5:-1 3:34 4:40 5:41 2:43 4:44 1:47 1:-1 1:47 3:50 4:51 4:52 9:53 10:54 2:55 3:-1 1:55 3:-1
-7:-1 2:191 6:192 9:193 7:195 11:-1 2:3 1:-1 2:1 7:-1 1:18 1:32 2:17 4:23 6:40 4:41 3:43 3:44 3:47 1:-1 3:50 3:51 4:52 10:53 9:54 1:58 1:55 7:-1
-7:-1 2:191 6:192 8:193 7:190 1:195 10:-1 3:3 2:1 5:-1 1:8 2:18 4:17 4:23 4:40 1:37 1:39 4:41 2:43 4:44 2:47 2:50 1:-1 1:50 4:51 3:52 10:53 2:136 3:54 6:58 4:-1 1:59 3:-1
-8:-1 2:191 5:192 8:193 8:190 11:-1 1:3 2:-1 2:1 3:-1 2:8 1:20 1:18 4:17 5:23 1:40 4:37 4:39 2:45 3:44 3:62 5:60 4:51 2:52 11:53 4:136 7:58 4:-1 1:59 2:-1
-7:-1 3:191 5:192 7:193 8:190 2:194 13:-1 3:0 1:-1 2:7 2:20 3:17 2:22 1:24 4:23 4:37 5:39 4:45 4:62 6:60 3:51 1:52 11:53 5:136 7:58 7:-1
-8:-1 3:191 4:192 8:193 7:190 2:194 17:-1 1:4 1:7 2:20 1:19 1:17 3:22 3:24 2:23 5:37 4:39 4:45 5:62 6:60 2:51 6:-1 1:53 5:67 6:136 6:58 7:-1
-8:-1 3:191 3:192 6:193 2:180 7:190 3:194 14:-1 5:4 2:16 2:19 1:22 2:21 3:24 1:23 5:37 4:39 5:45 4:62 7:60 1:139 2:-1 11:67 6:136 6:58 7:-1
-8:-1 4:185 3:192 4:193 4:180 6:190 3:194 13:-1 6:4 1:5 2:16 2:19 3:21 1:25 2:24 1:23 2:37 3:38 2:39 2:46 5:45 4:62 5:60 4:139 11:67 6:136 4:58 9:-1
-8:-1 5:185 1:192 2:193 6:180 6:190 2:194 16:-1 1:6 2:4 2:5 3:16 2:19 2:21 4:25 1:26 5:38 4:46 4:45 4:62 5:60 5:139 10:67 7:136 1:57 1:58 11:-1
-8:-1 6:185 9:180 5:190 2:194 17:-1 1:6 4:5 3:14 1:19 2:21 2:25 2:27 3:26 1:38 1:-1 2:38 4:46 2:45 1:-1 1:45 4:62 5:61 5:139 9:67 7:136 2:57 11:-1
-8:-1 4:185 1:181 6:180 3:-1 5:190 1:173 1:194 17:-1 2:6 3:5 4:14 1:-1 1:21 1:25 3:27 3:26 8:-1 1:46 1:66 1:45 2:-1 2:62 1:63 5:61 6:139 7:67 2:141 1:128 2:135 3:136 2:57 4:-1 1:152 7:-1
-8:-1 4:185 3:181 5:180 5:-1 1:190 2:173 1:-1 1:194 17:-1 2:6 3:5 2:-1 2:13 1:-1 1:25 3:27 1:28 2:26 7:-1 3:66 3:-1 1:62 3:63 5:61 6:139 4:67 4:141 2:128 4:135 1:136 1:-1 1:57 4:-1 2:152 5:-1
-8:-1 3:185 5:181 3:180 1:174 3:-1 1:189 1:-1 2:173 15:-1 3:9 3:6 1:10 1:5 4:-1 2:13 2:-1 2:27 2:28 2:26 7:-1 3:66 3:-1 4:63 3:61 1:-1 7:139 2:67 5:141 3:128 5:135 5:-1 2:152 6:-1
-8:-1 4:184 5:181 1:180 4:174 1:175 1:-1 1:189 2:171 15:-1 1:12 4:9 2:10 6:-1 2:13 2:-1 1:27 3:28 1:26 8:-1 3:66 2:-1 1:64 5:63 1:61 1:-1 6:139 3:138 5:141 3:128 6:135 4:-1 2:152 6:-1
-8:-1 3:184 7:181 4:174 1:175 3:171 16:-1 1:12 4:9 2:10 3:-1 1:14 2:-1 3:15 1:-1 4:28 1:-1 2:68 4:69 4:66 2:65 1:-1 1:64 4:63 2:-1 6:139 4:138 5:141 3:128 5:135 5:-1 1:151 7:-1
-9:-1 3:184 7:181 4:174 2:172 1:171 16:-1 1:12 5:9 8:-1 2:15 1:-1 4:29 2:-1 1:68 5:69 3:66 1:73 2:-1 3:64 1:63 4:-1 5:139 6:138 3:141 4:128 1:135 2:147 1:145 4:-1 3:151 6:-1
-8:-1 4:184 6:181 3:174 4:172 16:-1 2:12 1:11 3:9 9:-1 1:15 3:-1 2:29 1:-1 2:70 1:68 5:69 4:73 2:-1 3:64 4:-1 1:83 4:139 7:138 2:141 5:128 1:-1 1:147 2:145 3:-1 3:151 7:-1
-9:-1 4:184 6:181 2:174 4:172 17:-1 1:12 3:11 1:9 8:-1 2:15 3:-1 2:29 2:-1 2:70 5:69 4:73 1:-1 1:71 1:-1 2:64 1:-1 1:83 2:-1 3:83 1:139 8:138 2:134 4:128 3:-1 2:145 3:-1 2:148 2:151 6:-1
-9:-1 2:184 2:182 4:181 2:179 3:176 3:172 17:-1 1:11 5:-1 3:89 3:88 6:-1 1:29 3:-1 1:70 4:69 2:76 3:73 3:71 1:64 2:-1 7:83 8:138 3:134 3:128 4:-1 2:145 2:-1 1:149 3:148 7:-1
-10:-1 1:183 4:182 5:179 4:176 1:172 22:-1 5:89 2:88 14:-1 4:76 2:74 4:71 1:64 1:-1 3:83 1:-1 2:83 3:140 6:138 5:134 2:128 4:-1 1:146 2:-1 2:149 2:148 7:-1
-10:-1 1:183 4:182 4:179 5:176 19:-1 3:91 5:89 3:88 12:-1 5:76 4:74 3:71 1:64 4:83 1:-1 1:83 5:140 4:138 6:134 2:129 4:-1 1:146 1:-1 3:149 2:148 7:-1
-10:-1 1:183 4:182 5:179 4:176 19:-1 4:91 5:89 1:88 3:87 9:-1 2:85 5:76 3:74 5:72 3:83 2:-1 1:127 5:140 4:132 4:134 2:131 2:129 4:-1 1:150 1:-1 2:149 9:-1
-10:-1 1:183 3:182 6:179 3:176 19:-1 5:91 4:89 5:87 7:-1 3:85 2:77 3:76 4:74 4:72 3:83 3:-1 1:127 5:140 4:132 2:134 3:131 3:129 4:-1 1:150 12:-1
-11:-1 4:182 4:179 1:178 3:176 20:-1 4:91 4:89 7:87 4:-1 1:84 2:-1 1:85 1:84 3:77 2:76 2:74 2:75 4:72 2:83 1:-1 2:124 1:-1 1:127 4:140 5:132 1:133 4:131 3:129 4:-1 1:150 11:-1
-11:-1 3:182 1:200 5:178 3:176 19:-1 5:91 5:90 6:87 1:-1 8:84 1:-1 2:77 1:76 6:75 1:72 2:80 2:83 1:-1 2:116 1:-1 1:127 4:140 4:132 1:133 5:131 2:129 17:-1
-1:187 11:-1 2:182 2:200 3:178 4:-1 1:177 17:-1 6:91 6:90 7:87 8:84 1:-1 2:77 4:75 1:-1 1:75 3:80 3:-1 3:116 1:-1 1:127 3:140 4:132 2:133 4:131 2:129 17:-1
-12:-1 5:200 1:178 4:-1 2:177 16:-1 6:91 7:90 7:87 7:84 1:86 2:77 2:79 3:75 1:78 1:-1 2:80 2:-1 1:123 3:116 3:127 1:118 2:125 3:137 3:133 4:130 1:129 18:-1
-13:-1 5:200 5:-1 1:177 16:-1 3:92 3:94 9:90 5:87 5:84 4:86 4:79 3:78 3:80 2:-1 2:123 3:116 1:127 2:118 1:125 1:-1 4:137 2:133 4:130 2:-1 1:143 16:-1
-13:-1 2:199 2:200 5:-1 1:204 17:-1 3:92 3:94 10:90 3:87 1:99 9:86 3:79 4:78 2:80 1:82 2:-1 1:123 2:117 1:122 3:118 1:125 2:-1 4:137 1:157 4:130 2:-1 1:143 17:-1
-14:-1 2:199 2:198 2:-1 1:201 1:-1 3:204 15:-1 3:92 5:94 8:90 5:99 8:86 1:79 1:-1 2:79 4:78 1:80 4:-1 2:117 2:122 2:118 2:-1 1:154 1:-1 1:137 1:-1 3:157 1:130 1:-1 1:142 2:-1 1:144 17:-1
-2:-1 1:186 12:-1 1:199 2:198 2:-1 1:201 3:-1 1:204 14:-1 4:92 5:94 6:90 1:98 6:99 8:86 1:79 1:-1 2:79 4:78 5:-1 2:117 2:122 1:118 3:-1 1:154 1:-1 1:156 3:157 24:-1
-17:-1 2:198 1:202 1:201 5:-1 2:205 12:-1 3:92 1:93 5:94 4:90 2:98 7:99 8:100 2:-1 1:79 3:81 1:78 6:-1 1:117 2:121 5:-1 2:156 1:155 3:157 5:-1 1:168 17:-1
-17:-1 1:198 3:202 18:-1 3:92 2:93 5:94 1:90 5:98 6:99 9:100 2:-1 4:81 6:-1 1:117 2:121 5:-1 2:153 2:155 2:157 6:-1 2:168 16:-1
-20:-1 2:202 18:-1 2:92 3:93 5:94 5:98 7:99 8:100 1:101 2:-1 3:81 7:-1 2:119 1:120 5:-1 1:153 3:155 2:158 5:-1 3:168 15:-1
-21:-1 1:202 18:-1 1:92 4:93 4:94 6:98 7:99 7:100 3:101 11:-1 2:119 7:-1 1:155 1:159 2:158 6:-1 1:168 2:169 15:-1
-22:-1 1:203 3:-1 1:207 2:208 11:-1 1:92 5:93 2:94 2:96 1:97 4:98 8:99 6:100 7:101 8:-1 1:119 7:-1 1:155 2:159 1:158 6:-1 1:168 3:169 14:-1
-22:-1 2:203 1:-1 1:207 1:206 3:208 10:-1 4:93 2:95 3:96 2:97 4:98 7:99 5:100 8:101 1:102 16:-1 2:159 8:-1 3:169 15:-1
-25:-1 1:207 2:206 3:208 10:-1 2:93 4:95 2:96 4:97 2:98 8:99 2:100 2:104 7:101 2:102 9:-1 1:126 6:-1 1:160 10:-1 3:169 14:-1
-24:-1 5:206 2:208 1:228 10:-1 4:95 2:96 1:-1 1:97 1:-1 2:97 2:98 7:99 6:104 4:101 3:102 17:-1 1:160 6:-1 1:161 20:-1
-24:-1 6:206 1:208 2:228 20:-1 1:97 5:105 3:99 7:104 3:101 3:102 16:-1 1:165 2:160 4:-1 3:161 19:-1
-24:-1 1:209 3:206 3:227 1:228 21:-1 8:105 7:104 3:103 3:102 17:-1 1:160 1:-1 1:162 2:-1 5:161 19:-1
-24:-1 3:209 1:206 4:227 2:228 19:-1 8:105 8:104 3:103 2:102 18:-1 1:160 4:-1 4:166 1:161 3:167 15:-1
-23:-1 1:210 3:209 5:227 2:228 19:-1 8:105 1:106 6:104 4:103 20:-1 1:160 1:163 3:-1 4:166 1:-1 2:167 4:-1 3:170 9:-1
-23:-1 2:210 2:209 6:227 2:228 1:226 18:-1 8:105 2:106 4:104 3:103 1:108 21:-1 2:163 4:-1 1:166 2:-1 2:167 4:-1 7:170 5:-1
-23:-1 2:210 1:209 2:212 5:227 1:228 1:225 1:226 18:-1 1:107 6:105 4:106 2:104 2:103 2:108 23:-1 2:163 5:-1 1:167 7:-1 7:170 4:-1
-24:-1 2:211 3:212 4:227 1:224 2:225 2:226 17:-1 2:107 4:105 6:106 2:103 3:108 26:-1 2:164 11:-1 5:170 4:-1
-24:-1 1:211 4:212 2:227 3:224 2:225 19:-1 2:107 3:105 7:106 1:110 3:108 44:-1 1:170 4:-1
-24:-1 2:211 5:212 4:224 2:225 18:-1 3:107 2:105 7:106 2:110 2:108 36:-1 7:235 6:-1
-25:-1 2:212 3:213 5:224 1:225 18:-1 4:107 2:111 4:106 2:109 3:110 4:-1 2:115 32:-1 4:235 2:236 1:232 6:-1
-27:-1 4:213 5:224 19:-1 1:107 5:111 3:106 2:109 3:110 5:-1 2:115 29:-1 5:235 4:236 1:232 5:-1
-27:-1 3:213 1:221 3:224 1:222 20:-1 6:111 2:106 2:109 3:110 5:-1 2:115 27:-1 1:234 5:235 5:236 2:232 5:-1
-27:-1 1:215 2:213 3:221 2:222 1:223 20:-1 6:111 3:112 4:110 5:-1 2:115 24:-1 4:234 3:235 7:236 2:232 4:-1
-26:-1 3:215 3:221 2:222 1:223 21:-1 5:111 5:112 1:114 7:-1 1:115 23:-1 6:234 9:236 3:232 4:-1
-27:-1 2:215 4:221 1:222 23:-1 4:111 5:112 2:114 31:-1 6:234 8:236 4:232 3:-1
-27:-1 1:215 2:218 2:221 1:229 24:-1 4:111 5:112 33:-1 6:234 6:236 2:233 4:232 3:-1
-27:-1 1:214 2:218 1:217 2:229 25:-1 3:113 5:112 34:-1 6:234 4:236 4:233 2:230 1:232 3:-1
-26:-1 2:214 1:218 2:217 1:220 26:-1 3:113 3:112 35:-1 7:234 2:236 5:233 1:231 2:230 4:-1
-27:-1 2:214 2:217 1:220 26:-1 4:113 38:-1 3:234 7:-1 4:233 1:231 2:230 3:-1
-26:-1 3:214 2:217 80:-1 2:233 2:231 1:230 4:-1
-26:-1 2:219 1:214 1:217 89:-1 1:238
-26:-1 3:219 86:-1 1:237 2:-1 1:239 1:-1
-26:-1 3:219 89:-1 1:239 1:-1
-25:-1 3:216 92:-1
-26:-1 2:216 92:-1
-26:-1 1:216 93:-1
+31:-1 8:204 50:-1 9:61 22:-1
+23:-1 2:202 6:-1 7:204 23:-1 1:33 17:-1 19:61 15:59 2:60 5:-1
+2:-1 6:195 1:203 13:-1 6:202 4:-1 6:204 19:-1 2:41 4:33 2:38 2:-1 1:53 10:-1 2:54 19:61 14:59 5:60 2:-1
+1:-1 7:195 11:203 9:202 4:-1 5:204 18:-1 3:41 4:33 3:38 5:53 3:-1 6:54 1:52 18:61 14:59 7:60 1:-1
+2:-1 6:195 11:203 10:202 4:-1 4:204 2:-1 1:40 15:-1 2:32 1:41 3:33 1:-1 4:38 4:53 9:54 3:52 16:61 15:59 7:60
+1:-1 7:195 11:203 2:202 2:-1 6:202 4:-1 3:204 3:-1 1:40 14:-1 5:32 1:33 2:-1 4:38 3:53 9:54 5:52 14:61 15:59 7:60 1:-1
+2:-1 6:195 12:203 4:-1 5:202 3:-1 4:204 3:-1 1:40 13:-1 2:34 4:32 2:-1 5:38 3:47 8:54 7:52 9:61 4:57 1:58 15:59 7:60
+1:-1 7:195 11:203 5:-1 5:202 4:-1 2:204 16:-1 4:34 3:32 2:-1 4:37 5:47 7:54 8:52 7:61 5:57 2:58 14:59 7:60 1:-1
+2:-1 7:195 10:203 5:-1 5:202 5:-1 1:204 16:-1 5:34 2:32 3:-1 4:37 5:47 5:54 2:48 7:52 3:55 9:57 3:58 13:59 7:60 1:-1
+1:-1 7:195 10:203 6:-1 5:202 21:-1 5:34 1:31 3:30 3:-1 1:37 2:-1 4:47 3:46 4:48 1:49 6:52 3:55 1:56 8:57 4:58 12:59 7:60 2:-1
+2:-1 2:195 2:-1 3:195 10:203 5:-1 6:202 21:-1 3:34 2:31 3:30 6:-1 3:47 4:46 4:48 2:49 5:52 3:55 2:56 7:57 5:58 11:59 7:60 2:-1
+1:-1 2:195 3:-1 2:195 9:203 1:200 5:-1 6:202 15:-1 2:2 8:-1 2:31 2:30 3:-1 3:39 3:47 5:46 3:48 2:49 5:52 3:55 3:56 6:57 6:58 11:59 4:60 1:-1 1:60 3:-1
+2:-1 2:195 3:-1 2:195 8:199 6:200 7:202 15:-1 2:2 8:-1 2:31 1:30 3:-1 5:39 1:47 5:46 3:48 3:49 4:52 3:55 3:56 6:57 7:58 10:59 4:60 5:-1
+1:-1 2:195 3:-1 2:195 8:199 7:200 7:202 14:-1 2:2 6:-1 2:36 1:35 5:-1 4:39 2:45 6:46 3:48 3:49 1:52 1:-1 1:52 4:55 3:56 5:57 8:58 10:59 2:60 3:-1 1:60 3:-1
+7:-1 2:198 7:199 8:200 7:202 12:-1 1:3 1:-1 2:1 6:-1 1:18 5:-1 3:23 1:39 4:45 5:46 3:48 3:49 1:52 2:-1 4:55 4:56 4:57 9:58 5:59 5:63 1:60 7:-1
+7:-1 2:198 6:199 8:200 8:197 10:-1 3:3 1:-1 1:1 7:-1 1:18 4:17 4:23 4:45 1:42 5:46 3:48 3:49 1:52 1:67 5:55 3:56 4:57 9:58 4:142 7:63 4:-1 1:64 3:-1
+8:-1 2:198 6:199 7:200 8:197 11:-1 2:3 1:-1 2:1 3:-1 3:8 1:18 4:17 5:23 2:45 3:42 3:44 1:46 4:48 1:49 3:67 2:65 1:55 1:-1 1:55 4:56 3:57 10:58 4:142 7:63 4:-1 1:64 2:-1
+7:-1 3:198 5:199 7:200 8:197 11:-1 1:3 3:-1 3:0 1:-1 2:7 1:20 1:18 3:17 2:22 1:24 3:23 1:45 4:42 5:44 4:50 4:67 4:65 1:55 4:56 2:57 10:58 5:142 7:63 7:-1
+8:-1 3:198 4:199 8:200 7:197 1:-1 1:201 18:-1 1:7 2:20 1:19 1:17 3:22 3:24 2:23 5:42 4:44 4:50 4:67 6:65 4:56 3:-1 3:58 5:72 6:142 6:63 7:-1
+7:-1 4:198 3:199 8:200 7:197 1:-1 2:201 15:-1 3:4 1:7 1:20 1:16 2:19 1:22 2:21 3:24 1:23 5:42 4:44 1:51 4:50 4:67 6:65 2:56 2:-1 3:58 8:72 6:142 6:63 7:-1
+8:-1 4:192 3:199 5:200 3:187 6:197 1:201 1:-1 1:201 13:-1 7:4 2:16 2:19 3:21 1:25 2:24 1:23 4:42 3:44 2:51 5:50 3:67 6:65 2:145 1:-1 1:145 11:72 6:142 5:63 8:-1
+8:-1 5:192 1:199 3:200 5:187 6:197 2:201 15:-1 2:6 3:4 1:5 3:16 2:19 2:21 4:25 1:26 4:43 2:44 3:51 5:50 3:67 5:65 5:145 10:72 7:142 2:63 11:-1
+8:-1 6:192 9:187 5:197 2:201 17:-1 1:6 1:4 3:5 3:14 1:19 2:21 2:25 2:27 2:26 2:43 1:-1 1:43 1:44 4:51 2:50 1:-1 2:50 2:67 2:65 4:66 5:145 9:72 8:142 1:63 11:-1
+8:-1 4:192 1:188 6:187 2:-1 1:187 5:197 1:180 1:201 17:-1 2:6 3:5 4:14 1:13 1:21 1:25 3:27 3:26 8:-1 3:50 1:-1 2:50 1:67 1:68 5:66 6:145 7:72 2:147 1:134 2:141 5:142 4:-1 1:159 7:-1
+8:-1 4:192 3:188 5:187 5:-1 1:197 2:180 1:-1 1:201 17:-1 2:6 3:5 1:14 1:-1 2:13 1:-1 1:25 3:27 1:28 2:26 7:-1 2:71 4:-1 1:50 3:68 5:66 6:145 4:72 4:147 2:134 4:141 2:142 5:-1 2:159 5:-1
+8:-1 3:191 5:188 3:187 1:181 3:-1 1:196 1:-1 2:180 15:-1 4:9 2:6 2:10 4:-1 2:13 2:-1 2:27 2:28 2:26 7:-1 3:71 3:-1 4:68 3:66 1:-1 7:145 2:72 5:147 3:134 5:141 1:-1 1:62 3:-1 2:159 6:-1
+8:-1 4:191 5:188 1:187 4:181 1:182 1:-1 1:196 2:178 15:-1 1:12 5:9 2:10 5:-1 2:13 2:-1 1:27 3:28 1:26 8:-1 3:71 2:-1 1:69 5:68 1:66 1:-1 6:145 3:144 5:147 3:134 5:141 1:154 4:-1 2:159 6:-1
+8:-1 3:191 7:188 4:181 1:182 3:178 16:-1 1:12 4:9 2:10 3:-1 1:14 2:-1 3:15 1:-1 4:28 1:-1 2:73 4:74 4:71 2:70 1:-1 1:69 4:68 2:-1 6:145 4:144 5:147 3:134 3:141 2:154 5:-1 1:158 7:-1
+9:-1 3:191 7:188 4:181 2:179 1:178 16:-1 1:12 1:11 4:9 9:-1 1:15 1:-1 4:29 2:-1 1:73 5:74 3:71 1:78 2:-1 3:69 1:68 4:-1 5:145 6:144 3:147 4:134 2:141 1:153 1:154 4:-1 3:158 6:-1
+8:-1 4:191 6:188 3:181 4:179 16:-1 2:12 2:11 2:9 9:-1 1:15 3:-1 2:29 1:-1 2:75 1:73 5:74 4:78 2:-1 3:69 4:-1 1:88 4:145 7:144 2:147 5:134 2:-1 1:153 1:151 3:-1 3:158 7:-1
+9:-1 3:191 7:188 2:181 4:179 17:-1 1:12 4:11 8:-1 2:15 3:-1 2:29 2:-1 2:75 5:74 4:78 1:-1 4:69 1:-1 2:88 1:-1 3:88 1:145 8:144 2:140 4:134 3:-1 2:151 3:-1 2:155 2:158 6:-1
+9:-1 1:191 3:189 4:188 2:186 3:183 3:179 23:-1 3:94 3:93 10:-1 1:75 4:74 2:81 3:78 3:76 1:69 2:-1 7:88 8:144 3:140 4:134 3:-1 2:151 2:-1 1:156 3:155 7:-1
+10:-1 1:190 4:189 5:186 4:183 1:179 22:-1 5:94 2:93 15:-1 3:81 2:79 4:76 1:69 1:-1 7:88 2:146 6:144 5:140 2:134 4:-1 2:152 1:-1 2:156 2:155 7:-1
+10:-1 1:190 4:189 4:186 5:183 19:-1 3:96 5:94 2:93 1:92 14:-1 3:81 4:79 3:76 1:69 7:88 4:146 4:144 5:140 2:137 1:135 6:-1 3:156 2:155 7:-1
+10:-1 1:190 4:189 5:186 4:183 19:-1 4:96 5:94 4:92 13:-1 3:81 3:79 5:77 4:88 2:130 1:121 4:146 5:138 2:140 3:137 2:135 4:-1 1:157 1:-1 2:156 9:-1
+10:-1 1:190 3:189 6:186 3:183 19:-1 5:96 4:94 5:92 12:-1 1:82 2:81 4:79 4:77 3:88 3:130 1:121 1:133 4:146 5:138 1:140 4:137 2:135 4:-1 1:157 12:-1
+11:-1 4:189 5:185 4:183 18:-1 5:96 4:94 7:92 3:-1 5:90 1:-1 3:82 2:81 2:79 3:80 3:77 1:88 4:130 1:121 2:133 3:146 6:138 4:137 3:135 16:-1
+11:-1 3:189 6:185 2:183 1:184 18:-1 6:96 5:95 7:92 8:89 3:82 1:81 2:79 4:80 2:77 2:129 2:130 3:121 2:133 3:146 3:138 3:139 4:137 2:135 17:-1
+1:194 11:-1 2:189 3:207 2:185 4:-1 1:184 17:-1 6:96 6:95 7:92 8:89 1:-1 2:82 1:81 2:83 1:80 1:-1 2:80 1:77 3:129 4:121 2:133 4:128 1:143 1:138 3:139 1:136 3:137 2:135 17:-1
+12:-1 2:206 3:207 6:-1 1:184 16:-1 6:96 8:95 5:92 7:89 2:91 1:-1 2:84 4:83 4:-1 3:129 4:121 1:133 4:128 3:143 2:139 2:136 3:148 19:-1
+13:-1 3:206 2:207 22:-1 3:97 4:99 9:95 4:92 5:89 4:91 1:-1 2:84 4:83 2:85 1:87 2:-1 2:129 3:121 2:123 1:131 1:128 1:-1 1:161 4:143 1:164 2:136 2:148 2:-1 1:149 16:-1
+2:-1 1:193 10:-1 3:206 1:205 5:-1 1:211 17:-1 2:97 5:99 10:95 3:104 4:89 5:91 1:-1 2:84 4:83 2:85 4:-1 2:122 2:127 3:123 1:-1 2:161 2:143 2:164 3:136 3:-1 1:150 17:-1
+15:-1 1:206 2:205 2:-1 1:208 2:-1 2:211 15:-1 3:97 5:99 8:95 5:104 3:89 6:91 1:-1 2:84 3:83 3:85 4:-1 1:122 3:127 3:-1 2:161 1:-1 1:143 3:164 23:-1
+16:-1 2:205 1:-1 2:208 4:-1 2:212 12:-1 3:97 1:98 5:99 6:95 1:103 6:104 7:105 2:91 1:-1 2:84 2:86 1:83 2:85 4:-1 2:122 1:126 1:127 4:-1 1:160 3:163 2:164 24:-1
+18:-1 1:205 2:209 19:-1 2:97 2:98 5:99 4:95 2:103 7:104 9:105 2:-1 4:86 6:-1 1:122 2:126 4:-1 2:160 1:163 1:162 3:164 5:-1 3:175 15:-1
+19:-1 2:209 18:-1 3:97 2:98 4:99 2:95 5:103 6:104 9:105 2:-1 4:86 7:-1 1:125 1:124 6:-1 3:162 2:165 6:-1 3:175 15:-1
+40:-1 2:97 4:98 3:99 1:101 5:103 7:104 7:105 3:106 2:-1 1:86 8:-1 2:125 1:124 5:-1 3:162 1:166 1:165 6:-1 3:175 1:176 14:-1
+22:-1 1:210 3:-1 1:215 13:-1 1:97 5:98 1:99 2:101 1:102 5:103 7:104 6:105 5:106 2:-1 1:107 7:-1 1:125 8:-1 1:162 2:166 1:165 6:-1 1:175 2:176 15:-1
+23:-1 1:210 2:-1 1:214 3:215 10:-1 2:97 3:98 2:100 2:101 2:102 4:103 8:104 5:105 7:106 1:107 9:-1 1:132 6:-1 2:162 1:166 7:-1 4:176 14:-1
+23:-1 1:210 2:214 1:213 3:215 11:-1 2:98 3:100 2:101 3:102 4:103 7:104 5:105 6:106 2:107 9:-1 1:132 7:-1 1:167 9:-1 3:176 15:-1
+24:-1 2:214 2:213 4:215 10:-1 5:100 2:101 1:102 1:-1 1:102 3:103 7:104 6:109 5:106 2:107 18:-1 1:167 6:-1 1:168 2:-1 1:176 16:-1
+24:-1 5:213 1:215 2:234 21:-1 2:103 6:104 7:109 4:106 3:107 15:-1 1:172 1:-1 2:167 4:-1 3:168 19:-1
+24:-1 1:216 4:213 3:234 1:235 20:-1 1:103 7:110 7:109 3:108 4:107 16:-1 1:172 2:-1 1:169 2:-1 2:173 2:168 19:-1
+23:-1 2:216 3:213 4:234 1:235 20:-1 8:110 7:109 3:108 2:107 18:-1 2:172 3:-1 4:173 1:-1 3:174 16:-1
+23:-1 1:217 2:216 2:213 4:234 2:235 20:-1 8:110 1:111 5:109 4:108 1:113 19:-1 2:172 3:-1 4:173 1:-1 3:174 3:-1 4:177 8:-1
+23:-1 1:217 2:216 1:213 5:234 3:235 19:-1 7:110 3:111 3:109 3:108 2:113 21:-1 1:172 7:-1 2:174 5:-1 6:177 6:-1
+24:-1 1:217 1:216 1:218 2:219 3:234 3:235 2:233 18:-1 1:112 5:110 5:111 1:109 3:108 2:113 23:-1 2:170 2:171 11:-1 6:177 4:-1
+24:-1 2:218 3:219 2:234 3:231 1:232 2:233 18:-1 2:112 3:110 7:111 2:108 2:113 42:-1 3:177 4:-1
+25:-1 1:218 5:219 4:231 2:232 19:-1 2:112 2:110 8:111 1:108 2:113 49:-1
+24:-1 2:218 4:219 4:231 2:232 19:-1 3:112 1:110 1:116 6:111 2:115 2:113 3:-1 1:120 33:-1 7:242 6:-1
+26:-1 2:219 3:220 4:231 1:232 19:-1 3:112 2:116 6:114 3:115 5:-1 2:120 30:-1 7:242 2:239 5:-1
+26:-1 5:220 3:231 1:229 1:230 19:-1 5:116 5:114 3:115 5:-1 2:120 28:-1 7:242 3:243 2:239 5:-1
+27:-1 4:220 1:228 3:229 1:230 20:-1 5:116 4:114 4:115 5:-1 2:120 25:-1 3:241 4:242 5:243 3:239 4:-1
+27:-1 1:222 1:220 3:228 2:229 1:230 21:-1 5:116 3:117 4:115 6:-1 1:120 23:-1 6:241 2:242 7:243 3:239 4:-1
+27:-1 3:222 3:228 1:229 23:-1 4:116 5:117 1:119 32:-1 5:241 9:243 4:239 3:-1
+27:-1 2:222 4:228 23:-1 4:116 5:117 2:119 32:-1 5:241 8:243 1:238 3:239 4:-1
+27:-1 1:221 2:225 2:228 1:236 24:-1 4:118 5:117 33:-1 6:241 6:243 2:240 1:238 3:239 3:-1
+26:-1 2:221 2:225 2:227 1:236 24:-1 4:118 4:117 34:-1 6:241 4:243 4:240 1:238 2:237 4:-1
+27:-1 2:221 1:225 1:224 1:227 26:-1 4:118 2:117 36:-1 4:241 6:-1 3:240 2:238 2:237 3:-1
+26:-1 3:221 2:224 80:-1 2:240 2:238 1:237 4:-1
+26:-1 2:226 1:221 2:224 88:-1 1:245
+26:-1 3:226 86:-1 1:244 2:-1 1:246 1:-1
+26:-1 3:226 89:-1 1:246 1:-1
+25:-1 3:223 92:-1
+26:-1 2:223 92:-1
+26:-1 1:223 93:-1
[meta]
-0|prov_london|4|47,15
-1|prov_manchester|2|45,13
-2|prov_edinburgh|2|45,10
-3|prov_dublin|2|43,13
-4|prov_paris|4|48,17
-5|prov_lyon|2|50,20
-6|prov_bordeaux|2|46,21
-7|prov_brussels|2|49,15
-8|prov_amsterdam|2|50,14
-9|prov_madrid|3|45,26
-10|prov_barcelona|2|48,25
-11|prov_seville|2|44,28
-12|prov_lisbon|2|41,27
-13|prov_rome|3|55,24
-14|prov_milan|3|52,21
-15|prov_naples|2|55,25
-16|prov_zurich|2|52,19
-17|prov_berlin|4|55,14
-18|prov_hamburg|2|53,13
-19|prov_munich|3|54,18
-20|prov_cologne|2|51,15
-21|prov_vienna|3|57,18
-22|prov_prague|2|56,16
-23|prov_warsaw|3|60,14
-24|prov_krakow|2|59,16
-25|prov_budapest|2|58,19
-26|prov_bucharest|2|63,22
-27|prov_belgrade|2|59,21
-28|prov_sofia|1|61,23
-29|prov_athens|2|61,28
-30|prov_stockholm|2|58,7
-31|prov_oslo|2|53,7
-32|prov_copenhagen|2|54,11
-33|prov_helsinki|2|62,7
-34|prov_riga|1|61,9
-35|prov_reykjavik|1|38,5
-36|prov_narvik|1|57,3
-37|prov_kyiv|3|65,16
-38|prov_odesa|2|65,19
-39|prov_kharkiv|2|69,16
-40|prov_minsk|2|64,12
-41|prov_moscow|4|69,11
-42|prov_petersburg|3|65,7
-43|prov_nizhny|2|73,10
-44|prov_kazan|2|75,11
-45|prov_volgograd|2|73,17
-46|prov_rostov|2|70,19
-47|prov_yekaterinburg|2|79,10
-48|prov_murmansk|1|66,3
-49|prov_arkhangelsk|1|71,5
-50|prov_omsk|2|82,11
-51|prov_novosibirsk|2|85,11
-52|prov_krasnoyarsk|2|89,10
-53|prov_irkutsk|1|94,14
-54|prov_yakutsk|1|107,6
-55|prov_magadan|1|116,8
-56|prov_norilsk|1|87,3
-57|prov_vladivostok|2|108,22
-58|prov_khabarovsk|1|110,18
-59|prov_petropavlovsk|1|117,14
-60|prov_astana|2|82,15
-61|prov_almaty|2|83,23
-62|prov_aktobe|1|78,16
-63|prov_tashkent|2|81,25
-64|prov_ashgabat|1|78,28
-65|prov_baku|2|75,25
-66|prov_tbilisi|1|74,24
-67|prov_ulaanbaatar|1|95,18
-68|prov_istanbul|3|64,25
-69|prov_ankara|2|67,26
-70|prov_izmir|2|63,27
-71|prov_tehran|3|76,30
-72|prov_isfahan|2|76,32
-73|prov_tabriz|1|74,27
-74|prov_baghdad|3|74,32
-75|prov_basra|2|74,35
-76|prov_damascus|2|69,32
-77|prov_jerusalem|2|68,34
-78|prov_riyadh|3|74,39
-79|prov_jeddah|2|71,40
-80|prov_dubai|2|77,38
-81|prov_sanaa|1|73,43
-82|prov_muscat|1|78,39
-83|prov_kabul|2|81,31
-84|prov_cairo|4|65,35
-85|prov_alexandria|2|65,34
-86|prov_aswan|1|66,39
-87|prov_tripoli|2|55,33
-88|prov_tunis|2|53,29
-89|prov_algiers|2|49,29
-90|prov_tamanrasset|1|50,39
-91|prov_casablanca|2|43,32
-92|prov_dakar|2|39,43
-93|prov_bamako|1|42,45
-94|prov_timbuktu|1|45,43
-95|prov_abidjan|2|44,49
-96|prov_accra|2|47,49
-97|prov_lagos|3|49,49
-98|prov_kano|2|52,45
-99|prov_ndjamena|1|56,45
-100|prov_khartoum|2|66,43
-101|prov_addis|2|70,47
-102|prov_mogadishu|1|73,51
-103|prov_nairobi|2|69,53
-104|prov_kampala|1|67,52
-105|prov_kinshasa|3|56,54
-106|prov_lubumbashi|1|64,58
-107|prov_luanda|2|55,56
-108|prov_dar_es_salaam|2|70,55
-109|prov_lusaka|1|64,59
-110|prov_harare|1|66,60
-111|prov_windhoek|1|57,63
-112|prov_johannesburg|3|64,64
-113|prov_cape_town|2|58,68
-114|prov_maputo|1|67,64
-115|prov_antananarivo|1|74,61
-116|prov_delhi|4|84,36
-117|prov_mumbai|3|82,41
-118|prov_kolkata|3|87,39
-119|prov_chennai|2|84,45
-120|prov_bangalore|2|85,44
-121|prov_hyderabad|2|84,43
-122|prov_nagpur|1|84,41
-123|prov_karachi|3|81,38
-124|prov_lahore|2|83,34
-125|prov_dhaka|2|88,39
-126|prov_colombo|1|85,48
-127|prov_kathmandu|1|86,37
-128|prov_beijing|4|100,26
-129|prov_shanghai|4|103,34
-130|prov_guangzhou|3|98,39
-131|prov_wuhan|3|98,35
-132|prov_chengdu|3|93,35
-133|prov_chongqing|2|95,36
-134|prov_xian|2|96,31
-135|prov_shenyang|2|104,24
-136|prov_harbin|2|105,20
-137|prov_kunming|2|93,38
-138|prov_lanzhou|1|93,29
-139|prov_urumqi|1|87,22
-140|prov_lhasa|1|88,35
-141|prov_hohhot|1|97,25
-142|prov_hong_kong|3|99,40
-143|prov_taipei|3|103,38
-144|prov_kaohsiung|2|102,40
-145|prov_seoul|3|106,28
-146|prov_busan|2|106,31
-147|prov_pyongyang|2|104,27
-148|prov_tokyo|4|112,30
-149|prov_osaka|3|109,31
-150|prov_fukuoka|2|107,32
-151|prov_sendai|2|112,27
-152|prov_sapporo|2|112,23
-153|prov_yangon|2|90,43
-154|prov_mandalay|1|90,40
-155|prov_bangkok|3|92,44
-156|prov_chiang_mai|1|91,42
-157|prov_hanoi|2|94,41
-158|prov_ho_chi_minh|3|95,46
-159|prov_phnom_penh|1|94,46
-160|prov_kuala_lumpur|2|92,50
-161|prov_kota_kinabalu|1|99,49
-162|prov_singapore|3|93,51
-163|prov_jakarta|3|95,55
-164|prov_surabaya|2|98,56
-165|prov_medan|2|91,50
-166|prov_banjarmasin|1|99,54
-167|prov_makassar|1|101,55
-168|prov_manila|3|102,44
-169|prov_cebu|1|104,46
-170|prov_port_moresby|1|115,57
-171|prov_new_york|4|25,25
-172|prov_washington|3|24,27
-173|prov_boston|2|26,23
-174|prov_chicago|3|21,24
-175|prov_detroit|2|22,24
-176|prov_atlanta|2|22,32
-177|prov_miami|2|23,38
-178|prov_houston|3|18,36
-179|prov_dallas|2|17,33
-180|prov_minneapolis|2|18,21
-181|prov_denver|2|15,26
-182|prov_phoenix|2|12,32
-183|prov_los_angeles|4|10,32
-184|prov_san_francisco|3|9,28
-185|prov_seattle|2|8,19
-186|prov_honolulu|2|2,41
-187|prov_midway|1|0,36
-188|prov_anchorage|1|4,6
-189|prov_toronto|3|23,23
-190|prov_montreal|2|25,21
-191|prov_vancouver|2|8,17
-192|prov_calgary|2|11,15
-193|prov_winnipeg|1|17,16
-194|prov_halifax|1|29,22
-195|prov_iqaluit|1|27,5
-196|prov_yellowknife|1|11,5
-197|prov_nuuk|1|32,5
-198|prov_mexico_city|4|16,41
-199|prov_guadalajara|2|15,41
-200|prov_monterrey|2|16,38
-201|prov_merida|1|20,40
-202|prov_guatemala|1|20,44
-203|prov_panama|2|23,47
-204|prov_havana|2|22,39
-205|prov_santo_domingo|1|27,42
-206|prov_bogota|3|25,49
-207|prov_medellin|2|25,48
-208|prov_caracas|2|28,46
-209|prov_quito|1|24,52
-210|prov_guayaquil|1|23,53
-211|prov_lima|3|24,58
-212|prov_cusco|1|26,58
-213|prov_la_paz|1|27,60
-214|prov_santiago|3|27,68
-215|prov_antofagasta|1|26,63
-216|prov_punta_arenas|1|26,75
-217|prov_buenos_aires|4|30,68
-218|prov_cordoba_ar|2|28,67
-219|prov_bariloche|1|26,71
-220|prov_montevideo|1|31,68
-221|prov_asuncion|1|31,64
-222|prov_sao_paulo|4|33,63
-223|prov_rio|3|34,63
-224|prov_brasilia|2|33,60
-225|prov_salvador|2|36,58
-226|prov_recife|2|37,56
-227|prov_manaus|2|30,54
-228|prov_belem|1|33,52
-229|prov_porto_alegre|2|32,66
-230|prov_sydney|3|116,68
-231|prov_melbourne|3|114,69
-232|prov_brisbane|2|116,65
-233|prov_adelaide|2|112,68
-234|prov_perth|2|99,67
-235|prov_darwin|1|107,58
-236|prov_alice_springs|1|109,63
-237|prov_hobart|1|115,71
-238|prov_auckland|2|119,70
-239|prov_christchurch|1|118,71
+0|prov_london|4|47,17
+1|prov_manchester|2|45,15
+2|prov_edinburgh|2|45,13
+3|prov_dublin|2|43,15
+4|prov_paris|4|49,20
+5|prov_lyon|2|50,22
+6|prov_bordeaux|2|46,23
+7|prov_brussels|2|50,18
+8|prov_amsterdam|2|50,16
+9|prov_madrid|3|45,27
+10|prov_barcelona|2|48,27
+11|prov_seville|2|44,30
+12|prov_lisbon|2|41,29
+13|prov_rome|3|55,26
+14|prov_milan|3|52,23
+15|prov_naples|2|55,27
+16|prov_zurich|2|52,21
+17|prov_berlin|4|55,16
+18|prov_hamburg|2|53,15
+19|prov_munich|3|54,20
+20|prov_cologne|2|51,18
+21|prov_vienna|3|57,20
+22|prov_prague|2|56,18
+23|prov_warsaw|3|60,16
+24|prov_krakow|2|59,18
+25|prov_budapest|2|58,21
+26|prov_bucharest|2|63,24
+27|prov_belgrade|2|59,23
+28|prov_sofia|1|61,25
+29|prov_athens|2|61,30
+30|prov_stockholm|2|58,10
+31|prov_gothenburg|1|54,11
+32|prov_sundsvall|1|57,7
+33|prov_kiruna|1|59,3
+34|prov_oslo|2|53,9
+35|prov_copenhagen|2|54,13
+36|prov_aarhus|1|53,13
+37|prov_helsinki|2|62,9
+38|prov_oulu|1|62,5
+39|prov_riga|1|62,12
+40|prov_reykjavik|1|39,6
+41|prov_narvik|1|58,2
+42|prov_kyiv|3|65,18
+43|prov_odesa|2|65,22
+44|prov_kharkiv|2|68,19
+45|prov_minsk|2|63,15
+46|prov_moscow|4|69,13
+47|prov_petersburg|3|65,9
+48|prov_nizhny|2|73,13
+49|prov_kazan|2|75,13
+50|prov_volgograd|2|74,20
+51|prov_rostov|2|70,21
+52|prov_yekaterinburg|2|79,12
+53|prov_murmansk|1|67,2
+54|prov_arkhangelsk|1|71,5
+55|prov_omsk|2|83,14
+56|prov_novosibirsk|2|86,14
+57|prov_krasnoyarsk|2|89,13
+58|prov_irkutsk|1|94,16
+59|prov_yakutsk|1|106,7
+60|prov_magadan|1|116,10
+61|prov_norilsk|1|88,2
+62|prov_vladivostok|2|108,25
+63|prov_khabarovsk|1|110,20
+64|prov_petropavlovsk|1|117,16
+65|prov_astana|2|82,18
+66|prov_almaty|2|83,25
+67|prov_aktobe|1|78,18
+68|prov_tashkent|2|81,27
+69|prov_ashgabat|1|78,30
+70|prov_baku|2|75,27
+71|prov_tbilisi|1|74,26
+72|prov_ulaanbaatar|1|95,20
+73|prov_istanbul|3|64,27
+74|prov_ankara|2|67,28
+75|prov_izmir|2|63,29
+76|prov_tehran|3|76,32
+77|prov_isfahan|2|76,34
+78|prov_tabriz|1|74,29
+79|prov_baghdad|3|74,34
+80|prov_basra|2|75,36
+81|prov_damascus|2|69,34
+82|prov_jerusalem|2|68,35
+83|prov_riyadh|3|74,40
+84|prov_jeddah|2|71,42
+85|prov_dubai|2|77,40
+86|prov_sanaa|1|73,45
+87|prov_muscat|1|78,40
+88|prov_kabul|2|81,33
+89|prov_cairo|4|65,37
+90|prov_alexandria|2|65,36
+91|prov_aswan|1|67,40
+92|prov_tripoli|2|55,34
+93|prov_tunis|2|53,31
+94|prov_algiers|2|49,31
+95|prov_tamanrasset|1|50,41
+96|prov_casablanca|2|43,34
+97|prov_dakar|2|39,45
+98|prov_bamako|1|43,46
+99|prov_timbuktu|1|45,44
+100|prov_abidjan|2|45,50
+101|prov_accra|2|47,50
+102|prov_lagos|3|49,50
+103|prov_kano|2|52,47
+104|prov_ndjamena|1|56,47
+105|prov_khartoum|2|66,45
+106|prov_addis|2|70,48
+107|prov_mogadishu|1|74,52
+108|prov_nairobi|2|69,54
+109|prov_kampala|1|66,53
+110|prov_kinshasa|3|56,55
+111|prov_lubumbashi|1|64,58
+112|prov_luanda|2|55,57
+113|prov_dar_es_salaam|2|71,56
+114|prov_lusaka|1|64,60
+115|prov_harare|1|65,61
+116|prov_windhoek|1|57,63
+117|prov_johannesburg|3|63,65
+118|prov_cape_town|2|58,68
+119|prov_maputo|1|66,65
+120|prov_antananarivo|1|75,62
+121|prov_delhi|4|84,38
+122|prov_mumbai|3|82,43
+123|prov_kolkata|3|87,41
+124|prov_chennai|2|85,46
+125|prov_bangalore|2|84,46
+126|prov_hyderabad|2|84,44
+127|prov_nagpur|1|85,42
+128|prov_guwahati|1|88,39
+129|prov_karachi|3|81,40
+130|prov_lahore|2|83,36
+131|prov_dhaka|2|88,40
+132|prov_colombo|1|84,49
+133|prov_kathmandu|1|87,38
+134|prov_beijing|4|100,28
+135|prov_shanghai|4|103,36
+136|prov_guangzhou|3|98,41
+137|prov_wuhan|3|99,36
+138|prov_chengdu|3|94,36
+139|prov_chongqing|2|94,37
+140|prov_xian|2|96,33
+141|prov_shenyang|2|104,26
+142|prov_harbin|2|105,22
+143|prov_kunming|2|93,40
+144|prov_lanzhou|1|93,31
+145|prov_urumqi|1|87,24
+146|prov_lhasa|1|88,37
+147|prov_hohhot|1|97,27
+148|prov_hong_kong|3|99,40
+149|prov_taipei|3|103,40
+150|prov_kaohsiung|2|102,41
+151|prov_seoul|3|106,30
+152|prov_busan|2|107,32
+153|prov_pyongyang|2|105,29
+154|prov_hamhung|1|106,28
+155|prov_tokyo|4|112,32
+156|prov_osaka|3|109,33
+157|prov_fukuoka|2|107,34
+158|prov_sendai|2|112,29
+159|prov_sapporo|2|112,25
+160|prov_yangon|2|90,44
+161|prov_mandalay|1|90,41
+162|prov_bangkok|3|92,46
+163|prov_chiang_mai|1|91,43
+164|prov_hanoi|2|95,42
+165|prov_ho_chi_minh|3|95,47
+166|prov_phnom_penh|1|94,47
+167|prov_kuala_lumpur|2|92,51
+168|prov_kota_kinabalu|1|100,50
+169|prov_singapore|3|94,52
+170|prov_jakarta|3|95,56
+171|prov_surabaya|2|98,56
+172|prov_medan|2|91,52
+173|prov_banjarmasin|1|99,54
+174|prov_makassar|1|101,55
+175|prov_manila|3|102,45
+176|prov_cebu|1|104,48
+177|prov_port_moresby|1|115,57
+178|prov_new_york|4|25,27
+179|prov_washington|3|24,29
+180|prov_boston|2|26,25
+181|prov_chicago|3|21,26
+182|prov_detroit|2|22,26
+183|prov_atlanta|2|22,34
+184|prov_miami|2|23,39
+185|prov_houston|3|17,37
+186|prov_dallas|2|17,35
+187|prov_minneapolis|2|18,23
+188|prov_denver|2|15,28
+189|prov_phoenix|2|12,34
+190|prov_los_angeles|4|10,34
+191|prov_san_francisco|3|8,29
+192|prov_seattle|2|8,21
+193|prov_honolulu|2|2,41
+194|prov_midway|1|0,38
+195|prov_anchorage|1|4,8
+196|prov_toronto|3|23,25
+197|prov_montreal|2|25,23
+198|prov_vancouver|2|8,19
+199|prov_calgary|2|11,17
+200|prov_winnipeg|1|17,19
+201|prov_halifax|1|29,24
+202|prov_iqaluit|1|27,6
+203|prov_yellowknife|1|11,7
+204|prov_nuuk|1|32,6
+205|prov_mexico_city|4|16,43
+206|prov_guadalajara|2|15,42
+207|prov_monterrey|2|16,39
+208|prov_merida|1|20,42
+209|prov_guatemala|1|19,45
+210|prov_panama|2|23,48
+211|prov_havana|2|22,41
+212|prov_santo_domingo|1|26,43
+213|prov_bogota|3|25,51
+214|prov_medellin|2|25,50
+215|prov_caracas|2|28,48
+216|prov_quito|1|23,53
+217|prov_guayaquil|1|23,54
+218|prov_lima|3|24,59
+219|prov_cusco|1|26,59
+220|prov_la_paz|1|27,61
+221|prov_santiago|3|27,68
+222|prov_antofagasta|1|27,64
+223|prov_punta_arenas|1|26,75
+224|prov_buenos_aires|4|30,69
+225|prov_cordoba_ar|2|28,67
+226|prov_bariloche|1|26,71
+227|prov_montevideo|1|31,68
+228|prov_asuncion|1|30,65
+229|prov_sao_paulo|4|33,63
+230|prov_rio|3|34,63
+231|prov_brasilia|2|33,60
+232|prov_salvador|2|35,59
+233|prov_recife|2|36,57
+234|prov_manaus|2|30,54
+235|prov_belem|1|33,54
+236|prov_porto_alegre|2|32,67
+237|prov_sydney|3|116,68
+238|prov_melbourne|3|114,69
+239|prov_brisbane|2|116,66
+240|prov_adelaide|2|111,69
+241|prov_perth|2|99,67
+242|prov_darwin|1|107,59
+243|prov_alice_springs|1|109,64
+244|prov_hobart|1|115,71
+245|prov_auckland|2|119,70
+246|prov_christchurch|1|118,71
diff --git a/app/src/main/assets/scenarios/campaign_cw_01_suez.scn b/app/src/main/assets/scenarios/campaign_cw_01_suez.scn
index 364fe2d..e0c0b41 100644
--- a/app/src/main/assets/scenarios/campaign_cw_01_suez.scn
+++ b/app/src/main/assets/scenarios/campaign_cw_01_suez.scn
@@ -62,11 +62,11 @@ EGY|42,9|ANTI_AIR|2|-
EGY|42,10|ANTI_AIR|2|-
EGY|42,11|ANTI_AIR|2|-
EGY|43,11|ARMOUR|2|-
-EGY|42,8|ARMOUR|2|-
-EGY|41,8|ARTILLERY|2|-
-EGY|40,9|ARTILLERY|2|-
-EGY|41,10|ANTI_TANK|2|-
-EGY|46,16|ANTI_TANK|2|-
+EGY|40,9|ARMOUR|2|-
+EGY|41,10|ARTILLERY|2|-
+EGY|46,16|ARTILLERY|2|-
+EGY|45,15|ANTI_TANK|2|-
+EGY|44,15|ANTI_TANK|2|-
FRA|15,3|MARINE|3|-
FRA|18,18|MARINE|3|-
FRA|5,29|MARINE|3|-
@@ -75,12 +75,12 @@ FRA|15,2|TRANSPORT_SHIP|2|-
FRA|14,3|CRUISER|2|-
ISR|47,8|ARMOUR|3|-
ISR|48,8|ARMOUR|3|-
-ISR|46,7|ARMOUR|3|-
-ISR|46,8|INFANTRY|2|-
-ISR|46,9|INFANTRY|2|-
+ISR|46,9|ARMOUR|3|-
ISR|47,9|INFANTRY|2|-
-ISR|48,9|RECON|2|-
-ISR|45,7|RECON|2|-
+ISR|48,9|INFANTRY|2|-
+ISR|45,9|INFANTRY|2|-
+ISR|46,10|RECON|2|-
+ISR|47,10|RECON|2|-
SAU|50,19|INFANTRY|1|-
SAU|51,19|INFANTRY|1|-
ESP|7,2|INFANTRY|1|-
diff --git a/app/src/main/assets/scenarios/campaign_cw_01_suez_west.scn b/app/src/main/assets/scenarios/campaign_cw_01_suez_west.scn
index 30a75af..d5b466f 100644
--- a/app/src/main/assets/scenarios/campaign_cw_01_suez_west.scn
+++ b/app/src/main/assets/scenarios/campaign_cw_01_suez_west.scn
@@ -62,11 +62,11 @@ EGY|42,9|ANTI_AIR|2|-
EGY|42,10|ANTI_AIR|2|-
EGY|42,11|ANTI_AIR|2|-
EGY|43,11|ARMOUR|2|-
-EGY|42,8|ARMOUR|2|-
-EGY|41,8|ARTILLERY|2|-
-EGY|40,9|ARTILLERY|2|-
-EGY|41,10|ANTI_TANK|2|-
-EGY|46,16|ANTI_TANK|2|-
+EGY|40,9|ARMOUR|2|-
+EGY|41,10|ARTILLERY|2|-
+EGY|46,16|ARTILLERY|2|-
+EGY|45,15|ANTI_TANK|2|-
+EGY|44,15|ANTI_TANK|2|-
FRA|15,3|MARINE|3|-
FRA|18,18|MARINE|3|-
FRA|5,29|MARINE|3|-
@@ -75,12 +75,12 @@ FRA|15,2|TRANSPORT_SHIP|2|-
FRA|14,3|CRUISER|2|-
ISR|47,8|ARMOUR|3|-
ISR|48,8|ARMOUR|3|-
-ISR|46,7|ARMOUR|3|-
-ISR|46,8|INFANTRY|2|-
-ISR|46,9|INFANTRY|2|-
+ISR|46,9|ARMOUR|3|-
ISR|47,9|INFANTRY|2|-
-ISR|48,9|RECON|2|-
-ISR|45,7|RECON|2|-
+ISR|48,9|INFANTRY|2|-
+ISR|45,9|INFANTRY|2|-
+ISR|46,10|RECON|2|-
+ISR|47,10|RECON|2|-
SAU|50,19|INFANTRY|1|-
SAU|51,19|INFANTRY|1|-
ESP|7,2|INFANTRY|1|-
diff --git a/app/src/main/assets/scenarios/campaign_cw_03_central_front.scn b/app/src/main/assets/scenarios/campaign_cw_03_central_front.scn
index 5fd605f..7b92638 100644
--- a/app/src/main/assets/scenarios/campaign_cw_03_central_front.scn
+++ b/app/src/main/assets/scenarios/campaign_cw_03_central_front.scn
@@ -20,8 +20,8 @@ FRA|nation_fra|#4C5C9E|4|BALANCED|1200|1,1,1,0,0,1|🇫🇷|NATO|1
GBR|nation_gbr|#8C4C4C|0|BALANCED|1200|1,1,1,0,0,1|🇬🇧|NATO|1
NLD|nation_nld|#C4813C|8|TURTLE|500|1,1,1,0,0,1|🇳🇱|NATO|1
BEL|nation_bel|#9E8C4C|7|TURTLE|500|1,1,1,0,0,1|🇧🇪|NATO|1
-DNK|nation_dnk|#A85C6E|32|TURTLE|500|1,1,1,0,0,1|🇩🇰|NATO|1
-RUS|nation_sun|#8C6E4C|39|AGGRESSIVE|2200|3,3,3,2,0,3|🇷🇺|PACT|1
+DNK|nation_dnk|#A85C6E|33|TURTLE|500|1,1,1,0,0,1|🇩🇰|NATO|1
+RUS|nation_sun|#8C6E4C|41|AGGRESSIVE|2200|3,3,3,2,0,3|🇷🇺|PACT|1
POL|nation_pol|#B4535C|23|AGGRESSIVE|800|1,1,1,0,0,1|🇵🇱|PACT|1
CZE|nation_cze|#8A96A0|22|BALANCED|600|1,1,1,0,0,1|🇨🇿|PACT|1
HUN|nation_hun|#9E7A4C|25|BALANCED|500|1,1,1,0,0,1|🇭🇺|PACT|1
@@ -37,11 +37,11 @@ ROU|nation_rou|#8C7A3C|26|TURTLE|320|1,1,1,0,0,1|🇷🇴||1
SRB|nation_srb|#8C5C4C|27|TURTLE|260|1,1,1,0,0,1|🇷🇸||1
BGR|nation_bgr|#6E8C5C|28|TURTLE|240|1,1,1,0,0,1|🇧🇬||1
GRC|nation_grc|#4C7AA8|29|TURTLE|300|1,1,1,0,0,1|🇬🇷||1
-NOR|nation_nor|#5C7EA8|31|TURTLE|380|1,1,1,0,0,1|🇳🇴||1
-FIN|nation_fin|#7A9EB4|33|TURTLE|320|1,1,1,0,0,1|🇫🇮||1
-TUR|nation_tur|#A84C4C|42|TURTLE|740|1,1,1,0,0,1|🇹🇷||1
-TUN|nation_tun|#9E5C5C|45|TURTLE|240|1,1,1,0,0,1|🇹🇳||1
-DZA|nation_dza|#5C9E5C|46|TURTLE|460|1,1,1,0,0,1|🇩🇿||1
+NOR|nation_nor|#5C7EA8|32|TURTLE|380|1,1,1,0,0,1|🇳🇴||1
+FIN|nation_fin|#7A9EB4|35|TURTLE|320|1,1,1,0,0,1|🇫🇮||1
+TUR|nation_tur|#A84C4C|44|TURTLE|740|1,1,1,0,0,1|🇹🇷||1
+TUN|nation_tun|#9E5C5C|47|TURTLE|240|1,1,1,0,0,1|🇹🇳||1
+DZA|nation_dza|#5C9E5C|48|TURTLE|460|1,1,1,0,0,1|🇩🇿||1
[relations]
DEU RUS WAR
@@ -81,15 +81,15 @@ FRA: 4-6
GBR: 0-2
NLD: 8
BEL: 7
-DNK: 32
-RUS: 34-41
+DNK: 33-34
+RUS: 36-43
POL: 23-24
CZE: 22
HUN: 25
DDR: 17
CHE: 16
AUT: 21
-SWE: 30
+SWE: 30-31
IRL: 3
ESP: 9-11
PRT: 12
@@ -98,28 +98,28 @@ ROU: 26
SRB: 27
BGR: 28
GRC: 29
-NOR: 31
-FIN: 33
-TUR: 42-44
-TUN: 45
-DZA: 46
+NOR: 32
+FIN: 35
+TUR: 44-46
+TUN: 47
+DZA: 48
[units]
DEU|21,12|HEADQUARTERS|2|-
DEU|23,20|ANTI_TANK|3|-
DEU|18,16|ANTI_TANK|3|-
DEU|22,12|ANTI_TANK|3|-
-DEU|20,13|ANTI_TANK|3|-
+DEU|20,11|ANTI_TANK|3|-
+DEU|20,13|ARMOUR|3|-
DEU|21,13|ARMOUR|3|-
DEU|24,20|ARMOUR|3|-
-DEU|23,19|ARMOUR|3|-
+DEU|23,19|INFANTRY|3|-
DEU|22,19|INFANTRY|3|-
DEU|22,20|INFANTRY|3|-
-DEU|22,21|INFANTRY|3|-
+DEU|22,21|ARTILLERY|3|-
DEU|23,21|ARTILLERY|3|-
-DEU|19,16|ARTILLERY|3|-
+DEU|19,16|ANTI_AIR|3|-
DEU|18,15|ANTI_AIR|3|-
-DEU|17,15|ANTI_AIR|3|-
FRA|13,19|ARMOUR|3|-
FRA|16,24|ARMOUR|3|-
FRA|10,25|ARTILLERY|3|-
@@ -131,7 +131,7 @@ NLD|17,14|INFANTRY|2|-
BEL|16,16|INFANTRY|2|-
BEL|17,16|INFANTRY|2|-
DNK|24,9|INFANTRY|2|-
-DNK|25,8|ANTI_AIR|2|-
+DNK|22,8|ANTI_AIR|2|-
RUS|49,9|ARMOUR|3|-
RUS|41,3|ARMOUR|3|-
RUS|51,22|ARMOUR|3|-
@@ -169,7 +169,7 @@ CHE|20,21|MOUNTAIN_INFANTRY|3|-
CHE|20,20|ANTI_AIR|2|-
AUT|28,20|INFANTRY|2|-
SWE|29,3|INFANTRY|2|-
-SWE|30,2|INFANTRY|2|-
+SWE|23,6|INFANTRY|2|-
IRL|5,12|INFANTRY|1|-
BGR|35,28|INFANTRY|1|-
DZA|14,37|INFANTRY|1|-
diff --git a/app/src/main/assets/scenarios/campaign_cw_03_central_front_pact.scn b/app/src/main/assets/scenarios/campaign_cw_03_central_front_pact.scn
index 05c8cd5..4e37df8 100644
--- a/app/src/main/assets/scenarios/campaign_cw_03_central_front_pact.scn
+++ b/app/src/main/assets/scenarios/campaign_cw_03_central_front_pact.scn
@@ -20,8 +20,8 @@ FRA|nation_fra|#4C5C9E|4|BALANCED|1200|1,1,1,0,0,1|🇫🇷|NATO|1
GBR|nation_gbr|#8C4C4C|0|BALANCED|1200|1,1,1,0,0,1|🇬🇧|NATO|1
NLD|nation_nld|#C4813C|8|TURTLE|500|1,1,1,0,0,1|🇳🇱|NATO|1
BEL|nation_bel|#9E8C4C|7|TURTLE|500|1,1,1,0,0,1|🇧🇪|NATO|1
-DNK|nation_dnk|#A85C6E|32|TURTLE|500|1,1,1,0,0,1|🇩🇰|NATO|1
-RUS|nation_sun|#8C6E4C|39|AGGRESSIVE|2200|3,3,3,2,0,3|🇷🇺|PACT|1
+DNK|nation_dnk|#A85C6E|33|TURTLE|500|1,1,1,0,0,1|🇩🇰|NATO|1
+RUS|nation_sun|#8C6E4C|41|AGGRESSIVE|2200|3,3,3,2,0,3|🇷🇺|PACT|1
POL|nation_pol|#B4535C|23|AGGRESSIVE|800|1,1,1,0,0,1|🇵🇱|PACT|1
CZE|nation_cze|#8A96A0|22|BALANCED|600|1,1,1,0,0,1|🇨🇿|PACT|1
HUN|nation_hun|#9E7A4C|25|BALANCED|500|1,1,1,0,0,1|🇭🇺|PACT|1
@@ -37,11 +37,11 @@ ROU|nation_rou|#8C7A3C|26|TURTLE|320|1,1,1,0,0,1|🇷🇴||1
SRB|nation_srb|#8C5C4C|27|TURTLE|260|1,1,1,0,0,1|🇷🇸||1
BGR|nation_bgr|#6E8C5C|28|TURTLE|240|1,1,1,0,0,1|🇧🇬||1
GRC|nation_grc|#4C7AA8|29|TURTLE|300|1,1,1,0,0,1|🇬🇷||1
-NOR|nation_nor|#5C7EA8|31|TURTLE|380|1,1,1,0,0,1|🇳🇴||1
-FIN|nation_fin|#7A9EB4|33|TURTLE|320|1,1,1,0,0,1|🇫🇮||1
-TUR|nation_tur|#A84C4C|42|TURTLE|740|1,1,1,0,0,1|🇹🇷||1
-TUN|nation_tun|#9E5C5C|45|TURTLE|240|1,1,1,0,0,1|🇹🇳||1
-DZA|nation_dza|#5C9E5C|46|TURTLE|460|1,1,1,0,0,1|🇩🇿||1
+NOR|nation_nor|#5C7EA8|32|TURTLE|380|1,1,1,0,0,1|🇳🇴||1
+FIN|nation_fin|#7A9EB4|35|TURTLE|320|1,1,1,0,0,1|🇫🇮||1
+TUR|nation_tur|#A84C4C|44|TURTLE|740|1,1,1,0,0,1|🇹🇷||1
+TUN|nation_tun|#9E5C5C|47|TURTLE|240|1,1,1,0,0,1|🇹🇳||1
+DZA|nation_dza|#5C9E5C|48|TURTLE|460|1,1,1,0,0,1|🇩🇿||1
[relations]
DEU RUS WAR
@@ -81,15 +81,15 @@ FRA: 4-6
GBR: 0-2
NLD: 8
BEL: 7
-DNK: 32
-RUS: 34-41
+DNK: 33-34
+RUS: 36-43
POL: 23-24
CZE: 22
HUN: 25
DDR: 17
CHE: 16
AUT: 21
-SWE: 30
+SWE: 30-31
IRL: 3
ESP: 9-11
PRT: 12
@@ -98,28 +98,28 @@ ROU: 26
SRB: 27
BGR: 28
GRC: 29
-NOR: 31
-FIN: 33
-TUR: 42-44
-TUN: 45
-DZA: 46
+NOR: 32
+FIN: 35
+TUR: 44-46
+TUN: 47
+DZA: 48
[units]
DEU|21,12|HEADQUARTERS|2|-
DEU|23,20|ANTI_TANK|3|-
DEU|18,16|ANTI_TANK|3|-
DEU|22,12|ANTI_TANK|3|-
-DEU|20,13|ANTI_TANK|3|-
+DEU|20,11|ANTI_TANK|3|-
+DEU|20,13|ARMOUR|3|-
DEU|21,13|ARMOUR|3|-
DEU|24,20|ARMOUR|3|-
-DEU|23,19|ARMOUR|3|-
+DEU|23,19|INFANTRY|3|-
DEU|22,19|INFANTRY|3|-
DEU|22,20|INFANTRY|3|-
-DEU|22,21|INFANTRY|3|-
+DEU|22,21|ARTILLERY|3|-
DEU|23,21|ARTILLERY|3|-
-DEU|19,16|ARTILLERY|3|-
+DEU|19,16|ANTI_AIR|3|-
DEU|18,15|ANTI_AIR|3|-
-DEU|17,15|ANTI_AIR|3|-
FRA|13,19|ARMOUR|3|-
FRA|16,24|ARMOUR|3|-
FRA|10,25|ARTILLERY|3|-
@@ -131,7 +131,7 @@ NLD|17,14|INFANTRY|2|-
BEL|16,16|INFANTRY|2|-
BEL|17,16|INFANTRY|2|-
DNK|24,9|INFANTRY|2|-
-DNK|25,8|ANTI_AIR|2|-
+DNK|22,8|ANTI_AIR|2|-
RUS|49,9|ARMOUR|3|-
RUS|41,3|ARMOUR|3|-
RUS|51,22|ARMOUR|3|-
@@ -169,7 +169,7 @@ CHE|20,21|MOUNTAIN_INFANTRY|3|-
CHE|20,20|ANTI_AIR|2|-
AUT|28,20|INFANTRY|2|-
SWE|29,3|INFANTRY|2|-
-SWE|30,2|INFANTRY|2|-
+SWE|23,6|INFANTRY|2|-
IRL|5,12|INFANTRY|1|-
BGR|35,28|INFANTRY|1|-
DZA|14,37|INFANTRY|1|-
diff --git a/app/src/main/assets/scenarios/campaign_ww2_01_poland.scn b/app/src/main/assets/scenarios/campaign_ww2_01_poland.scn
index 841cf86..9a7cfd3 100644
--- a/app/src/main/assets/scenarios/campaign_ww2_01_poland.scn
+++ b/app/src/main/assets/scenarios/campaign_ww2_01_poland.scn
@@ -17,7 +17,7 @@ starTurns 20,23
[nations]
POL|nation_pol|#B4535C|23|BALANCED|700|1,1,1,0,0,1|🇵🇱|ALLIES|1
DEU|nation_deu|#6E7A86|17|AGGRESSIVE|1500|3,3,2,1,0,2|🇩🇪|AXIS|1
-RUS|nation_sun|#8C6E4C|39|TURTLE|600|1,1,1,0,0,1|🇷🇺||1
+RUS|nation_sun|#8C6E4C|41|TURTLE|600|1,1,1,0,0,1|🇷🇺||1
SWE|nation_swe|#4C6E9E|30|TURTLE|400|1,1,1,0,0,1|🇸🇪||1
GBR|nation_gbr|#8C4C4C|0|TURTLE|1100|1,1,1,0,0,1|🇬🇧||1
IRL|nation_irl|#4C8C5C|3|TURTLE|260|1,1,1,0,0,1|🇮🇪||1
@@ -33,10 +33,10 @@ ROU|nation_rou|#8C7A3C|26|TURTLE|320|1,1,1,0,0,1|🇷🇴||1
SRB|nation_srb|#8C5C4C|27|TURTLE|260|1,1,1,0,0,1|🇷🇸||1
BGR|nation_bgr|#6E8C5C|28|TURTLE|240|1,1,1,0,0,1|🇧🇬||1
GRC|nation_grc|#4C7AA8|29|TURTLE|300|1,1,1,0,0,1|🇬🇷||1
-NOR|nation_nor|#5C7EA8|31|TURTLE|380|1,1,1,0,0,1|🇳🇴||1
-DNK|nation_dnk|#A85C6E|32|TURTLE|320|1,1,1,0,0,1|🇩🇰||1
-FIN|nation_fin|#7A9EB4|33|TURTLE|320|1,1,1,0,0,1|🇫🇮||1
-TUR|nation_tur|#A84C4C|42|TURTLE|740|1,1,1,0,0,1|🇹🇷||1
+NOR|nation_nor|#5C7EA8|32|TURTLE|380|1,1,1,0,0,1|🇳🇴||1
+DNK|nation_dnk|#A85C6E|33|TURTLE|320|1,1,1,0,0,1|🇩🇰||1
+FIN|nation_fin|#7A9EB4|35|TURTLE|320|1,1,1,0,0,1|🇫🇮||1
+TUR|nation_tur|#A84C4C|44|TURTLE|740|1,1,1,0,0,1|🇹🇷||1
[relations]
DEU POL WAR
@@ -44,11 +44,11 @@ DEU POL WAR
[owners]
POL: 23-24
DEU: 17-22
-RUS: 34-41
-SWE: 30
+RUS: 36-43
+SWE: 30-31
GBR: 0-2
IRL: 3
-FRA: 4-6,45-46
+FRA: 4-6,47-48
BEL: 7
NLD: 8
ESP: 9-11
@@ -60,10 +60,10 @@ ROU: 26
SRB: 27
BGR: 28
GRC: 29
-NOR: 31
-DNK: 32
-FIN: 33
-TUR: 42-44
+NOR: 32
+DNK: 33-34
+FIN: 35
+TUR: 44-46
[units]
POL|32,14|INFANTRY|2|-
@@ -94,11 +94,12 @@ RUS|49,9|INFANTRY|1|-
RUS|39,12|INFANTRY|1|-
RUS|35,7|INFANTRY|1|-
SWE|29,3|INFANTRY|1|-
-SWE|30,2|INFANTRY|1|-
+SWE|23,6|INFANTRY|1|-
BEL|16,16|INFANTRY|1|-
BGR|35,28|INFANTRY|1|-
CHE|19,21|INFANTRY|1|-
DNK|24,9|INFANTRY|1|-
+DNK|22,8|INFANTRY|1|-
ESP|8,32|INFANTRY|1|-
ESP|14,30|INFANTRY|1|-
ESP|5,37|INFANTRY|1|-
diff --git a/app/src/main/assets/scenarios/campaign_ww2_01_poland_axis.scn b/app/src/main/assets/scenarios/campaign_ww2_01_poland_axis.scn
index 7ab558a..4ac9b73 100644
--- a/app/src/main/assets/scenarios/campaign_ww2_01_poland_axis.scn
+++ b/app/src/main/assets/scenarios/campaign_ww2_01_poland_axis.scn
@@ -17,7 +17,7 @@ starTurns 12,16
[nations]
POL|nation_pol|#B4535C|23|TURTLE|700|1,1,1,0,0,1|🇵🇱|ALLIES|1
DEU|nation_deu|#6E7A86|17|AGGRESSIVE|1500|3,3,2,1,0,2|🇩🇪|AXIS|1
-RUS|nation_sun|#8C6E4C|39|TURTLE|600|1,1,1,0,0,1|🇷🇺||1
+RUS|nation_sun|#8C6E4C|41|TURTLE|600|1,1,1,0,0,1|🇷🇺||1
SWE|nation_swe|#4C6E9E|30|TURTLE|400|1,1,1,0,0,1|🇸🇪||1
GBR|nation_gbr|#8C4C4C|0|TURTLE|1100|1,1,1,0,0,1|🇬🇧||1
IRL|nation_irl|#4C8C5C|3|TURTLE|260|1,1,1,0,0,1|🇮🇪||1
@@ -33,10 +33,10 @@ ROU|nation_rou|#8C7A3C|26|TURTLE|320|1,1,1,0,0,1|🇷🇴||1
SRB|nation_srb|#8C5C4C|27|TURTLE|260|1,1,1,0,0,1|🇷🇸||1
BGR|nation_bgr|#6E8C5C|28|TURTLE|240|1,1,1,0,0,1|🇧🇬||1
GRC|nation_grc|#4C7AA8|29|TURTLE|300|1,1,1,0,0,1|🇬🇷||1
-NOR|nation_nor|#5C7EA8|31|TURTLE|380|1,1,1,0,0,1|🇳🇴||1
-DNK|nation_dnk|#A85C6E|32|TURTLE|320|1,1,1,0,0,1|🇩🇰||1
-FIN|nation_fin|#7A9EB4|33|TURTLE|320|1,1,1,0,0,1|🇫🇮||1
-TUR|nation_tur|#A84C4C|42|TURTLE|740|1,1,1,0,0,1|🇹🇷||1
+NOR|nation_nor|#5C7EA8|32|TURTLE|380|1,1,1,0,0,1|🇳🇴||1
+DNK|nation_dnk|#A85C6E|33|TURTLE|320|1,1,1,0,0,1|🇩🇰||1
+FIN|nation_fin|#7A9EB4|35|TURTLE|320|1,1,1,0,0,1|🇫🇮||1
+TUR|nation_tur|#A84C4C|44|TURTLE|740|1,1,1,0,0,1|🇹🇷||1
[relations]
DEU POL WAR
@@ -44,11 +44,11 @@ DEU POL WAR
[owners]
POL: 23-24
DEU: 17-22
-RUS: 34-41
-SWE: 30
+RUS: 36-43
+SWE: 30-31
GBR: 0-2
IRL: 3
-FRA: 4-6,45-46
+FRA: 4-6,47-48
BEL: 7
NLD: 8
ESP: 9-11
@@ -60,10 +60,10 @@ ROU: 26
SRB: 27
BGR: 28
GRC: 29
-NOR: 31
-DNK: 32
-FIN: 33
-TUR: 42-44
+NOR: 32
+DNK: 33-34
+FIN: 35
+TUR: 44-46
[units]
POL|32,14|INFANTRY|2|-
@@ -94,11 +94,12 @@ RUS|49,9|INFANTRY|1|-
RUS|39,12|INFANTRY|1|-
RUS|35,7|INFANTRY|1|-
SWE|29,3|INFANTRY|1|-
-SWE|30,2|INFANTRY|1|-
+SWE|23,6|INFANTRY|1|-
BEL|16,16|INFANTRY|1|-
BGR|35,28|INFANTRY|1|-
CHE|19,21|INFANTRY|1|-
DNK|24,9|INFANTRY|1|-
+DNK|22,8|INFANTRY|1|-
ESP|8,32|INFANTRY|1|-
ESP|14,30|INFANTRY|1|-
ESP|5,37|INFANTRY|1|-
diff --git a/app/src/main/assets/scenarios/campaign_ww2_02_france.scn b/app/src/main/assets/scenarios/campaign_ww2_02_france.scn
index 19a7a08..9699e3d 100644
--- a/app/src/main/assets/scenarios/campaign_ww2_02_france.scn
+++ b/app/src/main/assets/scenarios/campaign_ww2_02_france.scn
@@ -32,11 +32,11 @@ SRB|nation_srb|#8C5C4C|27|TURTLE|260|1,1,1,0,0,1|🇷🇸||1
BGR|nation_bgr|#6E8C5C|28|TURTLE|240|1,1,1,0,0,1|🇧🇬||1
GRC|nation_grc|#4C7AA8|29|TURTLE|300|1,1,1,0,0,1|🇬🇷||1
SWE|nation_swe|#4C6E9E|30|TURTLE|420|1,1,1,0,0,1|🇸🇪||1
-NOR|nation_nor|#5C7EA8|31|TURTLE|380|1,1,1,0,0,1|🇳🇴||1
-DNK|nation_dnk|#A85C6E|32|TURTLE|320|1,1,1,0,0,1|🇩🇰||1
-FIN|nation_fin|#7A9EB4|33|TURTLE|320|1,1,1,0,0,1|🇫🇮||1
-RUS|nation_sun|#8C6E4C|39|TURTLE|1500|1,1,1,0,0,1|🇷🇺||1
-TUR|nation_tur|#A84C4C|42|TURTLE|740|1,1,1,0,0,1|🇹🇷||1
+NOR|nation_nor|#5C7EA8|32|TURTLE|380|1,1,1,0,0,1|🇳🇴||1
+DNK|nation_dnk|#A85C6E|33|TURTLE|320|1,1,1,0,0,1|🇩🇰||1
+FIN|nation_fin|#7A9EB4|35|TURTLE|320|1,1,1,0,0,1|🇫🇮||1
+RUS|nation_sun|#8C6E4C|41|TURTLE|1500|1,1,1,0,0,1|🇷🇺||1
+TUR|nation_tur|#A84C4C|44|TURTLE|740|1,1,1,0,0,1|🇹🇷||1
[relations]
DEU FRA WAR
@@ -46,7 +46,7 @@ DEU NLD WAR
[owners]
DEU: 17-22
-FRA: 4-6,45-46
+FRA: 4-6,47-48
GBR: 0-2
BEL: 7
NLD: 8
@@ -61,12 +61,12 @@ ROU: 26
SRB: 27
BGR: 28
GRC: 29
-SWE: 30
-NOR: 31
-DNK: 32
-FIN: 33
-RUS: 34-41
-TUR: 42-44
+SWE: 30-31
+NOR: 32
+DNK: 33-34
+FIN: 35
+RUS: 36-43
+TUR: 44-46
[units]
DEU|25,14|HEADQUARTERS|1|-
@@ -82,8 +82,8 @@ DEU|24,14|INFANTRY|2|-
DEU|24,15|INFANTRY|2|-
DEU|25,15|RECON|2|-
DEU|22,12|RECON|2|-
+DEU|20,11|SUPPLY_TRUCK|1|-
DEU|20,13|SUPPLY_TRUCK|1|-
-DEU|21,13|SUPPLY_TRUCK|1|-
FRA|13,19|INFANTRY|2|-
FRA|16,24|INFANTRY|2|-
FRA|10,25|INFANTRY|2|-
@@ -114,6 +114,7 @@ ESP|8,32|INFANTRY|1|-
ESP|14,30|INFANTRY|1|-
BGR|35,28|INFANTRY|1|-
DNK|24,9|INFANTRY|1|-
+DNK|22,8|INFANTRY|1|-
FIN|36,2|INFANTRY|1|-
GRC|35,36|INFANTRY|1|-
HUN|30,21|INFANTRY|1|-
@@ -136,6 +137,7 @@ RUS|41,3|INFANTRY|1|-
RUS|51,22|INFANTRY|1|-
SRB|31,25|INFANTRY|1|-
SWE|29,3|INFANTRY|1|-
+SWE|23,6|INFANTRY|1|-
TUR|40,31|INFANTRY|1|-
TUR|44,33|INFANTRY|1|-
TUR|38,35|INFANTRY|1|-
diff --git a/app/src/main/assets/scenarios/campaign_ww2_02_france_allies.scn b/app/src/main/assets/scenarios/campaign_ww2_02_france_allies.scn
index b3a7a7a..9ae90e7 100644
--- a/app/src/main/assets/scenarios/campaign_ww2_02_france_allies.scn
+++ b/app/src/main/assets/scenarios/campaign_ww2_02_france_allies.scn
@@ -32,11 +32,11 @@ SRB|nation_srb|#8C5C4C|27|TURTLE|260|1,1,1,0,0,1|🇷🇸||1
BGR|nation_bgr|#6E8C5C|28|TURTLE|240|1,1,1,0,0,1|🇧🇬||1
GRC|nation_grc|#4C7AA8|29|TURTLE|300|1,1,1,0,0,1|🇬🇷||1
SWE|nation_swe|#4C6E9E|30|TURTLE|420|1,1,1,0,0,1|🇸🇪||1
-NOR|nation_nor|#5C7EA8|31|TURTLE|380|1,1,1,0,0,1|🇳🇴||1
-DNK|nation_dnk|#A85C6E|32|TURTLE|320|1,1,1,0,0,1|🇩🇰||1
-FIN|nation_fin|#7A9EB4|33|TURTLE|320|1,1,1,0,0,1|🇫🇮||1
-RUS|nation_sun|#8C6E4C|39|TURTLE|1500|1,1,1,0,0,1|🇷🇺||1
-TUR|nation_tur|#A84C4C|42|TURTLE|740|1,1,1,0,0,1|🇹🇷||1
+NOR|nation_nor|#5C7EA8|32|TURTLE|380|1,1,1,0,0,1|🇳🇴||1
+DNK|nation_dnk|#A85C6E|33|TURTLE|320|1,1,1,0,0,1|🇩🇰||1
+FIN|nation_fin|#7A9EB4|35|TURTLE|320|1,1,1,0,0,1|🇫🇮||1
+RUS|nation_sun|#8C6E4C|41|TURTLE|1500|1,1,1,0,0,1|🇷🇺||1
+TUR|nation_tur|#A84C4C|44|TURTLE|740|1,1,1,0,0,1|🇹🇷||1
[relations]
DEU FRA WAR
@@ -46,7 +46,7 @@ DEU NLD WAR
[owners]
DEU: 17-22
-FRA: 4-6,45-46
+FRA: 4-6,47-48
GBR: 0-2
BEL: 7
NLD: 8
@@ -61,12 +61,12 @@ ROU: 26
SRB: 27
BGR: 28
GRC: 29
-SWE: 30
-NOR: 31
-DNK: 32
-FIN: 33
-RUS: 34-41
-TUR: 42-44
+SWE: 30-31
+NOR: 32
+DNK: 33-34
+FIN: 35
+RUS: 36-43
+TUR: 44-46
[units]
DEU|25,14|HEADQUARTERS|1|-
@@ -82,8 +82,8 @@ DEU|24,14|INFANTRY|2|-
DEU|24,15|INFANTRY|2|-
DEU|25,15|RECON|2|-
DEU|22,12|RECON|2|-
+DEU|20,11|SUPPLY_TRUCK|1|-
DEU|20,13|SUPPLY_TRUCK|1|-
-DEU|21,13|SUPPLY_TRUCK|1|-
FRA|13,19|INFANTRY|2|-
FRA|16,24|INFANTRY|2|-
FRA|10,25|INFANTRY|2|-
@@ -114,6 +114,7 @@ ESP|8,32|INFANTRY|1|-
ESP|14,30|INFANTRY|1|-
BGR|35,28|INFANTRY|1|-
DNK|24,9|INFANTRY|1|-
+DNK|22,8|INFANTRY|1|-
FIN|36,2|INFANTRY|1|-
GRC|35,36|INFANTRY|1|-
HUN|30,21|INFANTRY|1|-
@@ -136,6 +137,7 @@ RUS|41,3|INFANTRY|1|-
RUS|51,22|INFANTRY|1|-
SRB|31,25|INFANTRY|1|-
SWE|29,3|INFANTRY|1|-
+SWE|23,6|INFANTRY|1|-
TUR|40,31|INFANTRY|1|-
TUR|44,33|INFANTRY|1|-
TUR|38,35|INFANTRY|1|-
diff --git a/app/src/main/assets/scenarios/campaign_ww2_03_desert.scn b/app/src/main/assets/scenarios/campaign_ww2_03_desert.scn
index 65b62ff..52b2b68 100644
--- a/app/src/main/assets/scenarios/campaign_ww2_03_desert.scn
+++ b/app/src/main/assets/scenarios/campaign_ww2_03_desert.scn
@@ -54,8 +54,8 @@ GBR|42,9|SUPPLY_TRUCK|1|-
GBR|42,10|ARTILLERY|2|-
GBR|42,11|ARTILLERY|2|-
GBR|43,11|RECON|2|-
-GBR|42,8|RECON|2|-
-GBR|44,4|DESTROYER|2|-
+GBR|40,9|RECON|2|-
+GBR|46,7|DESTROYER|2|-
ITA|25,7|INFANTRY|2|-
ITA|50,32|INFANTRY|2|-
ITA|26,7|INFANTRY|2|-
diff --git a/app/src/main/assets/scenarios/campaign_ww2_03_desert_axis.scn b/app/src/main/assets/scenarios/campaign_ww2_03_desert_axis.scn
index cf51322..b9026c6 100644
--- a/app/src/main/assets/scenarios/campaign_ww2_03_desert_axis.scn
+++ b/app/src/main/assets/scenarios/campaign_ww2_03_desert_axis.scn
@@ -54,8 +54,8 @@ GBR|42,9|SUPPLY_TRUCK|1|-
GBR|42,10|ARTILLERY|2|-
GBR|42,11|ARTILLERY|2|-
GBR|43,11|RECON|2|-
-GBR|42,8|RECON|2|-
-GBR|44,4|DESTROYER|2|-
+GBR|40,9|RECON|2|-
+GBR|46,7|DESTROYER|2|-
ITA|25,7|INFANTRY|2|-
ITA|50,32|INFANTRY|2|-
ITA|26,7|INFANTRY|2|-
diff --git a/app/src/main/assets/scenarios/campaign_ww2_06_philippines.scn b/app/src/main/assets/scenarios/campaign_ww2_06_philippines.scn
index 11a7f93..be3fa48 100644
--- a/app/src/main/assets/scenarios/campaign_ww2_06_philippines.scn
+++ b/app/src/main/assets/scenarios/campaign_ww2_06_philippines.scn
@@ -31,20 +31,20 @@ THA: 7-8
ROC: 1
[units]
-USA|24,25|CARRIER|3|-
USA|23,25|CARRIER|3|-
-USA|25,25|TRANSPORT_SHIP|2|-
-USA|26,25|TRANSPORT_SHIP|2|-
-USA|27,25|TRANSPORT_SHIP|2|-
+USA|22,25|CARRIER|3|-
+USA|22,26|TRANSPORT_SHIP|2|-
+USA|22,27|TRANSPORT_SHIP|2|-
+USA|24,25|TRANSPORT_SHIP|2|-
USA|49,37|MARINE|3|-
USA|23,32|MARINE|3|-
USA|50,37|MARINE|3|-
-USA|29,26|BATTLESHIP|3|-
-USA|28,25|DESTROYER|2|-
-USA|28,27|DESTROYER|2|-
-USA|22,29|DESTROYER|2|-
-USA|29,28|SUBMARINE|2|-
-USA|28,29|SUBMARINE|2|-
+USA|25,25|BATTLESHIP|3|-
+USA|26,25|DESTROYER|2|-
+USA|27,25|DESTROYER|2|-
+USA|29,26|DESTROYER|2|-
+USA|28,25|SUBMARINE|2|-
+USA|28,27|SUBMARINE|2|-
JPN|24,11|INFANTRY|2|-
JPN|27,16|INFANTRY|2|-
JPN|11,33|INFANTRY|2|-
diff --git a/app/src/main/assets/scenarios/campaign_ww2_06_philippines_axis.scn b/app/src/main/assets/scenarios/campaign_ww2_06_philippines_axis.scn
index bbfafe3..4421a9f 100644
--- a/app/src/main/assets/scenarios/campaign_ww2_06_philippines_axis.scn
+++ b/app/src/main/assets/scenarios/campaign_ww2_06_philippines_axis.scn
@@ -31,20 +31,20 @@ THA: 7-8
ROC: 1
[units]
-USA|24,25|CARRIER|3|-
USA|23,25|CARRIER|3|-
-USA|25,25|TRANSPORT_SHIP|2|-
-USA|26,25|TRANSPORT_SHIP|2|-
-USA|27,25|TRANSPORT_SHIP|2|-
+USA|22,25|CARRIER|3|-
+USA|22,26|TRANSPORT_SHIP|2|-
+USA|22,27|TRANSPORT_SHIP|2|-
+USA|24,25|TRANSPORT_SHIP|2|-
USA|49,37|MARINE|3|-
USA|23,32|MARINE|3|-
USA|50,37|MARINE|3|-
-USA|29,26|BATTLESHIP|3|-
-USA|28,25|DESTROYER|2|-
-USA|28,27|DESTROYER|2|-
-USA|22,29|DESTROYER|2|-
-USA|29,28|SUBMARINE|2|-
-USA|28,29|SUBMARINE|2|-
+USA|25,25|BATTLESHIP|3|-
+USA|26,25|DESTROYER|2|-
+USA|27,25|DESTROYER|2|-
+USA|29,26|DESTROYER|2|-
+USA|28,25|SUBMARINE|2|-
+USA|28,27|SUBMARINE|2|-
JPN|24,11|INFANTRY|2|-
JPN|27,16|INFANTRY|2|-
JPN|11,33|INFANTRY|2|-
diff --git a/app/src/main/assets/scenarios/conquest_1939.scn b/app/src/main/assets/scenarios/conquest_1939.scn
index 62c5681..7d56358 100644
--- a/app/src/main/assets/scenarios/conquest_1939.scn
+++ b/app/src/main/assets/scenarios/conquest_1939.scn
@@ -13,50 +13,50 @@ startYear 1939
startMonth 9
[nations]
-RUS|nation_sun|#8C6E4C|41|AGGRESSIVE|3900|2,2,2,2,2,1|🇷🇺|ALLIES|8
-USA|nation_usa|#4C7BA8|171|BALANCED|3440|2,2,2,2,2,1|🇺🇸|ALLIES|10
-GBR|nation_gbr|#8C4C4C|0|BALANCED|3410|2,2,2,2,2,1|🇬🇧|ALLIES|1
-JPN|nation_jpn|#C45C5C|148|BALANCED|1920|2,2,2,2,2,1|🇯🇵|AXIS|1
-ROC|nation_roc|#B4454C|128|BALANCED|1760|2,2,2,2,2,1|🇹🇼|ALLIES|1
+RUS|nation_sun|#8C6E4C|46|AGGRESSIVE|3900|2,2,2,2,2,1|🇷🇺|ALLIES|8
+GBR|nation_gbr|#8C4C4C|0|BALANCED|3465|2,2,2,2,2,1|🇬🇧|ALLIES|1
+USA|nation_usa|#4C7BA8|178|BALANCED|3440|2,2,2,2,2,1|🇺🇸|ALLIES|10
+JPN|nation_jpn|#C45C5C|155|BALANCED|1980|2,2,2,2,2,1|🇯🇵|AXIS|1
+ROC|nation_roc|#B4454C|134|BALANCED|1760|2,2,2,2,2,1|🇹🇼|ALLIES|1
FRA|nation_fra|#4C5C9E|4|BALANCED|1757|2,2,2,2,2,1|🇫🇷|ALLIES|1
DEU|nation_deu|#6E7A86|17|AGGRESSIVE|1495|2,2,2,2,2,1|🇩🇪|AXIS|1
-BRA|nation_bra|#4F9A50|222|TURTLE|1260|1,1,1,1,1,1|🇧🇷||1
-AUS|nation_aus|#C4A05C|230|BALANCED|1189|1,1,1,1,1,1|🇦🇺|ALLIES|1
-CAN|nation_can|#6E93B5|189|TURTLE|979|1,1,1,1,1,1|🇨🇦|ALLIES|1
+BRA|nation_bra|#4F9A50|229|TURTLE|1260|1,1,1,1,1,1|🇧🇷||1
+AUS|nation_aus|#C4A05C|237|BALANCED|1189|1,1,1,1,1,1|🇦🇺|ALLIES|1
+CAN|nation_can|#6E93B5|196|TURTLE|979|1,1,1,1,1,1|🇨🇦|ALLIES|1
ITA|nation_ita|#5C9E6E|13|OPPORTUNIST|910|1,1,1,1,1,1|🇮🇹|AXIS|1
-SAU|nation_sau|#4C8C5C|78|TURTLE|902|1,1,1,1,1,1|🇸🇦||1
-TUR|nation_tur|#A84C4C|68|TURTLE|850|1,1,0,0,0,1|🇹🇷||1
-IRN|nation_irn|#4C8C6E|71|TURTLE|804|1,1,0,0,0,1|🇮🇷||1
-MEX|nation_mex|#3F8F6B|198|TURTLE|720|1,1,0,0,0,1|🇲🇽||1
-ARG|nation_arg|#6FA8C4|217|TURTLE|690|1,1,0,0,0,1|🇦🇷||1
+SAU|nation_sau|#4C8C5C|83|TURTLE|902|1,1,1,1,1,1|🇸🇦||1
+TUR|nation_tur|#A84C4C|73|TURTLE|850|1,1,0,0,0,1|🇹🇷||1
+IRN|nation_irn|#4C8C6E|76|TURTLE|804|1,1,0,0,0,1|🇮🇷||1
+MEX|nation_mex|#3F8F6B|205|TURTLE|720|1,1,0,0,0,1|🇲🇽||1
+ARG|nation_arg|#6FA8C4|224|TURTLE|690|1,1,0,0,0,1|🇦🇷||1
ESP|nation_esp|#B08A3C|9|TURTLE|644|1,1,0,0,0,1|🇪🇸||1
POL|nation_pol|#B4535C|23|BALANCED|572|1,1,0,0,0,1|🇵🇱|ALLIES|1
-THA|nation_tha|#5C86A8|155|BALANCED|528|1,1,0,0,0,1|🇹🇭||1
-NLD|nation_nld|#C4813C|163|TURTLE|494|0,0,0,0,0,0|🇳🇱||1
-CHL|nation_chl|#A8544C|214|TURTLE|482|0,0,0,0,0,0|🇨🇱||1
-COL|nation_col|#C29A3C|206|TURTLE|462|0,0,0,0,0,0|🇨🇴||1
-SWE|nation_swe|#4C6E9E|30|TURTLE|441|0,0,0,0,0,0|🇸🇪||1
-NOR|nation_nor|#5C7EA8|31|TURTLE|418|0,0,0,0,0,0|🇳🇴||1
-NZL|nation_nzl|#5C9E93|238|TURTLE|418|0,0,0,0,0,0|🇳🇿|ALLIES|1
-PER|nation_per|#B06A4C|211|TURTLE|418|0,0,0,0,0,0|🇵🇪||1
-VEN|nation_ven|#B4703C|208|TURTLE|399|0,0,0,0,0,0|🇻🇪||1
+THA|nation_tha|#5C86A8|162|BALANCED|528|1,1,0,0,0,1|🇹🇭||1
+SWE|nation_swe|#4C6E9E|30|TURTLE|504|1,1,0,0,0,1|🇸🇪||1
+NLD|nation_nld|#C4813C|170|TURTLE|494|0,0,0,0,0,0|🇳🇱||1
+CHL|nation_chl|#A8544C|221|TURTLE|482|0,0,0,0,0,0|🇨🇱||1
+COL|nation_col|#C29A3C|213|TURTLE|462|0,0,0,0,0,0|🇨🇴||1
+NOR|nation_nor|#5C7EA8|34|TURTLE|418|0,0,0,0,0,0|🇳🇴||1
+NZL|nation_nzl|#5C9E93|245|TURTLE|418|0,0,0,0,0,0|🇳🇿|ALLIES|1
+PER|nation_per|#B06A4C|218|TURTLE|418|0,0,0,0,0,0|🇵🇪||1
+VEN|nation_ven|#B4703C|215|TURTLE|399|0,0,0,0,0,0|🇻🇪||1
+DNK|nation_dnk|#A85C6E|35|TURTLE|384|0,0,0,0,0,0|🇩🇰||1
CHE|nation_che|#B45C5C|16|TURTLE|378|0,0,0,0,0,0|🇨🇭||1
-BEL|nation_bel|#9E8C4C|105|TURTLE|368|0,0,0,0,0,0|🇧🇪||1
-DNK|nation_dnk|#A85C6E|32|TURTLE|368|0,0,0,0,0,0|🇩🇰||1
+BEL|nation_bel|#9E8C4C|110|TURTLE|368|0,0,0,0,0,0|🇧🇪||1
+FIN|nation_fin|#7A9EB4|37|TURTLE|352|0,0,0,0,0,0|🇫🇮||1
PRT|nation_prt|#4C8C7A|12|TURTLE|345|0,0,0,0,0,0|🇵🇹||1
-FIN|nation_fin|#7A9EB4|33|TURTLE|336|0,0,0,0,0,0|🇫🇮||1
ROU|nation_rou|#8C7A3C|26|TURTLE|336|0,0,0,0,0,0|🇷🇴||1
GRC|nation_grc|#4C7AA8|29|TURTLE|315|0,0,0,0,0,0|🇬🇷||1
HUN|nation_hun|#9E7A4C|25|OPPORTUNIST|315|0,0,0,0,0,0|🇭🇺||1
IRL|nation_irl|#4C8C5C|3|TURTLE|273|0,0,0,0,0,0|🇮🇪||1
SRB|nation_srb|#8C5C4C|27|OPPORTUNIST|273|0,0,0,0,0,0|🇷🇸||1
-ECU|nation_ecu|#C7A24E|209|TURTLE|264|0,0,0,0,0,0|🇪🇨||1
+ECU|nation_ecu|#C7A24E|216|TURTLE|264|0,0,0,0,0,0|🇪🇨||1
BGR|nation_bgr|#6E8C5C|28|TURTLE|252|0,0,0,0,0,0|🇧🇬||1
-BOL|nation_bol|#8C9A4C|213|TURTLE|252|0,0,0,0,0,0|🇧🇴||1
-AFG|nation_afg|#8C7A5C|83|TURTLE|231|0,0,0,0,0,0|🇦🇫||1
-GTM|nation_gtm|#57A07E|202|TURTLE|231|0,0,0,0,0,0|🇬🇹||1
-URY|nation_ury|#6E9BB0|220|TURTLE|231|0,0,0,0,0,0|🇺🇾||1
-PRY|nation_pry|#7F8F5C|221|TURTLE|210|0,0,0,0,0,0|🇵🇾||1
+BOL|nation_bol|#8C9A4C|220|TURTLE|252|0,0,0,0,0,0|🇧🇴||1
+AFG|nation_afg|#8C7A5C|88|TURTLE|231|0,0,0,0,0,0|🇦🇫||1
+GTM|nation_gtm|#57A07E|209|TURTLE|231|0,0,0,0,0,0|🇬🇹||1
+URY|nation_ury|#6E9BB0|227|TURTLE|231|0,0,0,0,0,0|🇺🇾||1
+PRY|nation_pry|#7F8F5C|228|TURTLE|210|0,0,0,0,0,0|🇵🇾||1
[relations]
DEU GBR WAR
@@ -82,168 +82,167 @@ JPN AUS WAR
JPN NZL WAR
[owners]
-RUS: 34,37-67
-USA: 168-169,171-188,203-205
-GBR: 0-2,74-75,77,80-82,84-86,96-98,100,103-104,108-113,116-127,142,153-154,160-162
-JPN: 135-136,143-152
-ROC: 128-134,137-141
-FRA: 4-6,76,88-95,99,115,157-159
+RUS: 39,42-72
+GBR: 0-2,79-80,82,85-87,89-91,101-103,105,108-109,113-118,121-133,148,160-161,167-169
+USA: 175-176,178-195,210-212
+JPN: 141-142,149-159
+ROC: 134-140,143-147
+FRA: 4-6,81,93-100,104,120,164-166
DEU: 17-22
-BRA: 222-229
-AUS: 170,230-237
-CAN: 189-196
-ITA: 13-15,87,101-102
-SAU: 78-79
-TUR: 68-70
-IRN: 71-73
-MEX: 198-201
-ARG: 217-219
+BRA: 229-236
+AUS: 177,237-244
+CAN: 196-203
+ITA: 13-15,92,106-107
+SAU: 83-84
+TUR: 73-75
+IRN: 76-78
+MEX: 205-208
+ARG: 224-226
ESP: 9-11
POL: 23-24
-THA: 155-156
-NLD: 8,163-167
-CHL: 214-216
-COL: 206-207
-SWE: 30
-NOR: 31,36
-NZL: 238-239
-PER: 211-212
-VEN: 208
+THA: 162-163
+SWE: 30-33
+NLD: 8,170-174
+CHL: 221-223
+COL: 213-214
+NOR: 34,41
+NZL: 245-246
+PER: 218-219
+VEN: 215
+DNK: 35-36,40,204
CHE: 16
-BEL: 7,105-106
-DNK: 32,35,197
-PRT: 12,107,114
-FIN: 33
+BEL: 7,110-111
+FIN: 37-38
+PRT: 12,112,119
ROU: 26
GRC: 29
HUN: 25
IRL: 3
SRB: 27
-ECU: 209-210
+ECU: 216-217
BGR: 28
-BOL: 213
-AFG: 83
-GTM: 202
-URY: 220
-PRY: 221
+BOL: 220
+AFG: 88
+GTM: 209
+URY: 227
+PRY: 228
[units]
-GBR|47,15|INFANTRY|1|-
-GBR|46,15|ARTILLERY|1|-
-GBR|45,15|ARMOUR|1|-
-GBR|74,32|INFANTRY|1|-
-GBR|65,35|INFANTRY|1|-
-GBR|49,49|INFANTRY|1|-
-GBR|64,64|INFANTRY|1|-
-GBR|84,36|INFANTRY|1|-
-GBR|82,41|INFANTRY|1|-
-GBR|87,39|INFANTRY|1|-
-GBR|81,38|INFANTRY|1|-
+GBR|47,17|INFANTRY|1|-
+GBR|46,17|ARTILLERY|1|-
+GBR|45,17|ARMOUR|1|-
+GBR|74,34|INFANTRY|1|-
+GBR|65,37|INFANTRY|1|-
+GBR|49,50|INFANTRY|1|-
+GBR|63,65|INFANTRY|1|-
+GBR|84,38|INFANTRY|1|-
+GBR|82,43|INFANTRY|1|-
+GBR|87,41|INFANTRY|1|-
+GBR|81,40|INFANTRY|1|-
GBR|99,40|INFANTRY|1|-
-GBR|93,51|INFANTRY|1|-
-GBR|48,15|DESTROYER|1|-
-IRL|43,13|INFANTRY|1|-
-FRA|48,17|INFANTRY|1|-
-FRA|49,17|ARTILLERY|1|-
-FRA|49,16|ARMOUR|1|-
-FRA|95,46|INFANTRY|1|-
-FRA|48,16|DESTROYER|1|-
-BEL|56,54|INFANTRY|1|-
-NLD|95,55|INFANTRY|1|-
-NLD|94,55|ARTILLERY|1|-
-ESP|45,26|INFANTRY|1|-
-ESP|46,26|ARTILLERY|1|-
-PRT|41,27|INFANTRY|1|-
-ITA|55,24|INFANTRY|1|-
-ITA|56,24|ARTILLERY|1|-
-ITA|55,23|ARMOUR|1|-
-ITA|52,21|INFANTRY|1|-
-ITA|54,24|DESTROYER|1|-
-CHE|52,19|INFANTRY|1|-
-DEU|55,14|INFANTRY|1|-
-DEU|56,14|ARTILLERY|1|-
-DEU|55,13|ARMOUR|1|-
-DEU|54,18|INFANTRY|1|-
-DEU|57,18|INFANTRY|1|-
-POL|60,14|INFANTRY|1|-
-POL|61,14|ARTILLERY|1|-
-HUN|58,19|INFANTRY|1|-
-ROU|63,22|INFANTRY|1|-
-SRB|59,21|INFANTRY|1|-
-BGR|61,23|INFANTRY|1|-
-GRC|61,28|INFANTRY|1|-
-SWE|58,7|INFANTRY|1|-
-SWE|59,6|ARTILLERY|1|-
-NOR|53,7|INFANTRY|1|-
-NOR|54,7|ARTILLERY|1|-
-DNK|54,11|INFANTRY|1|-
-FIN|62,7|INFANTRY|1|-
-RUS|69,11|INFANTRY|1|-
-RUS|70,11|ARTILLERY|1|-
-RUS|70,10|ARMOUR|1|-
-RUS|65,16|INFANTRY|1|-
-RUS|65,7|INFANTRY|1|-
-TUR|64,25|INFANTRY|1|-
-TUR|65,25|ARTILLERY|1|-
-TUR|65,26|ARMOUR|1|-
-IRN|76,30|INFANTRY|1|-
-IRN|77,30|ARTILLERY|1|-
-IRN|76,29|ARMOUR|1|-
-SAU|74,39|INFANTRY|1|-
-SAU|75,39|ARTILLERY|1|-
-SAU|75,38|ARMOUR|1|-
-AFG|81,31|INFANTRY|1|-
-ROC|100,26|INFANTRY|1|-
-ROC|101,26|ARTILLERY|1|-
-ROC|100,25|ARMOUR|1|-
-ROC|103,34|INFANTRY|1|-
-ROC|98,39|INFANTRY|1|-
-ROC|98,35|INFANTRY|1|-
-ROC|93,35|INFANTRY|1|-
-JPN|112,30|INFANTRY|1|-
-JPN|112,29|ARTILLERY|1|-
-JPN|111,29|ARMOUR|1|-
-JPN|103,38|INFANTRY|1|-
-JPN|106,28|INFANTRY|1|-
-JPN|109,31|INFANTRY|1|-
-JPN|113,30|DESTROYER|1|-
-THA|92,44|INFANTRY|1|-
-THA|93,44|ARTILLERY|1|-
-USA|25,25|INFANTRY|1|-
-USA|26,24|ARTILLERY|1|-
-USA|25,24|ARMOUR|1|-
-USA|102,44|INFANTRY|1|-
-USA|24,27|INFANTRY|1|-
-USA|21,24|INFANTRY|1|-
-USA|18,36|INFANTRY|1|-
-USA|10,32|INFANTRY|1|-
-USA|9,28|INFANTRY|1|-
-USA|26,25|DESTROYER|1|-
+GBR|94,52|INFANTRY|1|-
+GBR|48,17|DESTROYER|1|-
+IRL|43,15|INFANTRY|1|-
+FRA|49,20|INFANTRY|1|-
+FRA|50,20|ARTILLERY|1|-
+FRA|49,19|ARMOUR|1|-
+FRA|95,47|INFANTRY|1|-
+BEL|56,55|INFANTRY|1|-
+NLD|95,56|INFANTRY|1|-
+NLD|96,56|ARTILLERY|1|-
+ESP|45,27|INFANTRY|1|-
+ESP|46,27|ARTILLERY|1|-
+PRT|41,29|INFANTRY|1|-
+ITA|55,26|INFANTRY|1|-
+ITA|56,26|ARTILLERY|1|-
+ITA|55,25|ARMOUR|1|-
+ITA|52,23|INFANTRY|1|-
+ITA|54,26|DESTROYER|1|-
+CHE|52,21|INFANTRY|1|-
+DEU|55,16|INFANTRY|1|-
+DEU|56,16|ARTILLERY|1|-
+DEU|55,15|ARMOUR|1|-
+DEU|54,20|INFANTRY|1|-
+DEU|57,20|INFANTRY|1|-
+POL|60,16|INFANTRY|1|-
+POL|61,16|ARTILLERY|1|-
+HUN|58,21|INFANTRY|1|-
+ROU|63,24|INFANTRY|1|-
+SRB|59,23|INFANTRY|1|-
+BGR|61,25|INFANTRY|1|-
+GRC|61,30|INFANTRY|1|-
+SWE|58,10|INFANTRY|1|-
+SWE|58,9|ARTILLERY|1|-
+NOR|53,9|INFANTRY|1|-
+NOR|54,9|ARTILLERY|1|-
+DNK|54,13|INFANTRY|1|-
+FIN|62,9|INFANTRY|1|-
+RUS|69,13|INFANTRY|1|-
+RUS|70,13|ARTILLERY|1|-
+RUS|70,12|ARMOUR|1|-
+RUS|65,18|INFANTRY|1|-
+RUS|65,9|INFANTRY|1|-
+TUR|64,27|INFANTRY|1|-
+TUR|65,27|ARTILLERY|1|-
+TUR|65,28|ARMOUR|1|-
+IRN|76,32|INFANTRY|1|-
+IRN|77,32|ARTILLERY|1|-
+IRN|76,31|ARMOUR|1|-
+SAU|74,40|INFANTRY|1|-
+SAU|75,40|ARTILLERY|1|-
+SAU|74,39|ARMOUR|1|-
+AFG|81,33|INFANTRY|1|-
+ROC|100,28|INFANTRY|1|-
+ROC|101,28|ARTILLERY|1|-
+ROC|100,27|ARMOUR|1|-
+ROC|103,36|INFANTRY|1|-
+ROC|98,41|INFANTRY|1|-
+ROC|99,36|INFANTRY|1|-
+ROC|94,36|INFANTRY|1|-
+JPN|112,32|INFANTRY|1|-
+JPN|112,31|ARTILLERY|1|-
+JPN|111,31|ARMOUR|1|-
+JPN|103,40|INFANTRY|1|-
+JPN|106,30|INFANTRY|1|-
+JPN|109,33|INFANTRY|1|-
+JPN|113,32|DESTROYER|1|-
+THA|92,46|INFANTRY|1|-
+THA|93,46|ARTILLERY|1|-
+USA|25,27|INFANTRY|1|-
+USA|26,26|ARTILLERY|1|-
+USA|25,26|ARMOUR|1|-
+USA|102,45|INFANTRY|1|-
+USA|24,29|INFANTRY|1|-
+USA|21,26|INFANTRY|1|-
+USA|17,37|INFANTRY|1|-
+USA|10,34|INFANTRY|1|-
+USA|8,29|INFANTRY|1|-
+USA|26,27|DESTROYER|1|-
AUS|116,68|INFANTRY|1|-
AUS|115,67|ARTILLERY|1|-
AUS|115,68|ARMOUR|1|-
AUS|114,69|INFANTRY|1|-
AUS|117,68|DESTROYER|1|-
-CAN|23,23|INFANTRY|1|-
-CAN|24,24|ARTILLERY|1|-
-CAN|24,23|DESTROYER|1|-
-MEX|16,41|INFANTRY|1|-
-MEX|17,41|ARTILLERY|1|-
-MEX|17,40|ARMOUR|1|-
-GTM|20,44|INFANTRY|1|-
-COL|25,49|INFANTRY|1|-
-COL|26,49|ARTILLERY|1|-
-VEN|28,46|INFANTRY|1|-
-ECU|24,52|INFANTRY|1|-
-PER|24,58|INFANTRY|1|-
-PER|25,58|ARTILLERY|1|-
-BOL|27,60|INFANTRY|1|-
+CAN|23,25|INFANTRY|1|-
+CAN|24,26|ARTILLERY|1|-
+CAN|24,25|DESTROYER|1|-
+MEX|16,43|INFANTRY|1|-
+MEX|17,43|ARTILLERY|1|-
+MEX|17,42|ARMOUR|1|-
+GTM|19,45|INFANTRY|1|-
+COL|25,51|INFANTRY|1|-
+COL|26,51|ARTILLERY|1|-
+VEN|28,48|INFANTRY|1|-
+ECU|23,53|INFANTRY|1|-
+PER|24,59|INFANTRY|1|-
+PER|25,59|ARTILLERY|1|-
+BOL|27,61|INFANTRY|1|-
CHL|27,68|INFANTRY|1|-
CHL|28,68|ARTILLERY|1|-
-ARG|30,68|INFANTRY|1|-
-ARG|30,67|ARTILLERY|1|-
+ARG|30,69|INFANTRY|1|-
+ARG|30,68|ARTILLERY|1|-
URY|31,68|INFANTRY|1|-
-PRY|31,64|INFANTRY|1|-
+PRY|30,65|INFANTRY|1|-
BRA|33,63|INFANTRY|1|-
BRA|34,62|ARTILLERY|1|-
BRA|33,62|ARMOUR|1|-
@@ -252,7 +251,7 @@ BRA|34,64|DESTROYER|1|-
NZL|119,70|INFANTRY|1|-
[playable]
-RUS,USA,GBR,JPN,ROC,FRA,DEU,AUS,CAN,ITA,POL,NZL
+RUS,GBR,USA,JPN,ROC,FRA,DEU,AUS,CAN,ITA,POL,NZL
[objectives]
# 沒有列出目標 = 征服模式的預設條件(拿下地圖上八成的省份)
diff --git a/app/src/main/assets/scenarios/conquest_1943.scn b/app/src/main/assets/scenarios/conquest_1943.scn
index dd7a636..a037ec1 100644
--- a/app/src/main/assets/scenarios/conquest_1943.scn
+++ b/app/src/main/assets/scenarios/conquest_1943.scn
@@ -13,45 +13,45 @@ startYear 1943
startMonth 3
[nations]
-RUS|nation_sun|#8C6E4C|41|AGGRESSIVE|3600|2,2,2,2,2,1|🇷🇺|ALLIES|1
-GBR|nation_gbr|#8C4C4C|0|BALANCED|3300|2,2,2,2,2,1|🇬🇧|ALLIES|1
-USA|nation_usa|#4C7BA8|171|BALANCED|3279|2,2,2,2,2,1|🇺🇸|ALLIES|1
-JPN|nation_jpn|#C45C5C|128|BALANCED|3180|2,2,2,2,2,1|🇯🇵|AXIS|1
-DEU|nation_deu|#6E7A86|4|AGGRESSIVE|2472|2,2,2,2,2,1|🇩🇪|AXIS|1
-ROC|nation_roc|#B4454C|132|BALANCED|1485|2,2,2,2,2,1|🇹🇼|ALLIES|1
-FRA|nation_fra|#4C5C9E|76|BALANCED|1425|2,2,2,2,2,1|🇫🇷|ALLIES|1
-BRA|nation_bra|#4F9A50|222|TURTLE|1260|1,1,1,1,1,1|🇧🇷||1
-AUS|nation_aus|#C4A05C|230|BALANCED|1189|1,1,1,1,1,1|🇦🇺|ALLIES|1
-CAN|nation_can|#6E93B5|189|TURTLE|979|1,1,1,1,1,1|🇨🇦|ALLIES|1
-SAU|nation_sau|#4C8C5C|78|TURTLE|902|1,1,1,1,1,1|🇸🇦||1
-TUR|nation_tur|#A84C4C|68|TURTLE|850|1,1,0,0,0,1|🇹🇷||1
+RUS|nation_sun|#8C6E4C|46|AGGRESSIVE|3600|2,2,2,2,2,1|🇷🇺|ALLIES|1
+GBR|nation_gbr|#8C4C4C|0|BALANCED|3355|2,2,2,2,2,1|🇬🇧|ALLIES|1
+USA|nation_usa|#4C7BA8|178|BALANCED|3279|2,2,2,2,2,1|🇺🇸|ALLIES|1
+JPN|nation_jpn|#C45C5C|134|BALANCED|3240|2,2,2,2,2,1|🇯🇵|AXIS|1
+DEU|nation_deu|#6E7A86|4|AGGRESSIVE|2530|2,2,2,2,2,1|🇩🇪|AXIS|1
+ROC|nation_roc|#B4454C|138|BALANCED|1485|2,2,2,2,2,1|🇹🇼|ALLIES|1
+FRA|nation_fra|#4C5C9E|81|BALANCED|1425|2,2,2,2,2,1|🇫🇷|ALLIES|1
+BRA|nation_bra|#4F9A50|229|TURTLE|1260|1,1,1,1,1,1|🇧🇷||1
+AUS|nation_aus|#C4A05C|237|BALANCED|1189|1,1,1,1,1,1|🇦🇺|ALLIES|1
+CAN|nation_can|#6E93B5|196|TURTLE|979|1,1,1,1,1,1|🇨🇦|ALLIES|1
+SAU|nation_sau|#4C8C5C|83|TURTLE|902|1,1,1,1,1,1|🇸🇦||1
+TUR|nation_tur|#A84C4C|73|TURTLE|850|1,1,0,0,0,1|🇹🇷||1
ITA|nation_ita|#5C9E6E|13|OPPORTUNIST|804|1,1,0,0,0,1|🇮🇹|AXIS|1
-MEX|nation_mex|#3F8F6B|198|TURTLE|720|1,1,0,0,0,1|🇲🇽||1
-ARG|nation_arg|#6FA8C4|217|TURTLE|690|1,1,0,0,0,1|🇦🇷||1
+MEX|nation_mex|#3F8F6B|205|TURTLE|720|1,1,0,0,0,1|🇲🇽||1
+ARG|nation_arg|#6FA8C4|224|TURTLE|690|1,1,0,0,0,1|🇦🇷||1
ESP|nation_esp|#B08A3C|9|TURTLE|644|1,1,0,0,0,1|🇪🇸||1
-THA|nation_tha|#5C86A8|155|BALANCED|528|1,1,0,0,0,1|🇹🇭|AXIS|1
-CHL|nation_chl|#A8544C|214|TURTLE|482|0,0,0,0,0,0|🇨🇱||1
-COL|nation_col|#C29A3C|206|TURTLE|462|0,0,0,0,0,0|🇨🇴||1
-SWE|nation_swe|#4C6E9E|30|TURTLE|441|0,0,0,0,0,0|🇸🇪||1
-NZL|nation_nzl|#5C9E93|238|TURTLE|418|0,0,0,0,0,0|🇳🇿|ALLIES|1
-PER|nation_per|#B06A4C|211|TURTLE|418|0,0,0,0,0,0|🇵🇪||1
-VEN|nation_ven|#B4703C|208|TURTLE|399|0,0,0,0,0,0|🇻🇪||1
+THA|nation_tha|#5C86A8|162|BALANCED|528|1,1,0,0,0,1|🇹🇭|AXIS|1
+SWE|nation_swe|#4C6E9E|30|TURTLE|504|1,1,0,0,0,1|🇸🇪||1
+CHL|nation_chl|#A8544C|221|TURTLE|482|0,0,0,0,0,0|🇨🇱||1
+COL|nation_col|#C29A3C|213|TURTLE|462|0,0,0,0,0,0|🇨🇴||1
+NZL|nation_nzl|#5C9E93|245|TURTLE|418|0,0,0,0,0,0|🇳🇿|ALLIES|1
+PER|nation_per|#B06A4C|218|TURTLE|418|0,0,0,0,0,0|🇵🇪||1
+VEN|nation_ven|#B4703C|215|TURTLE|399|0,0,0,0,0,0|🇻🇪||1
CHE|nation_che|#B45C5C|16|TURTLE|378|0,0,0,0,0,0|🇨🇭||1
-ETH|nation_eth|#6E9E4C|101|BALANCED|357|0,0,0,0,0,0|🇪🇹|ALLIES|1
-BEL|nation_bel|#9E8C4C|105|TURTLE|352|0,0,0,0,0,0|🇧🇪||1
-DNK|nation_dnk|#A85C6E|35|TURTLE|352|0,0,0,0,0,0|🇩🇰||1
+ETH|nation_eth|#6E9E4C|106|BALANCED|357|0,0,0,0,0,0|🇪🇹|ALLIES|1
+BEL|nation_bel|#9E8C4C|110|TURTLE|352|0,0,0,0,0,0|🇧🇪||1
+DNK|nation_dnk|#A85C6E|40|TURTLE|352|0,0,0,0,0,0|🇩🇰||1
+FIN|nation_fin|#7A9EB4|37|TURTLE|352|0,0,0,0,0,0|🇫🇮|AXIS|1
ROU|nation_rou|#8C7A3C|26|TURTLE|352|0,0,0,0,0,0|🇷🇴|AXIS|1
PRT|nation_prt|#4C8C7A|12|TURTLE|345|0,0,0,0,0,0|🇵🇹||1
-FIN|nation_fin|#7A9EB4|33|TURTLE|336|0,0,0,0,0,0|🇫🇮|AXIS|1
HUN|nation_hun|#9E7A4C|25|OPPORTUNIST|315|0,0,0,0,0,0|🇭🇺|AXIS|1
IRL|nation_irl|#4C8C5C|3|TURTLE|273|0,0,0,0,0,0|🇮🇪||1
-ECU|nation_ecu|#C7A24E|209|TURTLE|264|0,0,0,0,0,0|🇪🇨||1
+ECU|nation_ecu|#C7A24E|216|TURTLE|264|0,0,0,0,0,0|🇪🇨||1
BGR|nation_bgr|#6E8C5C|28|TURTLE|252|0,0,0,0,0,0|🇧🇬|AXIS|1
-BOL|nation_bol|#8C9A4C|213|TURTLE|252|0,0,0,0,0,0|🇧🇴||1
-AFG|nation_afg|#8C7A5C|83|TURTLE|231|0,0,0,0,0,0|🇦🇫||1
-GTM|nation_gtm|#57A07E|202|TURTLE|231|0,0,0,0,0,0|🇬🇹||1
-URY|nation_ury|#6E9BB0|220|TURTLE|231|0,0,0,0,0,0|🇺🇾||1
-PRY|nation_pry|#7F8F5C|221|TURTLE|210|0,0,0,0,0,0|🇵🇾||1
+BOL|nation_bol|#8C9A4C|220|TURTLE|252|0,0,0,0,0,0|🇧🇴||1
+AFG|nation_afg|#8C7A5C|88|TURTLE|231|0,0,0,0,0,0|🇦🇫||1
+GTM|nation_gtm|#57A07E|209|TURTLE|231|0,0,0,0,0,0|🇬🇹||1
+URY|nation_ury|#6E9BB0|227|TURTLE|231|0,0,0,0,0,0|🇺🇾||1
+PRY|nation_pry|#7F8F5C|228|TURTLE|210|0,0,0,0,0,0|🇵🇾||1
[relations]
DEU GBR WAR
@@ -128,155 +128,155 @@ THA NZL WAR
THA ETH WAR
[owners]
-RUS: 41-67,73
-GBR: 0-2,71-72,74-75,77,80-82,84-87,96-98,100,102-104,108-113,116-127
-USA: 171-188,203-205
-JPN: 128-131,135-136,141-154,157-169
-DEU: 4-8,17-24,27,29,31-32,34,36-37,39-40,88
-ROC: 132-134,137-140
-FRA: 76,89-95,99,115
-BRA: 222-229
-AUS: 170,230-237
-CAN: 189-196
-SAU: 78-79
-TUR: 68-70
+RUS: 46-72,78
+GBR: 0-2,76-77,79-80,82,85-87,89-92,101-103,105,107-109,113-118,121-133
+USA: 178-195,210-212
+JPN: 134-137,141-142,147-161,164-176
+DEU: 4-8,17-24,27,29,34-36,39,41-42,44-45,93
+ROC: 138-140,143-146
+FRA: 81,94-100,104,120
+BRA: 229-236
+AUS: 177,237-244
+CAN: 196-203
+SAU: 83-84
+TUR: 73-75
ITA: 13-15
-MEX: 198-201
-ARG: 217-219
+MEX: 205-208
+ARG: 224-226
ESP: 9-11
-THA: 155-156
-CHL: 214-216
-COL: 206-207
-SWE: 30
-NZL: 238-239
-PER: 211-212
-VEN: 208
+THA: 162-163
+SWE: 30-33
+CHL: 221-223
+COL: 213-214
+NZL: 245-246
+PER: 218-219
+VEN: 215
CHE: 16
-ETH: 101
-BEL: 105-106
-DNK: 35,197
-ROU: 26,38
-PRT: 12,107,114
-FIN: 33
+ETH: 106
+BEL: 110-111
+DNK: 40,204
+FIN: 37-38
+ROU: 26,43
+PRT: 12,112,119
HUN: 25
IRL: 3
-ECU: 209-210
+ECU: 216-217
BGR: 28
-BOL: 213
-AFG: 83
-GTM: 202
-URY: 220
-PRY: 221
+BOL: 220
+AFG: 88
+GTM: 209
+URY: 227
+PRY: 228
[units]
-GBR|47,15|INFANTRY|1|-
-GBR|46,15|ARTILLERY|1|-
-GBR|45,15|ARMOUR|1|-
-GBR|76,30|INFANTRY|1|-
-GBR|74,32|INFANTRY|1|-
-GBR|65,35|INFANTRY|1|-
-GBR|49,49|INFANTRY|1|-
-GBR|64,64|INFANTRY|1|-
-GBR|84,36|INFANTRY|1|-
-GBR|82,41|INFANTRY|1|-
-GBR|87,39|INFANTRY|1|-
-GBR|81,38|INFANTRY|1|-
-GBR|48,15|DESTROYER|1|-
-IRL|43,13|INFANTRY|1|-
-DEU|48,17|INFANTRY|1|-
-DEU|49,17|ARTILLERY|1|-
-DEU|49,16|ARMOUR|1|-
-DEU|55,14|INFANTRY|1|-
-DEU|54,18|INFANTRY|1|-
-DEU|57,18|INFANTRY|1|-
-DEU|60,14|INFANTRY|1|-
-DEU|65,16|INFANTRY|1|-
-DEU|48,16|DESTROYER|1|-
-ESP|45,26|INFANTRY|1|-
-ESP|46,26|ARTILLERY|1|-
-PRT|41,27|INFANTRY|1|-
-ITA|55,24|INFANTRY|1|-
-ITA|56,24|ARTILLERY|1|-
-ITA|55,23|ARMOUR|1|-
-ITA|52,21|INFANTRY|1|-
-CHE|52,19|INFANTRY|1|-
-HUN|58,19|INFANTRY|1|-
-ROU|63,22|INFANTRY|1|-
-BGR|61,23|INFANTRY|1|-
-SWE|58,7|INFANTRY|1|-
-SWE|59,6|ARTILLERY|1|-
-FIN|62,7|INFANTRY|1|-
-DNK|38,5|INFANTRY|1|-
-RUS|69,11|INFANTRY|1|-
-RUS|70,11|ARTILLERY|1|-
-RUS|70,10|ARMOUR|1|-
-RUS|65,7|INFANTRY|1|-
-TUR|64,25|INFANTRY|1|-
-TUR|65,25|ARTILLERY|1|-
-TUR|65,26|ARMOUR|1|-
-FRA|69,32|INFANTRY|1|-
-FRA|70,32|ARTILLERY|1|-
-FRA|69,31|ARMOUR|1|-
-SAU|74,39|INFANTRY|1|-
-SAU|75,39|ARTILLERY|1|-
-SAU|75,38|ARMOUR|1|-
-AFG|81,31|INFANTRY|1|-
-ETH|70,47|INFANTRY|1|-
-BEL|56,54|INFANTRY|1|-
-JPN|100,26|INFANTRY|1|-
-JPN|101,26|ARTILLERY|1|-
-JPN|100,25|ARMOUR|1|-
-JPN|103,34|INFANTRY|1|-
-JPN|98,39|INFANTRY|1|-
-JPN|98,35|INFANTRY|1|-
+GBR|47,17|INFANTRY|1|-
+GBR|46,17|ARTILLERY|1|-
+GBR|45,17|ARMOUR|1|-
+GBR|76,32|INFANTRY|1|-
+GBR|74,34|INFANTRY|1|-
+GBR|65,37|INFANTRY|1|-
+GBR|49,50|INFANTRY|1|-
+GBR|63,65|INFANTRY|1|-
+GBR|84,38|INFANTRY|1|-
+GBR|82,43|INFANTRY|1|-
+GBR|87,41|INFANTRY|1|-
+GBR|81,40|INFANTRY|1|-
+GBR|48,17|DESTROYER|1|-
+IRL|43,15|INFANTRY|1|-
+DEU|49,20|INFANTRY|1|-
+DEU|50,20|ARTILLERY|1|-
+DEU|49,19|ARMOUR|1|-
+DEU|55,16|INFANTRY|1|-
+DEU|54,20|INFANTRY|1|-
+DEU|57,20|INFANTRY|1|-
+DEU|60,16|INFANTRY|1|-
+DEU|65,18|INFANTRY|1|-
+ESP|45,27|INFANTRY|1|-
+ESP|46,27|ARTILLERY|1|-
+PRT|41,29|INFANTRY|1|-
+ITA|55,26|INFANTRY|1|-
+ITA|56,26|ARTILLERY|1|-
+ITA|55,25|ARMOUR|1|-
+ITA|52,23|INFANTRY|1|-
+CHE|52,21|INFANTRY|1|-
+HUN|58,21|INFANTRY|1|-
+ROU|63,24|INFANTRY|1|-
+BGR|61,25|INFANTRY|1|-
+SWE|58,10|INFANTRY|1|-
+SWE|58,9|ARTILLERY|1|-
+FIN|62,9|INFANTRY|1|-
+DNK|39,6|INFANTRY|1|-
+RUS|69,13|INFANTRY|1|-
+RUS|70,13|ARTILLERY|1|-
+RUS|70,12|ARMOUR|1|-
+RUS|65,9|INFANTRY|1|-
+TUR|64,27|INFANTRY|1|-
+TUR|65,27|ARTILLERY|1|-
+TUR|65,28|ARMOUR|1|-
+FRA|69,34|INFANTRY|1|-
+FRA|70,34|ARTILLERY|1|-
+FRA|69,33|ARMOUR|1|-
+FRA|68,34|DESTROYER|1|-
+SAU|74,40|INFANTRY|1|-
+SAU|75,40|ARTILLERY|1|-
+SAU|74,39|ARMOUR|1|-
+AFG|81,33|INFANTRY|1|-
+ETH|70,48|INFANTRY|1|-
+BEL|56,55|INFANTRY|1|-
+JPN|100,28|INFANTRY|1|-
+JPN|101,28|ARTILLERY|1|-
+JPN|100,27|ARMOUR|1|-
+JPN|103,36|INFANTRY|1|-
+JPN|98,41|INFANTRY|1|-
+JPN|99,36|INFANTRY|1|-
JPN|99,40|INFANTRY|1|-
-JPN|103,38|INFANTRY|1|-
-JPN|106,28|INFANTRY|1|-
-JPN|112,30|INFANTRY|1|-
-JPN|109,31|INFANTRY|1|-
-JPN|95,46|INFANTRY|1|-
-JPN|93,51|INFANTRY|1|-
-JPN|95,55|INFANTRY|1|-
-JPN|102,44|INFANTRY|1|-
-ROC|93,35|INFANTRY|1|-
-ROC|94,35|ARTILLERY|1|-
-ROC|94,34|ARMOUR|1|-
-THA|92,44|INFANTRY|1|-
-THA|93,44|ARTILLERY|1|-
+JPN|103,40|INFANTRY|1|-
+JPN|106,30|INFANTRY|1|-
+JPN|112,32|INFANTRY|1|-
+JPN|109,33|INFANTRY|1|-
+JPN|95,47|INFANTRY|1|-
+JPN|94,52|INFANTRY|1|-
+JPN|95,56|INFANTRY|1|-
+JPN|102,45|INFANTRY|1|-
+ROC|94,36|INFANTRY|1|-
+ROC|95,36|ARTILLERY|1|-
+ROC|94,35|ARMOUR|1|-
+THA|92,46|INFANTRY|1|-
+THA|93,46|ARTILLERY|1|-
AUS|116,68|INFANTRY|1|-
AUS|115,67|ARTILLERY|1|-
AUS|115,68|ARMOUR|1|-
AUS|114,69|INFANTRY|1|-
AUS|117,68|DESTROYER|1|-
-USA|25,25|INFANTRY|1|-
-USA|26,24|ARTILLERY|1|-
-USA|25,24|ARMOUR|1|-
-USA|24,27|INFANTRY|1|-
-USA|21,24|INFANTRY|1|-
-USA|18,36|INFANTRY|1|-
-USA|10,32|INFANTRY|1|-
-USA|9,28|INFANTRY|1|-
-USA|26,25|DESTROYER|1|-
-CAN|23,23|INFANTRY|1|-
-CAN|24,24|ARTILLERY|1|-
-CAN|24,23|DESTROYER|1|-
-MEX|16,41|INFANTRY|1|-
-MEX|17,41|ARTILLERY|1|-
-MEX|17,40|ARMOUR|1|-
-GTM|20,44|INFANTRY|1|-
-COL|25,49|INFANTRY|1|-
-COL|26,49|ARTILLERY|1|-
-VEN|28,46|INFANTRY|1|-
-ECU|24,52|INFANTRY|1|-
-PER|24,58|INFANTRY|1|-
-PER|25,58|ARTILLERY|1|-
-BOL|27,60|INFANTRY|1|-
+USA|25,27|INFANTRY|1|-
+USA|26,26|ARTILLERY|1|-
+USA|25,26|ARMOUR|1|-
+USA|24,29|INFANTRY|1|-
+USA|21,26|INFANTRY|1|-
+USA|17,37|INFANTRY|1|-
+USA|10,34|INFANTRY|1|-
+USA|8,29|INFANTRY|1|-
+USA|26,27|DESTROYER|1|-
+CAN|23,25|INFANTRY|1|-
+CAN|24,26|ARTILLERY|1|-
+CAN|24,25|DESTROYER|1|-
+MEX|16,43|INFANTRY|1|-
+MEX|17,43|ARTILLERY|1|-
+MEX|17,42|ARMOUR|1|-
+GTM|19,45|INFANTRY|1|-
+COL|25,51|INFANTRY|1|-
+COL|26,51|ARTILLERY|1|-
+VEN|28,48|INFANTRY|1|-
+ECU|23,53|INFANTRY|1|-
+PER|24,59|INFANTRY|1|-
+PER|25,59|ARTILLERY|1|-
+BOL|27,61|INFANTRY|1|-
CHL|27,68|INFANTRY|1|-
CHL|28,68|ARTILLERY|1|-
-ARG|30,68|INFANTRY|1|-
-ARG|30,67|ARTILLERY|1|-
+ARG|30,69|INFANTRY|1|-
+ARG|30,68|ARTILLERY|1|-
URY|31,68|INFANTRY|1|-
-PRY|31,64|INFANTRY|1|-
+PRY|30,65|INFANTRY|1|-
BRA|33,63|INFANTRY|1|-
BRA|34,62|ARTILLERY|1|-
BRA|33,62|ARMOUR|1|-
@@ -285,7 +285,7 @@ BRA|34,64|DESTROYER|1|-
NZL|119,70|INFANTRY|1|-
[playable]
-RUS,GBR,USA,JPN,DEU,ROC,FRA,AUS,CAN,ITA,THA,NZL,ETH,ROU,FIN,HUN,BGR
+RUS,GBR,USA,JPN,DEU,ROC,FRA,AUS,CAN,ITA,THA,NZL,ETH,FIN,ROU,HUN,BGR
[objectives]
# 沒有列出目標 = 征服模式的預設條件(拿下地圖上八成的省份)
diff --git a/app/src/main/assets/scenarios/conquest_1950.scn b/app/src/main/assets/scenarios/conquest_1950.scn
index 3a048da..1bfcc94 100644
--- a/app/src/main/assets/scenarios/conquest_1950.scn
+++ b/app/src/main/assets/scenarios/conquest_1950.scn
@@ -13,74 +13,74 @@ startYear 1950
startMonth 1
[nations]
-RUS|nation_sun|#8C6E4C|41|AGGRESSIVE|3824|2,2,2,2,2,1|🇷🇺|EAST|1
-USA|nation_usa|#4C7BA8|171|BALANCED|3040|2,2,2,2,2,1|🇺🇸|WEST|1
-CHN|nation_chn|#B4454C|128|BALANCED|2890|2,2,2,2,2,1|🇨🇳|EAST|1
+RUS|nation_sun|#8C6E4C|46|AGGRESSIVE|3824|2,2,2,2,2,1|🇷🇺|EAST|1
+USA|nation_usa|#4C7BA8|178|BALANCED|3040|2,2,2,2,2,1|🇺🇸|WEST|1
+CHN|nation_chn|#B4454C|134|BALANCED|2890|2,2,2,2,2,1|🇨🇳|EAST|1
GBR|nation_gbr|#8C4C4C|0|BALANCED|2200|2,2,2,2,2,1|🇬🇧|WEST|1
FRA|nation_fra|#4C5C9E|4|BALANCED|1710|2,2,2,2,2,1|🇫🇷|WEST|1
-IND|nation_ind|#C4864C|116|TURTLE|1552|2,2,2,2,2,1|🇮🇳||1
-JPN|nation_jpn|#C45C5C|148|BALANCED|1500|2,2,2,2,2,1|🇯🇵|WEST|1
+IND|nation_ind|#C4864C|121|TURTLE|1610|2,2,2,2,2,1|🇮🇳||1
+JPN|nation_jpn|#C45C5C|155|BALANCED|1500|2,2,2,2,2,1|🇯🇵|WEST|1
DEU|nation_frg|#6E7A86|19|AGGRESSIVE|1322|1,1,1,1,1,1|🇩🇪|WEST|1
-BRA|nation_bra|#4F9A50|222|TURTLE|1260|1,1,1,1,1,1|🇧🇷||1
-AUS|nation_aus|#C4A05C|230|BALANCED|1189|1,1,1,1,1,1|🇦🇺|WEST|1
-CAN|nation_can|#6E93B5|189|TURTLE|979|1,1,1,1,1,1|🇨🇦|WEST|1
-SAU|nation_sau|#4C8C5C|78|TURTLE|902|1,1,1,1,1,1|🇸🇦||1
-IDN|nation_idn|#A85C4C|163|TURTLE|875|1,1,0,0,0,1|🇮🇩||1
-TUR|nation_tur|#A84C4C|68|AGGRESSIVE|850|1,1,0,0,0,1|🇹🇷|WEST|1
+BRA|nation_bra|#4F9A50|229|TURTLE|1260|1,1,1,1,1,1|🇧🇷||1
+AUS|nation_aus|#C4A05C|237|BALANCED|1189|1,1,1,1,1,1|🇦🇺|WEST|1
+CAN|nation_can|#6E93B5|196|TURTLE|979|1,1,1,1,1,1|🇨🇦|WEST|1
+SAU|nation_sau|#4C8C5C|83|TURTLE|902|1,1,1,1,1,1|🇸🇦||1
+IDN|nation_idn|#A85C4C|170|TURTLE|875|1,1,0,0,0,1|🇮🇩||1
+TUR|nation_tur|#A84C4C|73|AGGRESSIVE|850|1,1,0,0,0,1|🇹🇷|WEST|1
ITA|nation_ita|#5C9E6E|13|OPPORTUNIST|840|1,1,0,0,0,1|🇮🇹|WEST|1
-IRN|nation_irn|#4C8C6E|71|TURTLE|804|1,1,0,0,0,1|🇮🇷||1
-EGY|nation_egy|#C4A84C|84|TURTLE|736|1,1,0,0,0,1|🇪🇬||1
-ZAF|nation_zaf|#4C7A5C|112|TURTLE|736|1,1,0,0,0,1|🇿🇦||1
+IRN|nation_irn|#4C8C6E|76|TURTLE|804|1,1,0,0,0,1|🇮🇷||1
+EGY|nation_egy|#C4A84C|89|TURTLE|736|1,1,0,0,0,1|🇪🇬||1
+ZAF|nation_zaf|#4C7A5C|117|TURTLE|736|1,1,0,0,0,1|🇿🇦||1
DDR|nation_ddr|#8C5A5A|17|BALANCED|735|1,1,0,0,0,1||EAST|1
-MEX|nation_mex|#3F8F6B|198|TURTLE|720|1,1,0,0,0,1|🇲🇽||1
-ARG|nation_arg|#6FA8C4|217|TURTLE|690|1,1,0,0,0,1|🇦🇷||1
-KOR|nation_kor|#5C9EB4|145|TURTLE|682|1,1,0,0,0,1|🇰🇷|WEST|1
+MEX|nation_mex|#3F8F6B|205|TURTLE|720|1,1,0,0,0,1|🇲🇽||1
+ARG|nation_arg|#6FA8C4|224|TURTLE|690|1,1,0,0,0,1|🇦🇷||1
+KOR|nation_kor|#5C9EB4|151|TURTLE|682|1,1,0,0,0,1|🇰🇷|WEST|1
ESP|nation_esp|#B08A3C|9|TURTLE|644|1,1,0,0,0,1|🇪🇸||1
-PAK|nation_pak|#4C8C5C|123|TURTLE|644|1,1,0,0,0,1|🇵🇰||1
+PAK|nation_pak|#4C8C5C|129|TURTLE|644|1,1,0,0,0,1|🇵🇰||1
POL|nation_pol|#B4535C|23|BALANCED|572|1,1,0,0,0,1|🇵🇱|EAST|1
-TWN|nation_roc|#4C86B4|143|TURTLE|572|1,1,0,0,0,1|🇹🇼|WEST|1
-THA|nation_tha|#5C86A8|155|TURTLE|528|1,1,0,0,0,1|🇹🇭||1
-CHL|nation_chl|#A8544C|214|TURTLE|482|0,0,0,0,0,0|🇨🇱||1
-COL|nation_col|#C29A3C|206|TURTLE|462|0,0,0,0,0,0|🇨🇴||1
-IRQ|nation_irq|#8C8C4C|74|TURTLE|462|0,0,0,0,0,0|🇮🇶||1
-PHL|nation_phl|#4C86A8|168|TURTLE|462|0,0,0,0,0,0|🇵🇭|WEST|1
-ISR|nation_isr|#5C86B4|77|TURTLE|441|0,0,0,0,0,0|🇮🇱||1
-SWE|nation_swe|#4C6E9E|30|TURTLE|441|0,0,0,0,0,0|🇸🇪||1
-NOR|nation_nor|#5C7EA8|31|TURTLE|418|0,0,0,0,0,0|🇳🇴|WEST|1
-NZL|nation_nzl|#5C9E93|238|TURTLE|418|0,0,0,0,0,0|🇳🇿|WEST|1
-PER|nation_per|#B06A4C|211|TURTLE|418|0,0,0,0,0,0|🇵🇪||1
+TWN|nation_roc|#4C86B4|149|TURTLE|572|1,1,0,0,0,1|🇹🇼|WEST|1
+THA|nation_tha|#5C86A8|162|TURTLE|528|1,1,0,0,0,1|🇹🇭||1
+SWE|nation_swe|#4C6E9E|30|TURTLE|504|1,1,0,0,0,1|🇸🇪||1
+CHL|nation_chl|#A8544C|221|TURTLE|482|0,0,0,0,0,0|🇨🇱||1
+COL|nation_col|#C29A3C|213|TURTLE|462|0,0,0,0,0,0|🇨🇴||1
+IRQ|nation_irq|#8C8C4C|79|TURTLE|462|0,0,0,0,0,0|🇮🇶||1
+PHL|nation_phl|#4C86A8|175|TURTLE|462|0,0,0,0,0,0|🇵🇭|WEST|1
+ISR|nation_isr|#5C86B4|82|TURTLE|441|0,0,0,0,0,0|🇮🇱||1
+NOR|nation_nor|#5C7EA8|34|TURTLE|418|0,0,0,0,0,0|🇳🇴|WEST|1
+NZL|nation_nzl|#5C9E93|245|TURTLE|418|0,0,0,0,0,0|🇳🇿|WEST|1
+PER|nation_per|#B06A4C|218|TURTLE|418|0,0,0,0,0,0|🇵🇪||1
NLD|nation_nld|#C4813C|8|TURTLE|399|0,0,0,0,0,0|🇳🇱|WEST|1
-VEN|nation_ven|#B4703C|208|TURTLE|399|0,0,0,0,0,0|🇻🇪||1
+VEN|nation_ven|#B4703C|215|TURTLE|399|0,0,0,0,0,0|🇻🇪||1
+PRK|nation_prk|#8C5C6E|153|AGGRESSIVE|396|0,0,0,0,0,0|🇰🇵|EAST|1
CHE|nation_che|#B45C5C|16|TURTLE|378|0,0,0,0,0,0|🇨🇭||1
-PRK|nation_prk|#8C5C6E|147|AGGRESSIVE|378|0,0,0,0,0,0|🇰🇵|EAST|1
-BEL|nation_bel|#9E8C4C|105|TURTLE|368|0,0,0,0,0,0|🇧🇪|WEST|1
+BEL|nation_bel|#9E8C4C|110|TURTLE|368|0,0,0,0,0,0|🇧🇪|WEST|1
+DNK|nation_dnk|#A85C6E|35|TURTLE|368|0,0,0,0,0,0|🇩🇰|WEST|1
AUT|nation_aut|#A0A6AC|21|TURTLE|357|0,0,0,0,0,0|🇦🇹||1
-ETH|nation_eth|#6E9E4C|101|TURTLE|357|0,0,0,0,0,0|🇪🇹||1
-DNK|nation_dnk|#A85C6E|32|TURTLE|352|0,0,0,0,0,0|🇩🇰|WEST|1
+ETH|nation_eth|#6E9E4C|106|TURTLE|357|0,0,0,0,0,0|🇪🇹||1
+FIN|nation_fin|#7A9EB4|37|TURTLE|352|0,0,0,0,0,0|🇫🇮||1
PRT|nation_prt|#4C8C7A|12|TURTLE|345|0,0,0,0,0,0|🇵🇹|WEST|1
-FIN|nation_fin|#7A9EB4|33|TURTLE|336|0,0,0,0,0,0|🇫🇮||1
ROU|nation_rou|#8C7A3C|26|TURTLE|336|0,0,0,0,0,0|🇷🇴|EAST|1
-MMR|nation_mmr|#8C9E4C|153|TURTLE|330|0,0,0,0,0,0|🇲🇲||1
+MMR|nation_mmr|#8C9E4C|160|TURTLE|330|0,0,0,0,0,0|🇲🇲||1
CZE|nation_cze|#8A96A0|22|TURTLE|315|0,0,0,0,0,0|🇨🇿|EAST|1
GRC|nation_grc|#4C7AA8|29|TURTLE|315|0,0,0,0,0,0|🇬🇷|WEST|1
HUN|nation_hun|#9E7A4C|25|OPPORTUNIST|315|0,0,0,0,0,0|🇭🇺|EAST|1
-CUB|nation_cub|#A85C4C|204|TURTLE|273|0,0,0,0,0,0|🇨🇺||1
+CUB|nation_cub|#A85C4C|211|TURTLE|273|0,0,0,0,0,0|🇨🇺||1
IRL|nation_irl|#4C8C5C|3|TURTLE|273|0,0,0,0,0,0|🇮🇪||1
SRB|nation_srb|#8C5C4C|27|TURTLE|273|0,0,0,0,0,0|🇷🇸||1
-SYR|nation_syr|#7A8C5C|76|TURTLE|273|0,0,0,0,0,0|🇸🇾||1
-ECU|nation_ecu|#C7A24E|209|TURTLE|264|0,0,0,0,0,0|🇪🇨||1
+SYR|nation_syr|#7A8C5C|81|TURTLE|273|0,0,0,0,0,0|🇸🇾||1
+ECU|nation_ecu|#C7A24E|216|TURTLE|264|0,0,0,0,0,0|🇪🇨||1
BGR|nation_bgr|#6E8C5C|28|TURTLE|252|0,0,0,0,0,0|🇧🇬|EAST|1
-BOL|nation_bol|#8C9A4C|213|TURTLE|252|0,0,0,0,0,0|🇧🇴||1
-MNG|nation_mng|#B4A05C|67|TURTLE|252|0,0,0,0,0,0|🇲🇳|EAST|1
-AFG|nation_afg|#8C7A5C|83|TURTLE|231|0,0,0,0,0,0|🇦🇫||1
-GTM|nation_gtm|#57A07E|202|TURTLE|231|0,0,0,0,0,0|🇬🇹||1
-LKA|nation_lka|#B4844C|126|TURTLE|231|0,0,0,0,0,0|🇱🇰||1
-PAN|nation_pan|#4E9E86|203|TURTLE|231|0,0,0,0,0,0|🇵🇦||1
-URY|nation_ury|#6E9BB0|220|TURTLE|231|0,0,0,0,0,0|🇺🇾||1
-DOM|nation_dom|#9E6B58|205|TURTLE|210|0,0,0,0,0,0|🇩🇴||1
-PRY|nation_pry|#7F8F5C|221|TURTLE|210|0,0,0,0,0,0|🇵🇾||1
-NPL|nation_npl|#A85C5C|127|TURTLE|189|0,0,0,0,0,0|🇳🇵||1
-ISL|nation_isl|#93A8B4|35|TURTLE|157|0,0,0,0,0,0|🇮🇸|WEST|1
+BOL|nation_bol|#8C9A4C|220|TURTLE|252|0,0,0,0,0,0|🇧🇴||1
+MNG|nation_mng|#B4A05C|72|TURTLE|252|0,0,0,0,0,0|🇲🇳|EAST|1
+AFG|nation_afg|#8C7A5C|88|TURTLE|231|0,0,0,0,0,0|🇦🇫||1
+GTM|nation_gtm|#57A07E|209|TURTLE|231|0,0,0,0,0,0|🇬🇹||1
+LKA|nation_lka|#B4844C|132|TURTLE|231|0,0,0,0,0,0|🇱🇰||1
+PAN|nation_pan|#4E9E86|210|TURTLE|231|0,0,0,0,0,0|🇵🇦||1
+URY|nation_ury|#6E9BB0|227|TURTLE|231|0,0,0,0,0,0|🇺🇾||1
+DOM|nation_dom|#9E6B58|212|TURTLE|210|0,0,0,0,0,0|🇩🇴||1
+PRY|nation_pry|#7F8F5C|228|TURTLE|210|0,0,0,0,0,0|🇵🇾||1
+NPL|nation_npl|#A85C5C|133|TURTLE|189|0,0,0,0,0,0|🇳🇵||1
+ISL|nation_isl|#93A8B4|40|TURTLE|157|0,0,0,0,0,0|🇮🇸|WEST|1
[relations]
USA RUS WAR
@@ -285,220 +285,217 @@ PHL PRK WAR
PHL MNG WAR
[owners]
-RUS: 34,37-66
-USA: 171-188
-CHN: 128-141
-GBR: 0-2,80-82,87,96-98,100,103-104,108-110,142,160-162
-FRA: 4-6,88-95,99,115,157-159
-IND: 116-122
-JPN: 148-152
+RUS: 39,42-71
+USA: 178-195
+CHN: 134-147
+GBR: 0-2,85-87,92,101-103,105,108-109,113-115,148,167-169
+FRA: 4-6,93-100,104,120,164-166
+IND: 121-128
+JPN: 155-159
DEU: 18-20
-BRA: 222-229
-AUS: 170,230-237
-CAN: 189-196
-SAU: 78-79
-IDN: 163-167
-TUR: 68-70
-ITA: 13-15,102
-IRN: 71-73
-EGY: 84-86
-ZAF: 111-113
+BRA: 229-236
+AUS: 177,237-244
+CAN: 196-203
+SAU: 83-84
+IDN: 170-174
+TUR: 73-75
+ITA: 13-15,107
+IRN: 76-78
+EGY: 89-91
+ZAF: 116-118
DDR: 17
-MEX: 198-201
-ARG: 217-219
-KOR: 145-146
+MEX: 205-208
+ARG: 224-226
+KOR: 151-152
ESP: 9-11
-PAK: 123-125
+PAK: 129-131
POL: 23-24
-TWN: 143-144
-THA: 155-156
-CHL: 214-216
-COL: 206-207
-IRQ: 74-75
-PHL: 168-169
-ISR: 77
-SWE: 30
-NOR: 31,36
-NZL: 238-239
-PER: 211-212
+TWN: 149-150
+THA: 162-163
+SWE: 30-33
+CHL: 221-223
+COL: 213-214
+IRQ: 79-80
+PHL: 175-176
+ISR: 82
+NOR: 34,41
+NZL: 245-246
+PER: 218-219
NLD: 8
-VEN: 208
+VEN: 215
+PRK: 153-154
CHE: 16
-PRK: 147
-BEL: 7,105-106
+BEL: 7,110-111
+DNK: 35-36,204
AUT: 21
-ETH: 101
-DNK: 32,197
-PRT: 12,107,114
-FIN: 33
+ETH: 106
+FIN: 37-38
+PRT: 12,112,119
ROU: 26
-MMR: 153-154
+MMR: 160-161
CZE: 22
GRC: 29
HUN: 25
-CUB: 204
+CUB: 211
IRL: 3
SRB: 27
-SYR: 76
-ECU: 209-210
+SYR: 81
+ECU: 216-217
BGR: 28
-BOL: 213
-MNG: 67
-AFG: 83
-GTM: 202
-LKA: 126
-PAN: 203
-URY: 220
-DOM: 205
-PRY: 221
-NPL: 127
-ISL: 35
+BOL: 220
+MNG: 72
+AFG: 88
+GTM: 209
+LKA: 132
+PAN: 210
+URY: 227
+DOM: 212
+PRY: 228
+NPL: 133
+ISL: 40
[units]
-GBR|47,15|INFANTRY|1|-
-GBR|46,15|ARTILLERY|1|-
-GBR|45,15|ARMOUR|1|-
-GBR|49,49|INFANTRY|1|-
+GBR|47,17|INFANTRY|1|-
+GBR|46,17|ARTILLERY|1|-
+GBR|45,17|ARMOUR|1|-
+GBR|49,50|INFANTRY|1|-
GBR|99,40|INFANTRY|1|-
-GBR|93,51|INFANTRY|1|-
-GBR|48,15|DESTROYER|1|-
-IRL|43,13|INFANTRY|1|-
-FRA|48,17|INFANTRY|1|-
-FRA|49,17|ARTILLERY|1|-
-FRA|49,16|ARMOUR|1|-
-FRA|95,46|INFANTRY|1|-
-FRA|48,16|DESTROYER|1|-
-BEL|56,54|INFANTRY|1|-
-NLD|50,14|INFANTRY|1|-
-ESP|45,26|INFANTRY|1|-
-ESP|46,26|ARTILLERY|1|-
-PRT|41,27|INFANTRY|1|-
-ITA|55,24|INFANTRY|1|-
-ITA|56,24|ARTILLERY|1|-
-ITA|55,23|ARMOUR|1|-
-ITA|52,21|INFANTRY|1|-
-CHE|52,19|INFANTRY|1|-
-DDR|55,14|INFANTRY|1|-
-DDR|56,14|ARTILLERY|1|-
-DDR|55,13|ARMOUR|1|-
-DEU|54,18|INFANTRY|1|-
-DEU|55,18|ARTILLERY|1|-
-DEU|54,17|ARMOUR|1|-
-AUT|57,18|INFANTRY|1|-
-CZE|56,16|INFANTRY|1|-
-POL|60,14|INFANTRY|1|-
-POL|61,14|ARTILLERY|1|-
-HUN|58,19|INFANTRY|1|-
-ROU|63,22|INFANTRY|1|-
-SRB|59,21|INFANTRY|1|-
-BGR|61,23|INFANTRY|1|-
-GRC|61,28|INFANTRY|1|-
-SWE|58,7|INFANTRY|1|-
-SWE|59,6|ARTILLERY|1|-
-NOR|53,7|INFANTRY|1|-
-NOR|54,7|ARTILLERY|1|-
-DNK|54,11|INFANTRY|1|-
-FIN|62,7|INFANTRY|1|-
-RUS|69,11|INFANTRY|1|-
-RUS|70,11|ARTILLERY|1|-
-RUS|70,10|ARMOUR|1|-
-RUS|65,16|INFANTRY|1|-
-RUS|65,7|INFANTRY|1|-
-ISL|38,5|INFANTRY|1|-
-MNG|95,18|INFANTRY|1|-
-TUR|64,25|INFANTRY|1|-
-TUR|65,25|ARTILLERY|1|-
-TUR|65,26|ARMOUR|1|-
-IRN|76,30|INFANTRY|1|-
-IRN|77,30|ARTILLERY|1|-
-IRN|76,29|ARMOUR|1|-
-IRQ|74,32|INFANTRY|1|-
-IRQ|74,31|ARTILLERY|1|-
-SYR|69,32|INFANTRY|1|-
-ISR|68,34|INFANTRY|1|-
-ISR|69,34|ARTILLERY|1|-
-SAU|74,39|INFANTRY|1|-
-SAU|75,39|ARTILLERY|1|-
-SAU|75,38|ARMOUR|1|-
-AFG|81,31|INFANTRY|1|-
-EGY|65,35|INFANTRY|1|-
-EGY|66,35|ARTILLERY|1|-
-EGY|66,34|ARMOUR|1|-
-ETH|70,47|INFANTRY|1|-
-ZAF|64,64|INFANTRY|1|-
-ZAF|65,64|ARTILLERY|1|-
-ZAF|64,63|ARMOUR|1|-
-IND|84,36|INFANTRY|1|-
-IND|85,36|ARTILLERY|1|-
-IND|84,35|ARMOUR|1|-
-IND|82,41|INFANTRY|1|-
-IND|87,39|INFANTRY|1|-
-PAK|81,38|INFANTRY|1|-
-PAK|82,38|ARTILLERY|1|-
-LKA|85,48|INFANTRY|1|-
-NPL|86,37|INFANTRY|1|-
-CHN|100,26|INFANTRY|1|-
-CHN|101,26|ARTILLERY|1|-
-CHN|100,25|ARMOUR|1|-
-CHN|103,34|INFANTRY|1|-
-CHN|98,39|INFANTRY|1|-
-CHN|98,35|INFANTRY|1|-
-CHN|93,35|INFANTRY|1|-
-TWN|103,38|INFANTRY|1|-
-TWN|102,39|ARTILLERY|1|-
-KOR|106,28|INFANTRY|1|-
-KOR|106,27|ARTILLERY|1|-
-PRK|104,27|INFANTRY|1|-
-JPN|112,30|INFANTRY|1|-
-JPN|112,29|ARTILLERY|1|-
-JPN|111,29|ARMOUR|1|-
-JPN|109,31|INFANTRY|1|-
-JPN|113,30|DESTROYER|1|-
-MMR|90,43|INFANTRY|1|-
-THA|92,44|INFANTRY|1|-
-THA|93,44|ARTILLERY|1|-
-IDN|95,55|INFANTRY|1|-
-IDN|94,55|ARTILLERY|1|-
-IDN|94,54|ARMOUR|1|-
-PHL|102,44|INFANTRY|1|-
-PHL|103,44|ARTILLERY|1|-
+GBR|94,52|INFANTRY|1|-
+GBR|48,17|DESTROYER|1|-
+IRL|43,15|INFANTRY|1|-
+FRA|49,20|INFANTRY|1|-
+FRA|50,20|ARTILLERY|1|-
+FRA|49,19|ARMOUR|1|-
+FRA|95,47|INFANTRY|1|-
+BEL|56,55|INFANTRY|1|-
+NLD|50,16|INFANTRY|1|-
+ESP|45,27|INFANTRY|1|-
+ESP|46,27|ARTILLERY|1|-
+PRT|41,29|INFANTRY|1|-
+ITA|55,26|INFANTRY|1|-
+ITA|56,26|ARTILLERY|1|-
+ITA|55,25|ARMOUR|1|-
+ITA|52,23|INFANTRY|1|-
+CHE|52,21|INFANTRY|1|-
+DDR|55,16|INFANTRY|1|-
+DDR|56,16|ARTILLERY|1|-
+DDR|55,15|ARMOUR|1|-
+DEU|54,20|INFANTRY|1|-
+DEU|55,20|ARTILLERY|1|-
+DEU|54,19|ARMOUR|1|-
+AUT|57,20|INFANTRY|1|-
+CZE|56,18|INFANTRY|1|-
+POL|60,16|INFANTRY|1|-
+POL|61,16|ARTILLERY|1|-
+HUN|58,21|INFANTRY|1|-
+ROU|63,24|INFANTRY|1|-
+SRB|59,23|INFANTRY|1|-
+BGR|61,25|INFANTRY|1|-
+GRC|61,30|INFANTRY|1|-
+SWE|58,10|INFANTRY|1|-
+SWE|58,9|ARTILLERY|1|-
+NOR|53,9|INFANTRY|1|-
+NOR|54,9|ARTILLERY|1|-
+DNK|54,13|INFANTRY|1|-
+FIN|62,9|INFANTRY|1|-
+RUS|69,13|INFANTRY|1|-
+RUS|70,13|ARTILLERY|1|-
+RUS|70,12|ARMOUR|1|-
+RUS|65,18|INFANTRY|1|-
+RUS|65,9|INFANTRY|1|-
+ISL|39,6|INFANTRY|1|-
+MNG|95,20|INFANTRY|1|-
+TUR|64,27|INFANTRY|1|-
+TUR|65,27|ARTILLERY|1|-
+TUR|65,28|ARMOUR|1|-
+IRN|76,32|INFANTRY|1|-
+IRN|77,32|ARTILLERY|1|-
+IRN|76,31|ARMOUR|1|-
+IRQ|74,34|INFANTRY|1|-
+IRQ|74,33|ARTILLERY|1|-
+SYR|69,34|INFANTRY|1|-
+ISR|68,35|INFANTRY|1|-
+ISR|68,36|ARTILLERY|1|-
+SAU|74,40|INFANTRY|1|-
+SAU|75,40|ARTILLERY|1|-
+SAU|74,39|ARMOUR|1|-
+AFG|81,33|INFANTRY|1|-
+EGY|65,37|INFANTRY|1|-
+EGY|66,37|ARTILLERY|1|-
+EGY|64,37|ARMOUR|1|-
+ETH|70,48|INFANTRY|1|-
+ZAF|63,65|INFANTRY|1|-
+ZAF|64,65|ARTILLERY|1|-
+ZAF|64,64|ARMOUR|1|-
+IND|84,38|INFANTRY|1|-
+IND|85,38|ARTILLERY|1|-
+IND|84,37|ARMOUR|1|-
+IND|82,43|INFANTRY|1|-
+IND|87,41|INFANTRY|1|-
+PAK|81,40|INFANTRY|1|-
+PAK|82,40|ARTILLERY|1|-
+LKA|84,49|INFANTRY|1|-
+NPL|87,38|INFANTRY|1|-
+CHN|100,28|INFANTRY|1|-
+CHN|101,28|ARTILLERY|1|-
+CHN|100,27|ARMOUR|1|-
+CHN|103,36|INFANTRY|1|-
+CHN|98,41|INFANTRY|1|-
+CHN|99,36|INFANTRY|1|-
+CHN|94,36|INFANTRY|1|-
+TWN|103,40|INFANTRY|1|-
+KOR|106,30|INFANTRY|1|-
+KOR|106,29|ARTILLERY|1|-
+PRK|105,29|INFANTRY|1|-
+JPN|112,32|INFANTRY|1|-
+JPN|112,31|ARTILLERY|1|-
+JPN|111,31|ARMOUR|1|-
+JPN|109,33|INFANTRY|1|-
+JPN|113,32|DESTROYER|1|-
+MMR|90,44|INFANTRY|1|-
+THA|92,46|INFANTRY|1|-
+THA|93,46|ARTILLERY|1|-
+IDN|95,56|INFANTRY|1|-
+IDN|96,56|ARTILLERY|1|-
+PHL|102,45|INFANTRY|1|-
+PHL|103,45|ARTILLERY|1|-
AUS|116,68|INFANTRY|1|-
AUS|115,67|ARTILLERY|1|-
AUS|115,68|ARMOUR|1|-
AUS|114,69|INFANTRY|1|-
AUS|117,68|DESTROYER|1|-
-USA|25,25|INFANTRY|1|-
-USA|26,24|ARTILLERY|1|-
-USA|25,24|ARMOUR|1|-
-USA|24,27|INFANTRY|1|-
-USA|21,24|INFANTRY|1|-
-USA|18,36|INFANTRY|1|-
-USA|10,32|INFANTRY|1|-
-USA|9,28|INFANTRY|1|-
-USA|26,25|DESTROYER|1|-
-CAN|23,23|INFANTRY|1|-
-CAN|24,24|ARTILLERY|1|-
-CAN|24,23|DESTROYER|1|-
-MEX|16,41|INFANTRY|1|-
-MEX|17,41|ARTILLERY|1|-
-MEX|17,40|ARMOUR|1|-
-GTM|20,44|INFANTRY|1|-
-PAN|23,47|INFANTRY|1|-
-CUB|22,39|INFANTRY|1|-
-DOM|27,42|INFANTRY|1|-
-COL|25,49|INFANTRY|1|-
-COL|26,49|ARTILLERY|1|-
-VEN|28,46|INFANTRY|1|-
-ECU|24,52|INFANTRY|1|-
-PER|24,58|INFANTRY|1|-
-PER|25,58|ARTILLERY|1|-
-BOL|27,60|INFANTRY|1|-
+USA|25,27|INFANTRY|1|-
+USA|26,26|ARTILLERY|1|-
+USA|25,26|ARMOUR|1|-
+USA|24,29|INFANTRY|1|-
+USA|21,26|INFANTRY|1|-
+USA|17,37|INFANTRY|1|-
+USA|10,34|INFANTRY|1|-
+USA|8,29|INFANTRY|1|-
+USA|26,27|DESTROYER|1|-
+CAN|23,25|INFANTRY|1|-
+CAN|24,26|ARTILLERY|1|-
+CAN|24,25|DESTROYER|1|-
+MEX|16,43|INFANTRY|1|-
+MEX|17,43|ARTILLERY|1|-
+MEX|17,42|ARMOUR|1|-
+GTM|19,45|INFANTRY|1|-
+PAN|23,48|INFANTRY|1|-
+CUB|22,41|INFANTRY|1|-
+DOM|26,43|INFANTRY|1|-
+COL|25,51|INFANTRY|1|-
+COL|26,51|ARTILLERY|1|-
+VEN|28,48|INFANTRY|1|-
+ECU|23,53|INFANTRY|1|-
+PER|24,59|INFANTRY|1|-
+PER|25,59|ARTILLERY|1|-
+BOL|27,61|INFANTRY|1|-
CHL|27,68|INFANTRY|1|-
CHL|28,68|ARTILLERY|1|-
-ARG|30,68|INFANTRY|1|-
-ARG|30,67|ARTILLERY|1|-
+ARG|30,69|INFANTRY|1|-
+ARG|30,68|ARTILLERY|1|-
URY|31,68|INFANTRY|1|-
-PRY|31,64|INFANTRY|1|-
+PRY|30,65|INFANTRY|1|-
BRA|33,63|INFANTRY|1|-
BRA|34,62|ARTILLERY|1|-
BRA|33,62|ARMOUR|1|-
diff --git a/app/src/main/assets/scenarios/conquest_1980.scn b/app/src/main/assets/scenarios/conquest_1980.scn
index ec2fea2..fd1fed3 100644
--- a/app/src/main/assets/scenarios/conquest_1980.scn
+++ b/app/src/main/assets/scenarios/conquest_1980.scn
@@ -13,104 +13,104 @@ startYear 1980
startMonth 1
[nations]
-RUS|nation_sun|#8C6E4C|41|AGGRESSIVE|3824|2,2,2,2,2,1|🇷🇺|PACT|1
-USA|nation_usa|#4C7BA8|171|BALANCED|3040|2,2,2,2,2,1|🇺🇸|NATO|1
-CHN|nation_chn|#B4454C|128|TURTLE|2890|2,2,2,2,2,1|🇨🇳||1
-IND|nation_ind|#C4864C|116|TURTLE|1552|2,2,2,2,2,1|🇮🇳||1
-JPN|nation_jpn|#C45C5C|148|TURTLE|1500|2,2,2,2,2,1|🇯🇵||1
+RUS|nation_sun|#8C6E4C|46|AGGRESSIVE|3824|2,2,2,2,2,1|🇷🇺|PACT|1
+USA|nation_usa|#4C7BA8|178|BALANCED|3040|2,2,2,2,2,1|🇺🇸|NATO|1
+CHN|nation_chn|#B4454C|134|TURTLE|2890|2,2,2,2,2,1|🇨🇳||1
+IND|nation_ind|#C4864C|121|TURTLE|1610|2,2,2,2,2,1|🇮🇳||1
+JPN|nation_jpn|#C45C5C|155|TURTLE|1500|2,2,2,2,2,1|🇯🇵||1
DEU|nation_frg|#6E7A86|19|AGGRESSIVE|1322|1,1,1,1,1,1|🇩🇪|NATO|1
GBR|nation_gbr|#8C4C4C|0|BALANCED|1320|1,1,1,1,1,1|🇬🇧|NATO|1
-BRA|nation_bra|#4F9A50|222|TURTLE|1260|1,1,1,1,1,1|🇧🇷||1
-AUS|nation_aus|#C4A05C|230|TURTLE|1148|1,1,1,1,1,1|🇦🇺||1
+BRA|nation_bra|#4F9A50|229|TURTLE|1260|1,1,1,1,1,1|🇧🇷||1
+AUS|nation_aus|#C4A05C|237|TURTLE|1148|1,1,1,1,1,1|🇦🇺||1
FRA|nation_fra|#4C5C9E|4|BALANCED|1092|1,1,1,1,1,1|🇫🇷|NATO|1
-CAN|nation_can|#6E93B5|189|TURTLE|979|1,1,1,1,1,1|🇨🇦|NATO|1
-SAU|nation_sau|#4C8C5C|78|TURTLE|902|1,1,1,1,1,1|🇸🇦||1
-IDN|nation_idn|#A85C4C|163|TURTLE|875|1,1,0,0,0,1|🇮🇩||1
-TUR|nation_tur|#A84C4C|68|AGGRESSIVE|850|1,1,0,0,0,1|🇹🇷|NATO|1
-IRN|nation_irn|#4C8C6E|71|TURTLE|804|1,1,0,0,0,1|🇮🇷||1
+CAN|nation_can|#6E93B5|196|TURTLE|979|1,1,1,1,1,1|🇨🇦|NATO|1
+SAU|nation_sau|#4C8C5C|83|TURTLE|902|1,1,1,1,1,1|🇸🇦||1
+IDN|nation_idn|#A85C4C|170|TURTLE|875|1,1,0,0,0,1|🇮🇩||1
+TUR|nation_tur|#A84C4C|73|AGGRESSIVE|850|1,1,0,0,0,1|🇹🇷|NATO|1
+IRN|nation_irn|#4C8C6E|76|TURTLE|804|1,1,0,0,0,1|🇮🇷||1
ITA|nation_ita|#5C9E6E|13|OPPORTUNIST|804|1,1,0,0,0,1|🇮🇹|NATO|1
-EGY|nation_egy|#C4A84C|84|TURTLE|736|1,1,0,0,0,1|🇪🇬||1
-ZAF|nation_zaf|#4C7A5C|112|TURTLE|736|1,1,0,0,0,1|🇿🇦||1
+EGY|nation_egy|#C4A84C|89|TURTLE|736|1,1,0,0,0,1|🇪🇬||1
+ZAF|nation_zaf|#4C7A5C|117|TURTLE|736|1,1,0,0,0,1|🇿🇦||1
DDR|nation_ddr|#8C5A5A|17|BALANCED|735|1,1,0,0,0,1||PACT|1
-MEX|nation_mex|#3F8F6B|198|TURTLE|720|1,1,0,0,0,1|🇲🇽||1
-ARG|nation_arg|#6FA8C4|217|TURTLE|690|1,1,0,0,0,1|🇦🇷||1
-KOR|nation_kor|#5C9EB4|145|TURTLE|682|1,1,0,0,0,1|🇰🇷||1
+MEX|nation_mex|#3F8F6B|205|TURTLE|720|1,1,0,0,0,1|🇲🇽||1
+ARG|nation_arg|#6FA8C4|224|TURTLE|690|1,1,0,0,0,1|🇦🇷||1
+KOR|nation_kor|#5C9EB4|151|TURTLE|682|1,1,0,0,0,1|🇰🇷||1
ESP|nation_esp|#B08A3C|9|TURTLE|644|1,1,0,0,0,1|🇪🇸||1
-NGA|nation_nga|#4C9E5C|97|TURTLE|616|1,1,0,0,0,1|🇳🇬||1
-PAK|nation_pak|#4C8C5C|123|TURTLE|616|1,1,0,0,0,1|🇵🇰||1
+NGA|nation_nga|#4C9E5C|102|TURTLE|616|1,1,0,0,0,1|🇳🇬||1
+PAK|nation_pak|#4C8C5C|129|TURTLE|616|1,1,0,0,0,1|🇵🇰||1
POL|nation_pol|#B4535C|23|BALANCED|572|1,1,0,0,0,1|🇵🇱|PACT|1
-TWN|nation_roc|#4C86B4|143|TURTLE|572|1,1,0,0,0,1|🇹🇼||1
-SGP|nation_sgp|#B45C5C|162|TURTLE|546|1,1,0,0,0,1|🇸🇬||1
-THA|nation_tha|#5C86A8|155|TURTLE|528|1,1,0,0,0,1|🇹🇭||1
-DZA|nation_dza|#5C9E5C|89|TURTLE|506|1,1,0,0,0,1|🇩🇿||1
-VNM|nation_vnm|#B4954C|158|TURTLE|506|1,1,0,0,0,1|🇻🇳||1
-ARE|nation_are|#6E9E7A|80|TURTLE|483|0,0,0,0,0,0|🇦🇪||1
-CHL|nation_chl|#A8544C|214|TURTLE|482|0,0,0,0,0,0|🇨🇱||1
-COL|nation_col|#C29A3C|206|TURTLE|462|0,0,0,0,0,0|🇨🇴||1
-IRQ|nation_irq|#8C8C4C|74|TURTLE|462|0,0,0,0,0,0|🇮🇶||1
-MYS|nation_mys|#4C9E6E|160|TURTLE|462|0,0,0,0,0,0|🇲🇾||1
-PHL|nation_phl|#4C86A8|168|TURTLE|462|0,0,0,0,0,0|🇵🇭||1
-ISR|nation_isr|#5C86B4|77|TURTLE|441|0,0,0,0,0,0|🇮🇱||1
-SWE|nation_swe|#4C6E9E|30|TURTLE|441|0,0,0,0,0,0|🇸🇪||1
-COD|nation_cod|#5C8C4C|105|TURTLE|418|0,0,0,0,0,0|🇨🇩||1
-NOR|nation_nor|#5C7EA8|31|TURTLE|418|0,0,0,0,0,0|🇳🇴|NATO|1
-NZL|nation_nzl|#5C9E93|238|TURTLE|418|0,0,0,0,0,0|🇳🇿||1
-PER|nation_per|#B06A4C|211|TURTLE|418|0,0,0,0,0,0|🇵🇪||1
-MAR|nation_mar|#A85C4C|91|TURTLE|399|0,0,0,0,0,0|🇲🇦||1
+TWN|nation_roc|#4C86B4|149|TURTLE|572|1,1,0,0,0,1|🇹🇼||1
+SGP|nation_sgp|#B45C5C|169|TURTLE|546|1,1,0,0,0,1|🇸🇬||1
+THA|nation_tha|#5C86A8|162|TURTLE|528|1,1,0,0,0,1|🇹🇭||1
+DZA|nation_dza|#5C9E5C|94|TURTLE|506|1,1,0,0,0,1|🇩🇿||1
+VNM|nation_vnm|#B4954C|165|TURTLE|506|1,1,0,0,0,1|🇻🇳||1
+SWE|nation_swe|#4C6E9E|30|TURTLE|504|1,1,0,0,0,1|🇸🇪||1
+ARE|nation_are|#6E9E7A|85|TURTLE|483|0,0,0,0,0,0|🇦🇪||1
+CHL|nation_chl|#A8544C|221|TURTLE|482|0,0,0,0,0,0|🇨🇱||1
+COL|nation_col|#C29A3C|213|TURTLE|462|0,0,0,0,0,0|🇨🇴||1
+IRQ|nation_irq|#8C8C4C|79|TURTLE|462|0,0,0,0,0,0|🇮🇶||1
+MYS|nation_mys|#4C9E6E|167|TURTLE|462|0,0,0,0,0,0|🇲🇾||1
+PHL|nation_phl|#4C86A8|175|TURTLE|462|0,0,0,0,0,0|🇵🇭||1
+ISR|nation_isr|#5C86B4|82|TURTLE|441|0,0,0,0,0,0|🇮🇱||1
+COD|nation_cod|#5C8C4C|110|TURTLE|418|0,0,0,0,0,0|🇨🇩||1
+NOR|nation_nor|#5C7EA8|34|TURTLE|418|0,0,0,0,0,0|🇳🇴|NATO|1
+NZL|nation_nzl|#5C9E93|245|TURTLE|418|0,0,0,0,0,0|🇳🇿||1
+PER|nation_per|#B06A4C|218|TURTLE|418|0,0,0,0,0,0|🇵🇪||1
+MAR|nation_mar|#A85C4C|96|TURTLE|399|0,0,0,0,0,0|🇲🇦||1
NLD|nation_nld|#C4813C|8|TURTLE|399|0,0,0,0,0,0|🇳🇱|NATO|1
-VEN|nation_ven|#B4703C|208|TURTLE|399|0,0,0,0,0,0|🇻🇪||1
+VEN|nation_ven|#B4703C|215|TURTLE|399|0,0,0,0,0,0|🇻🇪||1
+PRK|nation_prk|#8C5C6E|153|TURTLE|396|0,0,0,0,0,0|🇰🇵||1
CHE|nation_che|#B45C5C|16|TURTLE|378|0,0,0,0,0,0|🇨🇭||1
-PRK|nation_prk|#8C5C6E|147|TURTLE|378|0,0,0,0,0,0|🇰🇵||1
+DNK|nation_dnk|#A85C6E|35|TURTLE|368|0,0,0,0,0,0|🇩🇰|NATO|1
AUT|nation_aut|#A0A6AC|21|TURTLE|357|0,0,0,0,0,0|🇦🇹||1
-ETH|nation_eth|#6E9E4C|101|TURTLE|357|0,0,0,0,0,0|🇪🇹||1
-DNK|nation_dnk|#A85C6E|32|TURTLE|352|0,0,0,0,0,0|🇩🇰|NATO|1
-AGO|nation_ago|#A8804C|107|TURTLE|336|0,0,0,0,0,0|🇦🇴||1
+ETH|nation_eth|#6E9E4C|106|TURTLE|357|0,0,0,0,0,0|🇪🇹||1
+FIN|nation_fin|#7A9EB4|37|TURTLE|352|0,0,0,0,0,0|🇫🇮||1
+AGO|nation_ago|#A8804C|112|TURTLE|336|0,0,0,0,0,0|🇦🇴||1
BEL|nation_bel|#9E8C4C|7|TURTLE|336|0,0,0,0,0,0|🇧🇪|NATO|1
-BGD|nation_bgd|#5C9E7A|125|TURTLE|336|0,0,0,0,0,0|🇧🇩||1
-FIN|nation_fin|#7A9EB4|33|TURTLE|336|0,0,0,0,0,0|🇫🇮||1
-KEN|nation_ken|#4C8C6E|103|TURTLE|336|0,0,0,0,0,0|🇰🇪||1
-LBY|nation_lby|#A89A5C|87|TURTLE|336|0,0,0,0,0,0|🇱🇾||1
+BGD|nation_bgd|#5C9E7A|131|TURTLE|336|0,0,0,0,0,0|🇧🇩||1
+KEN|nation_ken|#4C8C6E|108|TURTLE|336|0,0,0,0,0,0|🇰🇪||1
+LBY|nation_lby|#A89A5C|92|TURTLE|336|0,0,0,0,0,0|🇱🇾||1
ROU|nation_rou|#8C7A3C|26|TURTLE|336|0,0,0,0,0,0|🇷🇴|PACT|1
-MMR|nation_mmr|#8C9E4C|153|TURTLE|330|0,0,0,0,0,0|🇲🇲||1
+MMR|nation_mmr|#8C9E4C|160|TURTLE|330|0,0,0,0,0,0|🇲🇲||1
CZE|nation_cze|#8A96A0|22|TURTLE|315|0,0,0,0,0,0|🇨🇿|PACT|1
GRC|nation_grc|#4C7AA8|29|TURTLE|315|0,0,0,0,0,0|🇬🇷|NATO|1
HUN|nation_hun|#9E7A4C|25|OPPORTUNIST|315|0,0,0,0,0,0|🇭🇺|PACT|1
PRT|nation_prt|#4C8C7A|12|TURTLE|315|0,0,0,0,0,0|🇵🇹|NATO|1
-SDN|nation_sdn|#9E8C4C|100|TURTLE|294|0,0,0,0,0,0|🇸🇩||1
-TZA|nation_tza|#4C9E86|108|TURTLE|294|0,0,0,0,0,0|🇹🇿||1
-CUB|nation_cub|#A85C4C|204|TURTLE|273|0,0,0,0,0,0|🇨🇺||1
-GHA|nation_gha|#B4844C|96|TURTLE|273|0,0,0,0,0,0|🇬🇭||1
+SDN|nation_sdn|#9E8C4C|105|TURTLE|294|0,0,0,0,0,0|🇸🇩||1
+TZA|nation_tza|#4C9E86|113|TURTLE|294|0,0,0,0,0,0|🇹🇿||1
+CUB|nation_cub|#A85C4C|211|TURTLE|273|0,0,0,0,0,0|🇨🇺||1
+GHA|nation_gha|#B4844C|101|TURTLE|273|0,0,0,0,0,0|🇬🇭||1
IRL|nation_irl|#4C8C5C|3|TURTLE|273|0,0,0,0,0,0|🇮🇪||1
-OMN|nation_omn|#8C9E7A|82|TURTLE|273|0,0,0,0,0,0|🇴🇲||1
+OMN|nation_omn|#8C9E7A|87|TURTLE|273|0,0,0,0,0,0|🇴🇲||1
SRB|nation_srb|#8C5C4C|27|TURTLE|273|0,0,0,0,0,0|🇷🇸||1
-SYR|nation_syr|#7A8C5C|76|TURTLE|273|0,0,0,0,0,0|🇸🇾||1
-ECU|nation_ecu|#C7A24E|209|TURTLE|264|0,0,0,0,0,0|🇪🇨||1
+SYR|nation_syr|#7A8C5C|81|TURTLE|273|0,0,0,0,0,0|🇸🇾||1
+ECU|nation_ecu|#C7A24E|216|TURTLE|264|0,0,0,0,0,0|🇪🇨||1
BGR|nation_bgr|#6E8C5C|28|TURTLE|252|0,0,0,0,0,0|🇧🇬|PACT|1
-BOL|nation_bol|#8C9A4C|213|TURTLE|252|0,0,0,0,0,0|🇧🇴||1
-CIV|nation_civ|#C4954C|95|TURTLE|252|0,0,0,0,0,0|🇨🇮||1
-MNG|nation_mng|#B4A05C|67|TURTLE|252|0,0,0,0,0,0|🇲🇳||1
-TUN|nation_tun|#9E5C5C|88|TURTLE|252|0,0,0,0,0,0|🇹🇳||1
-AFG|nation_afg|#8C7A5C|83|TURTLE|231|0,0,0,0,0,0|🇦🇫||1
-GTM|nation_gtm|#57A07E|202|TURTLE|231|0,0,0,0,0,0|🇬🇹||1
-LKA|nation_lka|#B4844C|126|TURTLE|231|0,0,0,0,0,0|🇱🇰||1
-MOZ|nation_moz|#7A9E6E|114|TURTLE|231|0,0,0,0,0,0|🇲🇿||1
-PAN|nation_pan|#4E9E86|203|TURTLE|231|0,0,0,0,0,0|🇵🇦||1
-SEN|nation_sen|#5C9E7A|92|TURTLE|231|0,0,0,0,0,0|🇸🇳||1
-UGA|nation_uga|#7A9E5C|104|TURTLE|231|0,0,0,0,0,0|🇺🇬||1
-URY|nation_ury|#6E9BB0|220|TURTLE|231|0,0,0,0,0,0|🇺🇾||1
-ZMB|nation_zmb|#8C9E5C|109|TURTLE|231|0,0,0,0,0,0|🇿🇲||1
-MLI|nation_mli|#B49A5C|93|TURTLE|220|0,0,0,0,0,0|🇲🇱||1
-DOM|nation_dom|#9E6B58|205|TURTLE|210|0,0,0,0,0,0|🇩🇴||1
-KHM|nation_khm|#7A8C6E|159|TURTLE|210|0,0,0,0,0,0|🇰🇭||1
-MDG|nation_mdg|#8C6E9E|115|TURTLE|210|0,0,0,0,0,0|🇲🇬||1
-PRY|nation_pry|#7F8F5C|221|TURTLE|210|0,0,0,0,0,0|🇵🇾||1
-YEM|nation_yem|#A87A5C|81|TURTLE|210|0,0,0,0,0,0|🇾🇪||1
-ZWE|nation_zwe|#9E8C5C|110|TURTLE|210|0,0,0,0,0,0|🇿🇼||1
-NPL|nation_npl|#A85C5C|127|TURTLE|189|0,0,0,0,0,0|🇳🇵||1
-PNG|nation_png|#7A9E86|170|TURTLE|189|0,0,0,0,0,0|🇵🇬||1
-SOM|nation_som|#7AA8B4|102|TURTLE|189|0,0,0,0,0,0|🇸🇴||1
-TCD|nation_tcd|#A8945C|99|TURTLE|189|0,0,0,0,0,0|🇹🇩||1
-ISL|nation_isl|#93A8B4|35|TURTLE|157|0,0,0,0,0,0|🇮🇸|NATO|1
+BOL|nation_bol|#8C9A4C|220|TURTLE|252|0,0,0,0,0,0|🇧🇴||1
+CIV|nation_civ|#C4954C|100|TURTLE|252|0,0,0,0,0,0|🇨🇮||1
+MNG|nation_mng|#B4A05C|72|TURTLE|252|0,0,0,0,0,0|🇲🇳||1
+TUN|nation_tun|#9E5C5C|93|TURTLE|252|0,0,0,0,0,0|🇹🇳||1
+AFG|nation_afg|#8C7A5C|88|TURTLE|231|0,0,0,0,0,0|🇦🇫||1
+GTM|nation_gtm|#57A07E|209|TURTLE|231|0,0,0,0,0,0|🇬🇹||1
+LKA|nation_lka|#B4844C|132|TURTLE|231|0,0,0,0,0,0|🇱🇰||1
+MOZ|nation_moz|#7A9E6E|119|TURTLE|231|0,0,0,0,0,0|🇲🇿||1
+PAN|nation_pan|#4E9E86|210|TURTLE|231|0,0,0,0,0,0|🇵🇦||1
+SEN|nation_sen|#5C9E7A|97|TURTLE|231|0,0,0,0,0,0|🇸🇳||1
+UGA|nation_uga|#7A9E5C|109|TURTLE|231|0,0,0,0,0,0|🇺🇬||1
+URY|nation_ury|#6E9BB0|227|TURTLE|231|0,0,0,0,0,0|🇺🇾||1
+ZMB|nation_zmb|#8C9E5C|114|TURTLE|231|0,0,0,0,0,0|🇿🇲||1
+MLI|nation_mli|#B49A5C|98|TURTLE|220|0,0,0,0,0,0|🇲🇱||1
+DOM|nation_dom|#9E6B58|212|TURTLE|210|0,0,0,0,0,0|🇩🇴||1
+KHM|nation_khm|#7A8C6E|166|TURTLE|210|0,0,0,0,0,0|🇰🇭||1
+MDG|nation_mdg|#8C6E9E|120|TURTLE|210|0,0,0,0,0,0|🇲🇬||1
+PRY|nation_pry|#7F8F5C|228|TURTLE|210|0,0,0,0,0,0|🇵🇾||1
+YEM|nation_yem|#A87A5C|86|TURTLE|210|0,0,0,0,0,0|🇾🇪||1
+ZWE|nation_zwe|#9E8C5C|115|TURTLE|210|0,0,0,0,0,0|🇿🇼||1
+NPL|nation_npl|#A85C5C|133|TURTLE|189|0,0,0,0,0,0|🇳🇵||1
+PNG|nation_png|#7A9E86|177|TURTLE|189|0,0,0,0,0,0|🇵🇬||1
+SOM|nation_som|#7AA8B4|107|TURTLE|189|0,0,0,0,0,0|🇸🇴||1
+TCD|nation_tcd|#A8945C|104|TURTLE|189|0,0,0,0,0,0|🇹🇩||1
+ISL|nation_isl|#93A8B4|40|TURTLE|157|0,0,0,0,0,0|🇮🇸|NATO|1
[relations]
USA RUS WAR
@@ -213,278 +213,275 @@ TUR BGR WAR
TUR DDR WAR
[owners]
-RUS: 34,37-66
-USA: 171-188
-CHN: 128-141
-IND: 116-122
-JPN: 148-152
+RUS: 39,42-71
+USA: 178-195
+CHN: 134-147
+IND: 121-128
+JPN: 155-159
DEU: 18-20
-GBR: 0-2,142
-BRA: 222-229
-AUS: 230-237
+GBR: 0-2,148
+BRA: 229-236
+AUS: 237-244
FRA: 4-6
-CAN: 189-196
-SAU: 78-79
-IDN: 163-167
-TUR: 68-70
-IRN: 71-73
+CAN: 196-203
+SAU: 83-84
+IDN: 170-174
+TUR: 73-75
+IRN: 76-78
ITA: 13-15
-EGY: 84-86
-ZAF: 111-113
+EGY: 89-91
+ZAF: 116-118
DDR: 17
-MEX: 198-201
-ARG: 217-219
-KOR: 145-146
+MEX: 205-208
+ARG: 224-226
+KOR: 151-152
ESP: 9-11
-NGA: 97-98
-PAK: 123-124
+NGA: 102-103
+PAK: 129-130
POL: 23-24
-TWN: 143-144
-SGP: 162
-THA: 155-156
-DZA: 89-90
-VNM: 157-158
-ARE: 80
-CHL: 214-216
-COL: 206-207
-IRQ: 74-75
-MYS: 160-161
-PHL: 168-169
-ISR: 77
-SWE: 30
-COD: 105-106
-NOR: 31,36
-NZL: 238-239
-PER: 211-212
-MAR: 91
+TWN: 149-150
+SGP: 169
+THA: 162-163
+DZA: 94-95
+VNM: 164-165
+SWE: 30-33
+ARE: 85
+CHL: 221-223
+COL: 213-214
+IRQ: 79-80
+MYS: 167-168
+PHL: 175-176
+ISR: 82
+COD: 110-111
+NOR: 34,41
+NZL: 245-246
+PER: 218-219
+MAR: 96
NLD: 8
-VEN: 208
+VEN: 215
+PRK: 153-154
CHE: 16
-PRK: 147
+DNK: 35-36,204
AUT: 21
-ETH: 101
-DNK: 32,197
-AGO: 107
+ETH: 106
+FIN: 37-38
+AGO: 112
BEL: 7
-BGD: 125
-FIN: 33
-KEN: 103
-LBY: 87
+BGD: 131
+KEN: 108
+LBY: 92
ROU: 26
-MMR: 153-154
+MMR: 160-161
CZE: 22
GRC: 29
HUN: 25
PRT: 12
-SDN: 100
-TZA: 108
-CUB: 204
-GHA: 96
+SDN: 105
+TZA: 113
+CUB: 211
+GHA: 101
IRL: 3
-OMN: 82
+OMN: 87
SRB: 27
-SYR: 76
-ECU: 209-210
+SYR: 81
+ECU: 216-217
BGR: 28
-BOL: 213
-CIV: 95
-MNG: 67
-TUN: 88
-AFG: 83
-GTM: 202
-LKA: 126
-MOZ: 114
-PAN: 203
-SEN: 92
-UGA: 104
-URY: 220
-ZMB: 109
-MLI: 93-94
-DOM: 205
-KHM: 159
-MDG: 115
-PRY: 221
-YEM: 81
-ZWE: 110
-NPL: 127
-PNG: 170
-SOM: 102
-TCD: 99
-ISL: 35
+BOL: 220
+CIV: 100
+MNG: 72
+TUN: 93
+AFG: 88
+GTM: 209
+LKA: 132
+MOZ: 119
+PAN: 210
+SEN: 97
+UGA: 109
+URY: 227
+ZMB: 114
+MLI: 98-99
+DOM: 212
+KHM: 166
+MDG: 120
+PRY: 228
+YEM: 86
+ZWE: 115
+NPL: 133
+PNG: 177
+SOM: 107
+TCD: 104
+ISL: 40
[units]
-GBR|47,15|INFANTRY|1|-
-GBR|46,15|ARTILLERY|1|-
-GBR|45,15|ARMOUR|1|-
+GBR|47,17|INFANTRY|1|-
+GBR|46,17|ARTILLERY|1|-
+GBR|45,17|ARMOUR|1|-
GBR|99,40|INFANTRY|1|-
-GBR|48,15|DESTROYER|1|-
-IRL|43,13|INFANTRY|1|-
-FRA|48,17|INFANTRY|1|-
-FRA|49,17|ARTILLERY|1|-
-FRA|49,16|ARMOUR|1|-
-FRA|48,16|DESTROYER|1|-
-BEL|49,15|INFANTRY|1|-
-NLD|50,14|INFANTRY|1|-
-ESP|45,26|INFANTRY|1|-
-ESP|46,26|ARTILLERY|1|-
-PRT|41,27|INFANTRY|1|-
-ITA|55,24|INFANTRY|1|-
-ITA|56,24|ARTILLERY|1|-
-ITA|55,23|ARMOUR|1|-
-ITA|52,21|INFANTRY|1|-
-CHE|52,19|INFANTRY|1|-
-DDR|55,14|INFANTRY|1|-
-DDR|56,14|ARTILLERY|1|-
-DDR|55,13|ARMOUR|1|-
-DEU|54,18|INFANTRY|1|-
-DEU|55,18|ARTILLERY|1|-
-DEU|54,17|ARMOUR|1|-
-AUT|57,18|INFANTRY|1|-
-CZE|56,16|INFANTRY|1|-
-POL|60,14|INFANTRY|1|-
-POL|61,14|ARTILLERY|1|-
-HUN|58,19|INFANTRY|1|-
-ROU|63,22|INFANTRY|1|-
-SRB|59,21|INFANTRY|1|-
-BGR|61,23|INFANTRY|1|-
-GRC|61,28|INFANTRY|1|-
-SWE|58,7|INFANTRY|1|-
-SWE|59,6|ARTILLERY|1|-
-NOR|53,7|INFANTRY|1|-
-NOR|54,7|ARTILLERY|1|-
-DNK|54,11|INFANTRY|1|-
-FIN|62,7|INFANTRY|1|-
-RUS|69,11|INFANTRY|1|-
-RUS|70,11|ARTILLERY|1|-
-RUS|70,10|ARMOUR|1|-
-RUS|65,16|INFANTRY|1|-
-RUS|65,7|INFANTRY|1|-
-ISL|38,5|INFANTRY|1|-
-MNG|95,18|INFANTRY|1|-
-TUR|64,25|INFANTRY|1|-
-TUR|65,25|ARTILLERY|1|-
-TUR|65,26|ARMOUR|1|-
-IRN|76,30|INFANTRY|1|-
-IRN|77,30|ARTILLERY|1|-
-IRN|76,29|ARMOUR|1|-
-IRQ|74,32|INFANTRY|1|-
-IRQ|74,31|ARTILLERY|1|-
-SYR|69,32|INFANTRY|1|-
-ISR|68,34|INFANTRY|1|-
-ISR|69,34|ARTILLERY|1|-
-SAU|74,39|INFANTRY|1|-
-SAU|75,39|ARTILLERY|1|-
-SAU|75,38|ARMOUR|1|-
-ARE|77,38|INFANTRY|1|-
-ARE|78,38|ARTILLERY|1|-
-YEM|73,43|INFANTRY|1|-
-OMN|78,39|INFANTRY|1|-
-AFG|81,31|INFANTRY|1|-
-EGY|65,35|INFANTRY|1|-
-EGY|66,35|ARTILLERY|1|-
-EGY|66,34|ARMOUR|1|-
-LBY|55,33|INFANTRY|1|-
-TUN|53,29|INFANTRY|1|-
-DZA|49,29|INFANTRY|1|-
-DZA|50,29|ARTILLERY|1|-
-MAR|43,32|INFANTRY|1|-
-SEN|39,43|INFANTRY|1|-
-MLI|42,45|INFANTRY|1|-
-CIV|44,49|INFANTRY|1|-
-GHA|47,49|INFANTRY|1|-
-NGA|49,49|INFANTRY|1|-
-NGA|50,48|ARTILLERY|1|-
-TCD|56,45|INFANTRY|1|-
-SDN|66,43|INFANTRY|1|-
-ETH|70,47|INFANTRY|1|-
-SOM|73,51|INFANTRY|1|-
-KEN|69,53|INFANTRY|1|-
-UGA|67,52|INFANTRY|1|-
-COD|56,54|INFANTRY|1|-
-COD|57,54|ARTILLERY|1|-
-AGO|55,56|INFANTRY|1|-
-TZA|70,55|INFANTRY|1|-
-ZMB|64,59|INFANTRY|1|-
-ZWE|66,60|INFANTRY|1|-
-ZAF|64,64|INFANTRY|1|-
-ZAF|65,64|ARTILLERY|1|-
-ZAF|64,63|ARMOUR|1|-
-MOZ|67,64|INFANTRY|1|-
-MDG|74,61|INFANTRY|1|-
-IND|84,36|INFANTRY|1|-
-IND|85,36|ARTILLERY|1|-
-IND|84,35|ARMOUR|1|-
-IND|82,41|INFANTRY|1|-
-IND|87,39|INFANTRY|1|-
-PAK|81,38|INFANTRY|1|-
-PAK|82,38|ARTILLERY|1|-
-BGD|88,39|INFANTRY|1|-
-LKA|85,48|INFANTRY|1|-
-NPL|86,37|INFANTRY|1|-
-CHN|100,26|INFANTRY|1|-
-CHN|101,26|ARTILLERY|1|-
-CHN|100,25|ARMOUR|1|-
-CHN|103,34|INFANTRY|1|-
-CHN|98,39|INFANTRY|1|-
-CHN|98,35|INFANTRY|1|-
-CHN|93,35|INFANTRY|1|-
-TWN|103,38|INFANTRY|1|-
-TWN|102,39|ARTILLERY|1|-
-KOR|106,28|INFANTRY|1|-
-KOR|106,27|ARTILLERY|1|-
-PRK|104,27|INFANTRY|1|-
-JPN|112,30|INFANTRY|1|-
-JPN|112,29|ARTILLERY|1|-
-JPN|111,29|ARMOUR|1|-
-JPN|109,31|INFANTRY|1|-
-JPN|113,30|DESTROYER|1|-
-MMR|90,43|INFANTRY|1|-
-THA|92,44|INFANTRY|1|-
-THA|93,44|ARTILLERY|1|-
-VNM|95,46|INFANTRY|1|-
-VNM|95,45|ARTILLERY|1|-
-KHM|94,46|INFANTRY|1|-
-MYS|92,50|INFANTRY|1|-
-MYS|93,50|ARTILLERY|1|-
-SGP|93,51|INFANTRY|1|-
-IDN|95,55|INFANTRY|1|-
-IDN|94,55|ARTILLERY|1|-
-IDN|94,54|ARMOUR|1|-
-PHL|102,44|INFANTRY|1|-
-PHL|103,44|ARTILLERY|1|-
+GBR|48,17|DESTROYER|1|-
+IRL|43,15|INFANTRY|1|-
+FRA|49,20|INFANTRY|1|-
+FRA|50,20|ARTILLERY|1|-
+FRA|49,19|ARMOUR|1|-
+BEL|50,18|INFANTRY|1|-
+NLD|50,16|INFANTRY|1|-
+ESP|45,27|INFANTRY|1|-
+ESP|46,27|ARTILLERY|1|-
+PRT|41,29|INFANTRY|1|-
+ITA|55,26|INFANTRY|1|-
+ITA|56,26|ARTILLERY|1|-
+ITA|55,25|ARMOUR|1|-
+ITA|52,23|INFANTRY|1|-
+CHE|52,21|INFANTRY|1|-
+DDR|55,16|INFANTRY|1|-
+DDR|56,16|ARTILLERY|1|-
+DDR|55,15|ARMOUR|1|-
+DEU|54,20|INFANTRY|1|-
+DEU|55,20|ARTILLERY|1|-
+DEU|54,19|ARMOUR|1|-
+AUT|57,20|INFANTRY|1|-
+CZE|56,18|INFANTRY|1|-
+POL|60,16|INFANTRY|1|-
+POL|61,16|ARTILLERY|1|-
+HUN|58,21|INFANTRY|1|-
+ROU|63,24|INFANTRY|1|-
+SRB|59,23|INFANTRY|1|-
+BGR|61,25|INFANTRY|1|-
+GRC|61,30|INFANTRY|1|-
+SWE|58,10|INFANTRY|1|-
+SWE|58,9|ARTILLERY|1|-
+NOR|53,9|INFANTRY|1|-
+NOR|54,9|ARTILLERY|1|-
+DNK|54,13|INFANTRY|1|-
+FIN|62,9|INFANTRY|1|-
+RUS|69,13|INFANTRY|1|-
+RUS|70,13|ARTILLERY|1|-
+RUS|70,12|ARMOUR|1|-
+RUS|65,18|INFANTRY|1|-
+RUS|65,9|INFANTRY|1|-
+ISL|39,6|INFANTRY|1|-
+MNG|95,20|INFANTRY|1|-
+TUR|64,27|INFANTRY|1|-
+TUR|65,27|ARTILLERY|1|-
+TUR|65,28|ARMOUR|1|-
+IRN|76,32|INFANTRY|1|-
+IRN|77,32|ARTILLERY|1|-
+IRN|76,31|ARMOUR|1|-
+IRQ|74,34|INFANTRY|1|-
+IRQ|74,33|ARTILLERY|1|-
+SYR|69,34|INFANTRY|1|-
+ISR|68,35|INFANTRY|1|-
+ISR|68,36|ARTILLERY|1|-
+SAU|74,40|INFANTRY|1|-
+SAU|75,40|ARTILLERY|1|-
+SAU|74,39|ARMOUR|1|-
+ARE|77,40|INFANTRY|1|-
+ARE|76,40|ARTILLERY|1|-
+YEM|73,45|INFANTRY|1|-
+OMN|78,40|INFANTRY|1|-
+AFG|81,33|INFANTRY|1|-
+EGY|65,37|INFANTRY|1|-
+EGY|66,37|ARTILLERY|1|-
+EGY|64,37|ARMOUR|1|-
+LBY|55,34|INFANTRY|1|-
+TUN|53,31|INFANTRY|1|-
+DZA|49,31|INFANTRY|1|-
+DZA|50,31|ARTILLERY|1|-
+MAR|43,34|INFANTRY|1|-
+SEN|39,45|INFANTRY|1|-
+MLI|43,46|INFANTRY|1|-
+CIV|45,50|INFANTRY|1|-
+GHA|47,50|INFANTRY|1|-
+NGA|49,50|INFANTRY|1|-
+NGA|49,49|ARTILLERY|1|-
+TCD|56,47|INFANTRY|1|-
+SDN|66,45|INFANTRY|1|-
+ETH|70,48|INFANTRY|1|-
+SOM|74,52|INFANTRY|1|-
+KEN|69,54|INFANTRY|1|-
+UGA|66,53|INFANTRY|1|-
+COD|56,55|INFANTRY|1|-
+COD|57,55|ARTILLERY|1|-
+AGO|55,57|INFANTRY|1|-
+TZA|71,56|INFANTRY|1|-
+ZMB|64,60|INFANTRY|1|-
+ZWE|65,61|INFANTRY|1|-
+ZAF|63,65|INFANTRY|1|-
+ZAF|64,65|ARTILLERY|1|-
+ZAF|64,64|ARMOUR|1|-
+MOZ|66,65|INFANTRY|1|-
+MDG|75,62|INFANTRY|1|-
+IND|84,38|INFANTRY|1|-
+IND|85,38|ARTILLERY|1|-
+IND|84,37|ARMOUR|1|-
+IND|82,43|INFANTRY|1|-
+IND|87,41|INFANTRY|1|-
+PAK|81,40|INFANTRY|1|-
+PAK|82,40|ARTILLERY|1|-
+BGD|88,40|INFANTRY|1|-
+LKA|84,49|INFANTRY|1|-
+NPL|87,38|INFANTRY|1|-
+CHN|100,28|INFANTRY|1|-
+CHN|101,28|ARTILLERY|1|-
+CHN|100,27|ARMOUR|1|-
+CHN|103,36|INFANTRY|1|-
+CHN|98,41|INFANTRY|1|-
+CHN|99,36|INFANTRY|1|-
+CHN|94,36|INFANTRY|1|-
+TWN|103,40|INFANTRY|1|-
+KOR|106,30|INFANTRY|1|-
+KOR|106,29|ARTILLERY|1|-
+PRK|105,29|INFANTRY|1|-
+JPN|112,32|INFANTRY|1|-
+JPN|112,31|ARTILLERY|1|-
+JPN|111,31|ARMOUR|1|-
+JPN|109,33|INFANTRY|1|-
+JPN|113,32|DESTROYER|1|-
+MMR|90,44|INFANTRY|1|-
+THA|92,46|INFANTRY|1|-
+THA|93,46|ARTILLERY|1|-
+VNM|95,47|INFANTRY|1|-
+VNM|95,46|ARTILLERY|1|-
+KHM|94,47|INFANTRY|1|-
+MYS|92,51|INFANTRY|1|-
+MYS|93,51|ARTILLERY|1|-
+SGP|94,52|INFANTRY|1|-
+IDN|95,56|INFANTRY|1|-
+IDN|96,56|ARTILLERY|1|-
+PHL|102,45|INFANTRY|1|-
+PHL|103,45|ARTILLERY|1|-
PNG|115,57|INFANTRY|1|-
-USA|25,25|INFANTRY|1|-
-USA|26,24|ARTILLERY|1|-
-USA|25,24|ARMOUR|1|-
-USA|24,27|INFANTRY|1|-
-USA|21,24|INFANTRY|1|-
-USA|18,36|INFANTRY|1|-
-USA|10,32|INFANTRY|1|-
-USA|9,28|INFANTRY|1|-
-USA|26,25|DESTROYER|1|-
-CAN|23,23|INFANTRY|1|-
-CAN|24,24|ARTILLERY|1|-
-CAN|24,23|DESTROYER|1|-
-MEX|16,41|INFANTRY|1|-
-MEX|17,41|ARTILLERY|1|-
-MEX|17,40|ARMOUR|1|-
-GTM|20,44|INFANTRY|1|-
-PAN|23,47|INFANTRY|1|-
-CUB|22,39|INFANTRY|1|-
-DOM|27,42|INFANTRY|1|-
-COL|25,49|INFANTRY|1|-
-COL|26,49|ARTILLERY|1|-
-VEN|28,46|INFANTRY|1|-
-ECU|24,52|INFANTRY|1|-
-PER|24,58|INFANTRY|1|-
-PER|25,58|ARTILLERY|1|-
-BOL|27,60|INFANTRY|1|-
+USA|25,27|INFANTRY|1|-
+USA|26,26|ARTILLERY|1|-
+USA|25,26|ARMOUR|1|-
+USA|24,29|INFANTRY|1|-
+USA|21,26|INFANTRY|1|-
+USA|17,37|INFANTRY|1|-
+USA|10,34|INFANTRY|1|-
+USA|8,29|INFANTRY|1|-
+USA|26,27|DESTROYER|1|-
+CAN|23,25|INFANTRY|1|-
+CAN|24,26|ARTILLERY|1|-
+CAN|24,25|DESTROYER|1|-
+MEX|16,43|INFANTRY|1|-
+MEX|17,43|ARTILLERY|1|-
+MEX|17,42|ARMOUR|1|-
+GTM|19,45|INFANTRY|1|-
+PAN|23,48|INFANTRY|1|-
+CUB|22,41|INFANTRY|1|-
+DOM|26,43|INFANTRY|1|-
+COL|25,51|INFANTRY|1|-
+COL|26,51|ARTILLERY|1|-
+VEN|28,48|INFANTRY|1|-
+ECU|23,53|INFANTRY|1|-
+PER|24,59|INFANTRY|1|-
+PER|25,59|ARTILLERY|1|-
+BOL|27,61|INFANTRY|1|-
CHL|27,68|INFANTRY|1|-
CHL|28,68|ARTILLERY|1|-
-ARG|30,68|INFANTRY|1|-
-ARG|30,67|ARTILLERY|1|-
+ARG|30,69|INFANTRY|1|-
+ARG|30,68|ARTILLERY|1|-
URY|31,68|INFANTRY|1|-
-PRY|31,64|INFANTRY|1|-
+PRY|30,65|INFANTRY|1|-
BRA|33,63|INFANTRY|1|-
BRA|34,62|ARTILLERY|1|-
BRA|33,62|ARMOUR|1|-
diff --git a/app/src/main/java/io/github/acidefluorhydrique/mapconquer/GameView.kt b/app/src/main/java/io/github/acidefluorhydrique/mapconquer/GameView.kt
index 8db39ef..e137854 100644
--- a/app/src/main/java/io/github/acidefluorhydrique/mapconquer/GameView.kt
+++ b/app/src/main/java/io/github/acidefluorhydrique/mapconquer/GameView.kt
@@ -925,14 +925,17 @@ class GameView(context: Context) : SurfaceView(context), SurfaceHolder.Callback
}
private fun continueGame() {
- val restored = SaveGame.load(context)
- if (restored == null) {
- toast(Strings.get(R.string.toast_save_broken))
- SaveGame.delete(context)
- refreshSaveState()
- return
+ when (val restored = SaveGame.load(context)) {
+ is SaveGame.Restore.Ok -> installSession(restored.session)
+ SaveGame.Restore.Outdated -> discardSave(R.string.toast_save_outdated)
+ SaveGame.Restore.Broken -> discardSave(R.string.toast_save_broken)
}
- installSession(restored)
+ }
+
+ private fun discardSave(message: Int) {
+ toast(Strings.get(message))
+ SaveGame.delete(context)
+ refreshSaveState()
}
private fun installSession(active: Session) {
diff --git a/app/src/main/java/io/github/acidefluorhydrique/mapconquer/game/SaveGame.kt b/app/src/main/java/io/github/acidefluorhydrique/mapconquer/game/SaveGame.kt
index 1c8a4ad..45da402 100644
--- a/app/src/main/java/io/github/acidefluorhydrique/mapconquer/game/SaveGame.kt
+++ b/app/src/main/java/io/github/acidefluorhydrique/mapconquer/game/SaveGame.kt
@@ -27,6 +27,16 @@ object SaveGame {
private const val FILE_NAME = "session.save"
private const val VERSION = 1
+ /** 讀檔的結果。存檔舊了跟存檔壞了是兩回事,玩家該看到不同的說明。 */
+ sealed class Restore {
+ class Ok(val session: Session) : Restore()
+
+ /** 存檔建立在另一個版本的地圖上(見 [io.github.acidefluorhydrique.mapconquer.world.WorldMap.fingerprint])。 */
+ object Outdated : Restore()
+
+ object Broken : Restore()
+ }
+
fun file(context: Context): File = File(context.filesDir, FILE_NAME)
fun exists(context: Context): Boolean = file(context).let { it.exists() && it.length() > 0 }
@@ -43,6 +53,7 @@ object SaveGame {
val sb = StringBuilder(8 * 1024)
sb.append("v ").append(VERSION).append('\n')
sb.append("scenario ").append(session.scenario.id).append('\n')
+ sb.append("map ").append(session.map.fingerprint).append('\n')
sb.append("difficulty ").append(session.difficulty.name).append('\n')
sb.append("player ").append(session.nations[session.playerNationId].code).append('\n')
sb.append("turn ").append(session.turn).append('\n')
@@ -140,11 +151,15 @@ object SaveGame {
if (scenarioId.isEmpty()) null else Summary(scenarioId, playerCode, difficulty, turn)
}.getOrNull()
- fun load(context: Context): Session? = runCatching {
+ fun load(context: Context): Restore = runCatching { restore(context) }
+ .getOrNull() ?: Restore.Broken
+
+ private fun restore(context: Context): Restore {
val lines = file(context).readLines()
- if (lines.isEmpty()) return null
+ if (lines.isEmpty()) return Restore.Broken
var scenarioId = ""
+ var mapPrint = ""
var playerCode = ""
var difficulty = Difficulty.OFFICER
var turn = 1
@@ -165,6 +180,7 @@ object SaveGame {
val value = line.substring(sep + 1).trim()
when (key) {
"scenario" -> scenarioId = value
+ "map" -> mapPrint = value
"player" -> playerCode = value
"difficulty" -> difficulty = Difficulty.byName(value)
"turn" -> turn = value.toIntOrNull() ?: 1
@@ -180,10 +196,13 @@ object SaveGame {
"unit" -> unitLines.add(value)
}
}
- if (scenarioId.isEmpty()) return null
+ if (scenarioId.isEmpty()) return Restore.Broken
val scenario = ScenarioLoader.load(context, scenarioId)
val map = MapLoader.load(context, scenario.mapId)
+ // 沒有指紋的存檔來自加上指紋之前的版本,而那一版之後地圖已經重新產生過,
+ // 所以一律視為舊的。
+ if (mapPrint != map.fingerprint) return Restore.Outdated
val session = Session(map, scenario, difficulty, playerCode, rngState)
session.turn = turn
@@ -252,6 +271,6 @@ object SaveGame {
session.sortieBases.clear()
sorties.split(',').mapNotNullTo(session.sortieBases) { it.trim().toIntOrNull() }
session.refreshSupplyView()
- session
- }.getOrNull()
+ return Restore.Ok(session)
+ }
}
diff --git a/app/src/main/java/io/github/acidefluorhydrique/mapconquer/world/WorldMap.kt b/app/src/main/java/io/github/acidefluorhydrique/mapconquer/world/WorldMap.kt
index e11e53e..aec035d 100644
--- a/app/src/main/java/io/github/acidefluorhydrique/mapconquer/world/WorldMap.kt
+++ b/app/src/main/java/io/github/acidefluorhydrique/mapconquer/world/WorldMap.kt
@@ -40,6 +40,34 @@ class WorldMap(
val tileCount: Int get() = cols * rows
+ /**
+ * 地圖內容的指紋:尺寸、環繞、每格地形與省份、省份清單。
+ *
+ * 存檔裡的格子與省份都是陣列索引,只在「同一張地圖」上有意義。地圖是
+ * 產生出來的,改一條海岸線、加一座城,索引就整片位移 —— 舊存檔照樣讀得
+ * 進來,只是部隊會站在海上、省份會歸錯國家。存檔記下這個指紋,讀檔時
+ * 對不上就拒絕,而不是默默讀出一局壞掉的戰局。
+ *
+ * 64 位元 FNV-1a:不求密碼學強度,只求任何一格的改動都會改到它。
+ */
+ val fingerprint: String by lazy {
+ var h = FNV_OFFSET
+ fun mix(value: Int) {
+ h = (h xor (value.toLong() and 0xffffffffL)) * FNV_PRIME
+ }
+ mix(cols)
+ mix(rows)
+ mix(if (wrapX) 1 else 0)
+ for (b in terrain) mix(b.toInt())
+ for (p in provinceOf) mix(p)
+ for (p in provinces) {
+ mix(p.capitalTile)
+ mix(p.cityTier)
+ for (c in p.nameKey) mix(c.code)
+ }
+ java.lang.Long.toHexString(h)
+ }
+
fun index(col: Int, row: Int): Int = row * cols + col
fun colOf(index: Int): Int = index % cols
@@ -160,4 +188,9 @@ class WorldMap(
if (inBounds(h.col, h.row)) out.add(indexWrapped(h.col, h.row))
}
}
+
+ private companion object {
+ const val FNV_OFFSET = -0x340d631b7bdddcdbL // 0xcbf29ce484222325
+ const val FNV_PRIME = 0x100000001b3L
+ }
}
diff --git a/app/src/main/res/values-b+zh+Hans/strings.xml b/app/src/main/res/values-b+zh+Hans/strings.xml
index f5f3a50..80ea259 100644
--- a/app/src/main/res/values-b+zh+Hans/strings.xml
+++ b/app/src/main/res/values-b+zh+Hans/strings.xml
@@ -112,6 +112,7 @@
已解除指挥官职务
地图加载失败
存档无法读取
+ 这个存档用的是旧版地图,无法继续
%2$s 攻下 %1$s
%2$s 占领 %1$s
%1$s 已被消灭
@@ -467,9 +468,14 @@
索菲亚
雅典
斯德哥尔摩
+ 哥德堡
+ 松兹瓦尔
+ 基律纳
奥斯陆
哥本哈根
+ 奥胡斯
赫尔辛基
+ 奥卢
里加
雷克雅未克
纳尔维克
@@ -559,6 +565,7 @@
班加罗尔
海得拉巴
那格浦尔
+ 古瓦哈蒂
卡拉奇
拉合尔
达卡
@@ -584,6 +591,7 @@
首尔
釜山
平壤
+ 咸兴
东京
大阪
福冈
diff --git a/app/src/main/res/values-b+zh+Hant/strings.xml b/app/src/main/res/values-b+zh+Hant/strings.xml
index 7cbe594..7b3a7c9 100644
--- a/app/src/main/res/values-b+zh+Hant/strings.xml
+++ b/app/src/main/res/values-b+zh+Hant/strings.xml
@@ -112,6 +112,7 @@
已解除指揮官職務
地圖載入失敗
存檔無法讀取
+ 這個存檔用的是舊版地圖,無法繼續
%2$s 攻下 %1$s
%2$s 佔領 %1$s
%1$s 已被消滅
@@ -467,9 +468,14 @@
索菲亞
雅典
斯德哥爾摩
+ 哥德堡
+ 松茲瓦爾
+ 基律納
奧斯陸
哥本哈根
+ 奧胡斯
赫爾辛基
+ 奧盧
里加
雷克雅維克
納爾維克
@@ -559,6 +565,7 @@
邦加羅爾
海得拉巴
那格浦爾
+ 古瓦哈提
喀拉蚩
拉合爾
達卡
@@ -584,6 +591,7 @@
首爾
釜山
平壤
+ 咸興
東京
大阪
福岡
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 80572a7..d5dd88a 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -112,6 +112,7 @@
Commander stood down
That map could not be loaded
The save file could not be read
+ That save was made on an older version of the map and can\'t be continued
%1$s captured by %2$s
%2$s occupies %1$s
%1$s has been eliminated
@@ -467,9 +468,14 @@
Sofia
Athens
Stockholm
+ Gothenburg
+ Sundsvall
+ Kiruna
Oslo
Copenhagen
+ Aarhus
Helsinki
+ Oulu
Riga
Reykjavik
Narvik
@@ -559,6 +565,7 @@
Bengaluru
Hyderabad
Nagpur
+ Guwahati
Karachi
Lahore
Dhaka
@@ -584,6 +591,7 @@
Seoul
Busan
Pyongyang
+ Hamhung
Tokyo
Osaka
Fukuoka
diff --git a/app/src/test/java/io/github/acidefluorhydrique/mapconquer/world/MapAssetTest.kt b/app/src/test/java/io/github/acidefluorhydrique/mapconquer/world/MapAssetTest.kt
index 6d7540d..828904f 100644
--- a/app/src/test/java/io/github/acidefluorhydrique/mapconquer/world/MapAssetTest.kt
+++ b/app/src/test/java/io/github/acidefluorhydrique/mapconquer/world/MapAssetTest.kt
@@ -6,6 +6,7 @@ package io.github.acidefluorhydrique.mapconquer.world
import io.github.acidefluorhydrique.mapconquer.TestAssets
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
+import org.junit.Assert.assertNotEquals
import org.junit.Assert.assertTrue
import org.junit.Test
@@ -123,4 +124,55 @@ class MapAssetTest {
assertTrue("城市太少", world.provinces.count { it.hasCity } > 100)
assertTrue("首都級城市太少", world.provinces.count { it.cityTier >= 4 } >= 8)
}
+
+ @Test
+ fun `fingerprint is stable for the same map and differs between maps`() {
+ val ids = TestAssets.mapIds()
+ for (id in ids) {
+ assertEquals("$id: 同一份檔案讀兩次,指紋不同", TestAssets.map(id).fingerprint,
+ TestAssets.cachedMap(id).fingerprint)
+ }
+ val prints = ids.map { TestAssets.cachedMap(it).fingerprint }
+ assertEquals("兩張不同的地圖指紋相同", prints.size, prints.toSet().size)
+ }
+
+ @Test
+ fun `fingerprint notices a single changed tile`() {
+ val world = TestAssets.cachedMap("world")
+ val terrain = world.terrain.copyOf()
+ val tile = (0 until world.tileCount).first { world.isLand(it) }
+ terrain[tile] = (terrain[tile] + 1).toByte()
+ val edited = WorldMap(world.id, world.cols, world.rows, terrain, world.provinceOf,
+ world.provinces, world.wrapX)
+ assertNotEquals(world.fingerprint, edited.fingerprint)
+ }
+
+ /**
+ * 海峽兩岸的城市格在網格上曾經直接相鄰(釜山—福岡、佛羅里達—哈瓦那),
+ * 地圖上看起來隔著海,部隊卻走得過去。產生器現在有拓撲檢查
+ * (tools/topology.py),這裡在遊戲端的讀檔結果上再釘一次。
+ */
+ @Test
+ fun `straits on the world map are water all the way across`() {
+ val world = TestAssets.cachedMap("world")
+ val byKey = world.provinces.associateBy { it.nameKey }
+ val buf = IntArray(6)
+ fun landTouches(a: String, b: String): Boolean {
+ val pa = byKey.getValue(a)
+ val pb = byKey.getValue(b)
+ return pa.tiles.any { tile ->
+ val n = world.neighbours(tile, buf)
+ (0 until n).any { world.isLand(buf[it]) && world.provinceOf[buf[it]] == pb.id }
+ }
+ }
+ for ((a, b) in listOf(
+ "prov_busan" to "prov_fukuoka",
+ "prov_miami" to "prov_havana",
+ "prov_london" to "prov_paris",
+ "prov_helsinki" to "prov_riga",
+ "prov_taipei" to "prov_shanghai"
+ )) {
+ if (a in byKey && b in byKey) assertFalse("$a 與 $b 之間應該是海", landTouches(a, b))
+ }
+ }
}
diff --git a/tools/genstrings.py b/tools/genstrings.py
index fb2cd81..674131d 100644
--- a/tools/genstrings.py
+++ b/tools/genstrings.py
@@ -165,6 +165,8 @@
"toast_commander_cleared": ("Commander stood down", "已解除指揮官職務", "已解除指挥官职务"),
"toast_map_missing": ("That map could not be loaded", "地圖載入失敗", "地图加载失败"),
"toast_save_broken": ("The save file could not be read", "存檔無法讀取", "存档无法读取"),
+ "toast_save_outdated": ("That save was made on an older version of the map and can't be continued",
+ "這個存檔用的是舊版地圖,無法繼續", "这个存档用的是旧版地图,无法继续"),
# 事件
"event_city_captured": ("%1$s captured by %2$s", "%2$s 攻下 %1$s", "%2$s 攻下 %1$s"),
diff --git a/tools/genworld.py b/tools/genworld.py
index 8f3d971..5626397 100644
--- a/tools/genworld.py
+++ b/tools/genworld.py
@@ -18,6 +18,7 @@
import hexraster
import places
import scenarios as scn
+import topology
ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
MAPS_DIR = os.path.join(ROOT, "app", "src", "main", "assets", "maps")
@@ -48,8 +49,9 @@
( -56.0, -35.0, 0.60), # 南半球高緯
( -35.0, 0.0, 0.85), # 南美南部、南非、澳洲
( 0.0, 30.0, 1.00), # 熱帶
- ( 30.0, 60.0, 1.75), # 歐洲、日本、美國、中國
- ( 60.0, 78.0, 0.70), # 北極圈
+ ( 30.0, 66.0, 1.75), # 歐洲、北歐、日本、美國、中國
+ ( 66.0, 72.0, 1.00), # 北極圈:拉普蘭、摩爾曼斯克、阿拉斯加北岸
+ ( 72.0, 78.0, 0.30), # 極地冰原
]
MAP_DEFS = [
@@ -84,14 +86,19 @@ def __init__(self, map_id, grid, terrain, is_land, provinces):
self.province_of = None # 逐格的省份 id
-def nearest_land_tile(grid, is_land, lon, lat):
- """把一個經緯度座標吸附到最近的陸地格。找不到就回 None。"""
+def nearest_land_tile(grid, is_land, lon, lat, allowed=None):
+ """
+ 把一個經緯度座標吸附到最近的陸地格。找不到就回 None。
+
+ [allowed] 過濾候選格:城市只能落在自己那塊陸地上,否則福岡會被吸到
+ 對岸的釜山旁邊,只因為那一格在網格上比九州近。
+ """
best = None
best_d = None
for row in range(grid.rows):
for col in range(grid.cols):
i = grid.index(col, row)
- if not is_land[i]:
+ if not is_land[i] or (allowed is not None and not allowed(i)):
continue
glon, glat = grid.lonlat(col, row)
dlon = glon - lon
@@ -133,21 +140,35 @@ def assign_provinces(grid, is_land, seeds):
owner[j] = owner[tile]
frontier.append(j)
- # 沒被走到的陸地(離島)改用直線最近的種子。
+ # 沒被走到的陸地(沒有城市的離島)整座島歸給直線最近的種子。
+ # 以島為單位而不是逐格:逐格分的話,西西里這種夾在兩國之間的島會被
+ # 對半切給兩邊,憑空多出一條跨海的「國界」。
for i in range(count):
if not is_land[i] or owner[i] != -1:
continue
- col, row = i % grid.cols, i // grid.cols
- lon, lat = grid.lonlat(col, row)
- best, best_d = None, None
- for pid, tile in enumerate(seeds):
- if tile is None:
- continue
- slon, slat = grid.lonlat(tile % grid.cols, tile // grid.cols)
- d = (slon - lon) ** 2 + (slat - lat) ** 2
- if best_d is None or d < best_d:
- best_d, best = d, pid
- owner[i] = best if best is not None else -1
+ island = [i]
+ owner[i] = -2
+ head = 0
+ while head < len(island):
+ tile = island[head]
+ head += 1
+ for c, r in grid.neighbours(tile % grid.cols, tile // grid.cols):
+ j = grid.index(c, r)
+ if is_land[j] and owner[j] == -1:
+ owner[j] = -2
+ island.append(j)
+ best, best_d = -1, None
+ for tile in island:
+ lon, lat = grid.lonlat(tile % grid.cols, tile // grid.cols)
+ for pid, seed in enumerate(seeds):
+ if seed is None:
+ continue
+ slon, slat = grid.lonlat(seed % grid.cols, seed // grid.cols)
+ d = (slon - lon) ** 2 + (slat - lat) ** 2
+ if best_d is None or d < best_d:
+ best_d, best = d, pid
+ for tile in island:
+ owner[tile] = best
return owner
@@ -179,7 +200,7 @@ def build_map(map_id, cols, rows, lon_min, lon_max, lat_max, lat_min,
]
# 城市座標先於海岸線:每座城市所在的格子一定是陸地。
- terrain, is_land = hexraster.build_terrain(
+ terrain, is_land, landmass, _anchors = hexraster.build_terrain(
grid, [(p[1], p[2]) for p in candidates]
)
@@ -201,7 +222,9 @@ def build_map(map_id, cols, rows, lon_min, lon_max, lat_max, lat_min,
# 完全正常。省份數少一個,沒有任何一行輸出提到它。
dropped = []
for key, lon, lat, tier, nation, *_names in candidates:
- tile, dist = nearest_land_tile(grid, is_land, lon, lat)
+ home = hexraster.landmass_of(lon, lat)
+ tile, dist = nearest_land_tile(grid, is_land, lon, lat,
+ lambda i, home=home: not hexraster.apart(landmass[i], home))
if tile is None:
dropped.append((key, "這張地圖上沒有陸地"))
continue
@@ -215,7 +238,7 @@ def build_map(map_id, cols, rows, lon_min, lon_max, lat_max, lat_min,
col, row = tile % cols, tile // cols
for c, r in grid.neighbours(col, row):
j = grid.index(c, r)
- if is_land[j] and j not in used:
+ if is_land[j] and j not in used and not hexraster.apart(landmass[j], home):
tile = j
moved = True
break
@@ -797,6 +820,13 @@ def main():
print(" - %s 放不下:%s" % (key, reason))
world = built_maps["world"]
+ errors = topology.check(world)
+ if errors:
+ print("世界地圖的拓撲檢查失敗(見 tools/topology.py):", file=sys.stderr)
+ for line in errors:
+ print(" " + line, file=sys.stderr)
+ sys.exit(1)
+
print(write_conquest(world, "conquest_1939", "scn_conquest_1939",
"scn_conquest_1939_desc", 10, places.WW2_MERGE, 1939,
turtle=places.WW2_NEUTRALS, blocs=places.WW2_BLOCS,
diff --git a/tools/geodata.py b/tools/geodata.py
index 17ff569..5858bdd 100644
--- a/tools/geodata.py
+++ b/tools/geodata.py
@@ -24,7 +24,7 @@
(-2.2, 35.4), (0.0, 36.2), (3.4, 37.2), (6.5, 37.3), (8.6, 37.4),
(10.8, 37.4), (11.3, 34.5), (13.6, 33.2), (15.0, 32.4),
(19.0, 30.3), (25.0, 31.6), (29.9, 31.2), (32.5, 31.1), (34.5, 28.0),
- (37.0, 22.0), (39.0, 15.0), (43.0, 12.5), (48.0, 11.5), (51.4, 11.8),
+ (37.0, 22.0), (39.0, 15.0), (43.2, 11.9), (44.5, 10.5), (47.0, 11.1), (49.5, 11.3), (51.3, 11.9),
(48.0, 5.0), (44.0, 1.0), (41.8, -2.0), (40.5, -6.0), (40.0, -10.5),
(35.5, -17.0), (35.0, -21.0), (32.5, -25.5), (31.0, -29.5), (27.5, -33.5),
(22.0, -34.0), (18.4, -34.4), (16.0, -28.5), (14.5, -22.0), (11.7, -15.8),
@@ -48,6 +48,23 @@
(21.5, 63.5), (24.0, 65.8), (27.0, 68.5), (31.0, 69.8), (24.0, 71.2), (18.0, 70.0),
(14.0, 68.0), (11.0, 64.0), (5.0, 62.0), (4.5, 59.5),
],
+ # 日德蘭半島原本也沒有多邊形:europe 的北岸停在北緯 54.5,丹麥只剩
+ # 城市錨點那一格,跟德國之間隔著一排海。
+ "jutland": [
+ (8.6, 54.3), (10.0, 54.3), (10.0, 54.8), (9.7, 55.2), (10.2, 55.8),
+ (10.9, 56.4), (10.3, 56.9), (10.6, 57.7), (10.0, 57.6), (8.6, 57.1),
+ (8.1, 56.6), (8.1, 55.5), (8.6, 54.9),
+ ],
+ # 芬蘭原本沒有自己的多邊形:斯堪地那維亞的東緣沿著波的尼亞灣往北走,
+ # europe 的西緣從聖彼得堡往北走,兩者之間北緯 60–67、東經 21–29 整片是
+ # 空白 —— 芬蘭本土柵格化出來是海,赫爾辛基只剩錨點那一格,其餘的地被
+ # 聖彼得堡與莫曼斯克吃掉。
+ "finland": [
+ (21.3, 60.4), (22.5, 60.0), (25.0, 60.1), (27.5, 60.5), (29.8, 61.1),
+ (31.5, 62.9), (30.0, 64.8), (29.6, 66.8), (29.3, 69.0), (28.5, 70.0),
+ (26.0, 69.9), (24.0, 68.8), (21.0, 69.2), (23.8, 67.2), (24.2, 65.9),
+ (25.4, 65.0), (24.5, 64.8), (22.0, 63.5), (21.3, 62.3), (21.5, 61.2),
+ ],
"siberia": [
(60.0, 66.0), (55.0, 68.5), (60.0, 70.5), (70.0, 72.5), (78.0, 73.0),
(86.0, 74.5), (100.0, 76.0), (110.0, 76.5), (113.0, 73.5), (129.0, 73.5),
@@ -108,8 +125,8 @@
"india": [
(68.0, 24.0), (72.0, 21.0), (73.0, 15.5), (77.5, 8.2), (80.3, 13.0),
(82.0, 17.0), (87.0, 21.5), (90.0, 22.0), (92.0, 21.5), (94.0, 24.0),
- (97.5, 28.0), (92.0, 28.0), (88.0, 27.5), (84.0, 28.5), (80.0, 30.0),
- (76.0, 32.5), (72.0, 29.0), (68.5, 26.5),
+ (97.5, 28.0), (92.0, 28.0), (88.0, 27.5), (84.0, 28.5), (82.5, 30.4),
+ (79.0, 33.2), (77.8, 35.3), (76.0, 33.0), (72.0, 29.0), (68.5, 26.5),
],
"indochina": [
(97.0, 17.0), (100.5, 20.0), (105.0, 22.5), (108.5, 21.5), (109.5, 15.0),
@@ -119,16 +136,42 @@
"malaya": [
(100.5, 6.5), (103.5, 5.5), (104.2, 1.4), (102.5, 1.6), (100.2, 5.5),
],
- "middle_east": [
- (26.0, 32.0), (35.0, 36.5), (38.0, 37.5), (44.0, 37.5), (48.0, 38.5),
- (53.0, 38.0), (56.0, 37.5), (61.0, 36.0), (62.0, 29.0), (61.0, 25.2),
- (57.0, 25.5), (56.5, 24.0), (52.0, 24.0), (48.5, 29.5), (47.0, 30.0),
- (43.0, 30.0), (39.0, 29.0), (35.0, 29.0), (34.0, 31.0),
+ # 原本是一整塊 middle_east,從利比亞外海的 (26, 32) 起筆 —— 黎凡特海
+ # 被畫成陸地,亞歷山卓的省一路長到敘利亞。它的南緣又跟 arabia 在荷莫茲
+ # 疊在一起,伊朗、阿曼、阿聯之間全是陸路。拆成黎凡特與伊朗兩塊,
+ # 海岸各自沿著真實的海岸線走,阿拉伯半島跟誰不能相連交給 SEAS。
+ "levant": [
+ (34.2, 31.3), (34.9, 32.8), (35.5, 34.5), (35.9, 35.9), (36.2, 36.7),
+ (38.0, 37.5), (42.0, 37.2), (44.8, 37.2), (45.5, 35.0), (46.2, 33.0),
+ (47.5, 31.5), (48.6, 30.0), (48.0, 29.9), (47.0, 30.0), (43.0, 30.0),
+ (39.0, 29.0), (35.0, 29.0), (34.9, 29.5),
+ ],
+ "sinai": [
+ (32.3, 31.2), (34.2, 31.3), (34.9, 29.5), (34.3, 27.8), (33.5, 28.3),
+ (32.6, 29.9),
+ ],
+ "iran": [
+ (44.8, 37.2), (44.3, 39.4), (48.0, 38.5), (53.0, 38.0), (56.0, 37.5),
+ (61.0, 36.0), (62.0, 29.0), (61.6, 25.2), (58.8, 25.5), (57.3, 25.8),
+ (56.4, 27.1), (54.5, 26.6), (52.5, 27.4), (51.0, 28.8), (50.2, 30.0),
+ (48.6, 30.0), (47.5, 31.5), (46.2, 33.0), (45.5, 35.0),
],
"arabia": [
- (34.5, 28.0), (39.0, 21.0), (43.0, 13.0), (45.0, 12.8), (52.0, 16.0),
- (56.0, 21.0), (57.0, 25.0), (52.0, 24.0), (48.5, 29.5), (46.0, 29.5),
- (41.0, 31.0), (38.0, 30.0),
+ (34.9, 29.5), (34.8, 28.1), (36.5, 25.5), (39.0, 21.5), (41.5, 17.5),
+ (43.2, 13.3), (45.0, 12.9), (48.5, 14.0), (52.2, 15.7), (55.0, 17.3),
+ (57.0, 18.9), (59.0, 20.5), (59.8, 22.5), (58.6, 23.6), (57.0, 24.0),
+ (56.3, 24.9), (56.2, 25.7), (55.4, 25.3), (54.0, 24.2), (52.0, 24.0),
+ (51.6, 25.2), (51.0, 24.6), (50.0, 26.0), (49.0, 27.5), (48.3, 28.7),
+ (47.7, 29.4), (46.0, 29.2), (41.0, 31.0), (38.0, 30.0),
+ ],
+ # 印度河流域原本沒有任何多邊形蓋到:afghanistan 的東緣、india 的西緣、
+ # china 的西南緣之間是一條南北向的空白,柵格化出來是一道海,巴基斯坦
+ # 被切成喀拉蚩與拉合爾兩座孤城,俾路支整片歸給喀布爾。
+ "pakistan": [
+ (61.6, 25.2), (64.0, 25.3), (66.7, 25.4), (67.2, 24.8), (68.3, 23.7),
+ (70.5, 24.4), (71.2, 27.8), (74.0, 30.0), (74.8, 32.5), (76.0, 34.0),
+ (77.5, 35.5), (75.5, 37.0), (71.5, 36.8), (70.0, 34.2), (69.3, 31.5),
+ (66.5, 29.8), (63.0, 29.4), (61.8, 28.0),
],
"afghanistan": [
(60.5, 29.5), (70.0, 30.0), (74.5, 36.5), (69.0, 38.5), (62.0, 36.0),
@@ -225,6 +268,56 @@
"tasmania": [(144.5, -40.5), (148.3, -40.7), (148.0, -43.5), (145.0, -43.0)],
}
+# 島嶼:跟其他任何陸地之間一定隔著海的多邊形群組。
+#
+# 海峽折線(見下)只挖得到一條線上的格子,而且城市格挖不到 —— 兩岸的城市
+# 格一旦在網格上貼在一起,海峽就被一座「陸橋」跨過去:釜山與福岡就是這樣
+# 接起來的,日本的部隊可以直接走進韓國。這張表是規則而不是線:同一群組
+# 內的格子彼此相連,群組以外的陸地一格都不能碰到它(見 hexraster.separate_landmasses)。
+#
+# 鍵是群組名,值是 LAND 裡的多邊形名。沒列在這裡的多邊形都屬於大陸。
+# 西西里刻意不列:墨西拿海峽只有三公里,在這個尺度下它就是義大利的腳尖。
+ISLANDS = {
+ "britain": ["britain"],
+ "ireland": ["ireland"],
+ "iceland": ["iceland"],
+ "sardinia": ["sardinia"],
+ "crete": ["crete"],
+ "japan": ["japan_honshu", "japan_kyushu", "japan_shikoku"],
+ "sakhalin": ["sakhalin"],
+ "taiwan": ["taiwan"],
+ "philippines": ["philippines"],
+ "sumatra": ["sumatra"],
+ "java": ["java"],
+ "borneo": ["borneo"],
+ "sulawesi": ["sulawesi"],
+ "new_guinea": ["new_guinea"],
+ "australia": ["australia"],
+ "tasmania": ["tasmania"],
+ "new_zealand": ["new_zealand"],
+ "sri_lanka": ["sri_lanka"],
+ "madagascar": ["madagascar"],
+ "cuba": ["cuba"],
+ "hispaniola": ["hispaniola"],
+ "newfoundland": ["newfoundland"],
+ "greenland": ["greenland"],
+}
+
+# 兩兩之間一定隔著海的大陸多邊形。
+#
+# 島嶼規則管不到這種情況:阿拉伯半島經由伊拉克、約旦跟歐亞大陸相連,
+# 它不是島;但它跟非洲之間隔著紅海與曼德海峽,跟伊朗之間隔著荷莫茲,
+# 跟南亞之間隔著阿拉伯海。這些海在網格上往往只有零到一格寬,城市格
+# 一貼過去就成了陸橋 —— 葉門的省長到索馬利亞、阿曼的省長到巴基斯坦。
+SEAS = [
+ ("arabia", "africa"),
+ ("arabia", "sinai"),
+ ("arabia", "iran"),
+ ("arabia", "india"),
+ ("arabia", "afghanistan"),
+ ("arabia", "pakistan"),
+]
+
# 海峽。
#
# 這些是折線,不是多邊形:柵格化的時候沿著線把最近的格子強制成水,
@@ -239,6 +332,8 @@
"gibraltar": [(-7.6, 35.9), (-5.6, 35.9), (-3.0, 36.0)],
"danish_straits": [(7.0, 57.6), (10.0, 57.4), (12.6, 55.8), (14.6, 55.2)],
"turkish_straits": [(25.8, 39.9), (27.2, 40.4), (28.6, 40.6), (29.4, 41.2)],
+ # 芬蘭灣:赫爾辛基與塔林只差不到一度緯度,多邊形在這個尺度下留不住海。
+ "gulf_of_finland": [(22.0, 59.75), (25.0, 59.75), (28.5, 59.95)],
"korea_strait": [(127.0, 33.2), (129.3, 34.0), (131.8, 34.2)],
"malacca": [(97.5, 6.2), (100.5, 3.0), (103.6, 0.6), (105.5, -1.5)],
"formosa_strait": [(118.5, 24.5), (119.5, 25.5)],
@@ -258,8 +353,18 @@
],
"caspian": [(47.5, 37.5), (54.0, 38.0), (53.5, 45.0), (48.5, 46.5), (47.0, 42.0)],
"red_sea": [(43.0, 12.5), (35.0, 28.5), (33.5, 28.5), (38.0, 20.0), (41.5, 12.5)],
- "persian_gulf": [(48.5, 30.0), (56.5, 26.5), (56.0, 24.6), (50.0, 27.5), (47.8, 29.6)],
- "baltic": [(12.0, 54.2), (21.0, 55.0), (25.5, 59.0), (24.0, 60.5), (19.0, 60.5), (17.0, 57.0), (12.5, 55.5)],
+ "persian_gulf": [
+ (48.6, 29.9), (50.3, 29.2), (52.5, 27.3), (54.5, 26.5), (56.2, 26.4),
+ (56.0, 25.8), (54.5, 25.0), (52.5, 25.3), (51.2, 26.2), (50.2, 27.0),
+ (49.0, 28.3), (48.2, 29.2),
+ ],
+ "baltic": [(12.0, 54.2), (21.0, 55.0), (23.5, 58.8), (22.0, 59.8), (19.0, 60.3), (17.0, 57.0), (12.5, 55.5)],
+ # 瑞典與芬蘭之間的海。沒有它,兩國在整條波的尼亞灣上都是陸地相接。
+ "gulf_of_bothnia": [
+ (18.9, 60.3), (21.2, 60.5), (21.3, 62.2), (22.0, 63.4), (24.4, 64.7),
+ (25.3, 65.1), (24.1, 65.8), (22.3, 65.6), (21.0, 64.5), (18.8, 63.0),
+ (17.5, 61.3),
+ ],
"north_sea": [(-2.0, 51.8), (8.0, 54.2), (6.0, 58.0), (0.0, 58.5), (-2.0, 55.0)],
"hudson_bay": [(-95.0, 58.0), (-80.0, 58.0), (-78.0, 62.5), (-82.0, 65.0), (-92.0, 64.0)],
"gulf_of_california": [(-114.5, 31.0), (-109.0, 23.0), (-110.5, 23.0), (-114.0, 29.0)],
diff --git a/tools/hexraster.py b/tools/hexraster.py
index 28d868e..2a514f7 100644
--- a/tools/hexraster.py
+++ b/tools/hexraster.py
@@ -192,8 +192,142 @@ def polyline_cells(grid, points, step=0.12):
return cells
+def _island_by_polygon():
+ out = {}
+ for group, names in geodata.ISLANDS.items():
+ for name in names:
+ out[name] = group
+ return out
+
+
+_ISLAND_OF = _island_by_polygon()
+_SEAS = {frozenset(pair) for pair in geodata.SEAS}
+
+
+def apart(a, b):
+ """
+ 兩個陸地多邊形之間是否一定隔著海。
+
+ 島嶼群組只跟同群組相連;[geodata.SEAS] 列出的大陸多邊形兩兩不相連;
+ 其餘的大陸多邊形彼此相連(歐洲與斯堪地那維亞、中國與朝鮮)。
+ """
+ if a == b:
+ return False
+ ga, gb = _ISLAND_OF.get(a), _ISLAND_OF.get(b)
+ if ga is not None or gb is not None:
+ return ga != gb
+ return frozenset((a, b)) in _SEAS
+
+
+def _ring_distance(lon, lat, polygon):
+ if point_in_polygon(lon, lat, polygon):
+ return 0.0
+ return distance_to_polyline(lon, lat, list(polygon) + [polygon[0]])
+
+
+def landmass_of(lon, lat):
+ """
+ 一個點屬於哪個陸地多邊形([geodata.LAND] 的鍵)。
+
+ 落在好幾個多邊形裡時以大陸為準 —— 薩哈林的多邊形跟西伯利亞有重疊,
+ 重疊處算西伯利亞,島嶼規則只管真正獨立的那一塊。都不在的點
+ (城市錨點常常落在手繪海岸線外面一點)取最近的多邊形。
+ """
+ best_name, best_d = None, None
+ for name, polygon in geodata.LAND.items():
+ d = _ring_distance(lon, lat, polygon)
+ if d == 0.0 and name not in _ISLAND_OF:
+ return name
+ if best_d is None or d < best_d:
+ best_name, best_d = name, d
+ return best_name
+
+
+def separate_landmasses(grid, is_land, landmass, kept):
+ """
+ 讓每一對 [apart] 的陸地之間至少隔一格海。
+
+ 兩格相鄰卻屬於不該相連的陸地時挖掉一格:先挖不是城市的那一格;
+ 兩格都不是城市時,島嶼對大陸挖大陸那一側(島嶼格子稀缺,日本全部
+ 也就十幾格),否則挖格子多的那一塊。兩格都是城市時,把其中一座城
+ (島上的優先)搬到同一塊陸地上最近、且四周沒有對岸陸地的格子 ——
+ 城市座標只是錨點,站在哪一格是這裡決定的。
+
+ [kept] 是 {格子: 城市經緯度},搬家時一併更新。
+ """
+ size = {}
+ for i, name in enumerate(landmass):
+ if is_land[i]:
+ size[name] = size.get(name, 0) + 1
+
+ def neighbours(i):
+ return [grid.index(c, r) for c, r in grid.neighbours(i % grid.cols, i // grid.cols)]
+
+ def touches_across(i, ignore=None):
+ return any(
+ k != ignore and is_land[k] and apart(landmass[k], landmass[i])
+ for k in neighbours(i)
+ )
+
+ def relocate(tile):
+ lon0, lat0 = grid.lonlat(tile % grid.cols, tile // grid.cols)
+ best, best_d = None, None
+ for j in range(len(is_land)):
+ if j == tile or not is_land[j] or j in kept:
+ continue
+ if apart(landmass[j], landmass[tile]) or touches_across(j, ignore=tile):
+ continue
+ lon, lat = grid.lonlat(j % grid.cols, j // grid.cols)
+ d = (lon - lon0) ** 2 + (lat - lat0) ** 2
+ if best_d is None or d < best_d:
+ best, best_d = j, d
+ if best is None:
+ raise ValueError("找不到能安置城市 %r 的格子" % (kept[tile],))
+ kept[best] = kept.pop(tile)
+ landmass[best] = landmass[tile]
+ is_land[tile] = False
+
+ def bigger(i, j):
+ return i if size.get(landmass[i], 0) >= size.get(landmass[j], 0) else j
+
+ changed = True
+ while changed:
+ changed = False
+ for i in range(len(is_land)):
+ if not is_land[i]:
+ continue
+ for j in neighbours(i):
+ if not is_land[i]:
+ break
+ if not is_land[j] or not apart(landmass[i], landmass[j]):
+ continue
+ island_i = landmass[i] in _ISLAND_OF
+ island_j = landmass[j] in _ISLAND_OF
+ if (i in kept) != (j in kept):
+ victim = j if i in kept else i
+ elif i in kept:
+ relocate(i if island_i or not island_j else j)
+ changed = True
+ continue
+ elif island_i != island_j:
+ victim = j if island_i else i
+ else:
+ victim = bigger(i, j)
+ is_land[victim] = False
+ changed = True
+ # 防呆:跑完之後不應該還有任何一對不該相連的陸地相鄰。
+ for i in range(len(is_land)):
+ if is_land[i] and touches_across(i):
+ raise AssertionError("陸塊分離沒有收斂:格子 %d" % i)
+
+
def build_terrain(grid, anchors=()):
- """回傳 (terrain_codes, is_land),兩者都是逐格的一維串列。"""
+ """
+ 回傳 (terrain_codes, is_land, landmass, anchor_tiles),前三者是逐格的一維串列。
+
+ landmass 是每一格所屬的陸地多邊形(見 [landmass_of]),海洋格是 None。
+ anchor_tiles 是 {城市經緯度: 格子},陸塊分離搬過家的城市以它為準。
+ """
land_polys = list(geodata.LAND.values())
sea_polys = list(geodata.SEA.values())
desert_polys = list(geodata.DESERTS.values())
@@ -221,6 +355,19 @@ def build_terrain(grid, anchors=()):
if i not in kept:
is_land[i] = False
+ # 城市格的陸塊看城市本身,不看格子中心:格子中心可能落在對岸。
+ landmass = [None] * count
+ for i in range(count):
+ if not is_land[i]:
+ continue
+ lon, lat = kept[i] if i in kept else lonlat[i]
+ landmass[i] = landmass_of(lon, lat)
+ separate_landmasses(grid, is_land, landmass, kept)
+ for i in range(count):
+ if not is_land[i]:
+ landmass[i] = None
+ anchor_tiles = {coord: tile for tile, coord in kept.items()}
+
terrain = ['~'] * count
for row in range(grid.rows):
for col in range(grid.cols):
@@ -235,7 +382,7 @@ def build_terrain(grid, anchors=()):
apply_mountains(grid, terrain, is_land, lonlat)
apply_rivers(grid, terrain, is_land, lonlat)
- return terrain, is_land
+ return terrain, is_land, landmass, anchor_tiles
def classify_land(lon, lat, desert_polys, jungle_polys, farm_polys):
diff --git a/tools/places.py b/tools/places.py
index f730d06..63f6fb9 100644
--- a/tools/places.py
+++ b/tools/places.py
@@ -48,9 +48,14 @@
("prov_sofia", 23.3, 42.7, 1, "BGR", "Sofia", "索菲亞", "索菲亚"),
("prov_athens", 23.7, 38.0, 2, "GRC", "Athens", "雅典", "雅典"),
("prov_stockholm", 18.1, 59.3, 2, "SWE", "Stockholm", "斯德哥爾摩", "斯德哥尔摩"),
+ ("prov_gothenburg", 12.0, 57.7, 1, "SWE", "Gothenburg", "哥德堡", "哥德堡"),
+ ("prov_sundsvall", 17.3, 62.4, 1, "SWE", "Sundsvall", "松茲瓦爾", "松兹瓦尔"),
+ ("prov_kiruna", 20.2, 67.9, 1, "SWE", "Kiruna", "基律納", "基律纳"),
("prov_oslo", 10.7, 59.9, 2, "NOR", "Oslo", "奧斯陸", "奥斯陆"),
("prov_copenhagen", 12.6, 55.7, 2, "DNK", "Copenhagen", "哥本哈根", "哥本哈根"),
+ ("prov_aarhus", 10.2, 56.2, 1, "DNK", "Aarhus", "奧胡斯", "奥胡斯"),
("prov_helsinki", 25.0, 60.2, 2, "FIN", "Helsinki", "赫爾辛基", "赫尔辛基"),
+ ("prov_oulu", 25.5, 65.0, 1, "FIN", "Oulu", "奧盧", "奥卢"),
("prov_riga", 24.1, 56.9, 1, "LVA", "Riga", "里加", "里加"),
("prov_reykjavik", -21.9, 64.1, 1, "ISL", "Reykjavik", "雷克雅維克", "雷克雅未克"),
("prov_narvik", 17.4, 68.4, 1, "NOR", "Narvik", "納爾維克", "纳尔维克"),
@@ -150,6 +155,7 @@
("prov_bangalore", 77.6, 13.0, 2, "IND", "Bengaluru", "邦加羅爾", "班加罗尔"),
("prov_hyderabad", 78.5, 17.4, 2, "IND", "Hyderabad", "海得拉巴", "海得拉巴"),
("prov_nagpur", 79.1, 21.1, 1, "IND", "Nagpur", "那格浦爾", "那格浦尔"),
+ ("prov_guwahati", 91.7, 26.1, 1, "IND", "Guwahati", "古瓦哈提", "古瓦哈蒂"),
("prov_karachi", 67.0, 24.9, 3, "PAK", "Karachi", "喀拉蚩", "卡拉奇"),
("prov_lahore", 74.3, 31.5, 2, "PAK", "Lahore", "拉合爾", "拉合尔"),
("prov_dhaka", 90.4, 23.8, 2, "BGD", "Dhaka", "達卡", "达卡"),
@@ -177,6 +183,7 @@
("prov_seoul", 127.0, 37.6, 3, "KOR", "Seoul", "首爾", "首尔"),
("prov_busan", 129.1, 35.2, 2, "KOR", "Busan", "釜山", "釜山"),
("prov_pyongyang", 125.8, 39.0, 2, "PRK", "Pyongyang", "平壤", "平壤"),
+ ("prov_hamhung", 127.5, 39.9, 1, "PRK", "Hamhung", "咸興", "咸兴"),
("prov_tokyo", 139.7, 35.7, 4, "JPN", "Tokyo", "東京", "东京"),
("prov_osaka", 135.5, 34.7, 3, "JPN", "Osaka", "大阪", "大阪"),
("prov_fukuoka", 130.4, 33.6, 2, "JPN", "Fukuoka", "福岡", "福冈"),
@@ -502,7 +509,7 @@
WW2_1943_PROVINCE_OWNERS.update({
# 德國:法國全境(1942 年 11 月之後)、低地國、北歐、波蘭、巴爾幹、蘇聯西部
"prov_paris": "DEU", "prov_lyon": "DEU", "prov_bordeaux": "DEU",
- "prov_amsterdam": "DEU", "prov_brussels": "DEU", "prov_copenhagen": "DEU",
+ "prov_amsterdam": "DEU", "prov_brussels": "DEU", "prov_copenhagen": "DEU", "prov_aarhus": "DEU",
"prov_oslo": "DEU", "prov_narvik": "DEU",
"prov_warsaw": "DEU", "prov_krakow": "DEU",
"prov_belgrade": "DEU", "prov_athens": "DEU",
diff --git a/tools/scenarios.py b/tools/scenarios.py
index 189eba2..9365c58 100644
--- a/tools/scenarios.py
+++ b/tools/scenarios.py
@@ -59,7 +59,7 @@
"DEU": ["prov_berlin", "prov_hamburg", "prov_munich", "prov_cologne",
"prov_prague", "prov_vienna"],
"RUS": ["prov_moscow", "prov_minsk", "prov_riga"],
- "SWE": ["prov_stockholm"],
+ "SWE": ["prov_stockholm", "prov_gothenburg"],
},
"blocs": {"AXIS": ["DEU"], "ALLIES": ["POL"]},
"funds": {"POL": 700, "DEU": 1500, "RUS": 600, "SWE": 400},
@@ -306,7 +306,7 @@
"GBR": ["prov_london", "prov_manchester", "prov_edinburgh"],
"NLD": ["prov_amsterdam"],
"BEL": ["prov_brussels"],
- "DNK": ["prov_copenhagen"],
+ "DNK": ["prov_copenhagen", "prov_aarhus"],
"RUS": ["prov_moscow", "prov_petersburg", "prov_rostov"],
"POL": ["prov_warsaw", "prov_krakow"],
"CZE": ["prov_prague"],
@@ -314,7 +314,7 @@
"DDR": ["prov_berlin"],
"CHE": ["prov_zurich"],
"AUT": ["prov_vienna"],
- "SWE": ["prov_stockholm"],
+ "SWE": ["prov_stockholm", "prov_gothenburg"],
"IRL": ["prov_dublin"],
},
"blocs": {"NATO": NATO_85, "PACT": PACT_85},
diff --git a/tools/topology.py b/tools/topology.py
new file mode 100644
index 0000000..48b8254
--- /dev/null
+++ b/tools/topology.py
@@ -0,0 +1,114 @@
+# SPDX-FileCopyrightText: 2026 AcideFluorhydrique
+# SPDX-License-Identifier: GPL-3.0-or-later
+"""
+世界地圖的拓撲檢查:哪些國家之間該有陸路、哪些之間一定隔著海。
+
+世界地圖是刻意變形的(歐洲、日本放大,兩大洋壓扁,見 genworld 的分段權重),
+變形本身不會改變拓撲 —— 經緯度對格子的映射在兩個軸上都是單調的。會改壞拓撲
+的是別的東西:手繪多邊形之間留了縫(芬蘭、印度河流域曾經整片是海)、海峽窄
+到網格上只剩零格(釜山與福岡相鄰,日本的部隊可以走進韓國)、省份從太少的
+城市往外長,長過了國界。這些錯誤在產出的檔案裡完全看不出來,只有玩起來才會
+發現國家擺錯了地方。
+
+所以把地理事實寫成兩張表,每次產生地圖都驗一遍,錯了就讓產生器失敗:
+
+- LAND_BORDERS:真實世界裡接壤、地圖上也必須有陸路相接的國家。
+- SEA_BETWEEN:真實世界裡隔著海、地圖上絕對不能陸地相鄰的國家。
+
+兩張表都用現代國家代碼,對應 places.PROVINCES 的歸屬 —— 劇本會把國家合併
+(1939 年朝鮮歸日本),但地理是合併之前的事。沒有城市的國家不在地圖上,
+它的鄰國在地圖上直接相接是預期中的(沒有約旦,以色列就跟沙烏地接壤),
+所以表裡只收兩邊都有城市的配對。
+"""
+
+LAND_BORDERS = [
+ # 北歐:芬蘭夾在瑞典與俄羅斯之間,不是一塊浮在波羅的海上的地。
+ ("FIN", "SWE"), ("FIN", "RUS"), ("NOR", "SWE"),
+ # 西歐與中歐
+ ("ESP", "FRA"), ("ESP", "PRT"), ("FRA", "BEL"), ("FRA", "DEU"),
+ ("FRA", "CHE"), ("FRA", "ITA"), ("DEU", "POL"), ("DEU", "NLD"),
+ ("DEU", "DNK"), ("DEU", "CZE"), ("DEU", "AUT"), ("POL", "UKR"),
+ ("POL", "BLR"), ("RUS", "UKR"), ("RUS", "BLR"),
+ # 中東與南亞
+ ("EGY", "ISR"), ("EGY", "LBY"), ("EGY", "SDN"), ("IRQ", "IRN"),
+ ("IRQ", "SAU"), ("IRQ", "SYR"), ("SAU", "YEM"), ("ARE", "SAU"),
+ ("ARE", "OMN"), ("IRN", "TUR"), ("IRN", "AFG"), ("IRN", "PAK"),
+ ("AFG", "PAK"), ("IND", "PAK"), ("IND", "CHN"), ("IND", "NPL"),
+ ("IND", "BGD"), ("IND", "MMR"),
+ # 東亞:朝鮮半島接在中國身上。
+ ("KOR", "PRK"), ("PRK", "CHN"), ("CHN", "RUS"), ("CHN", "MNG"),
+ ("CHN", "VNM"),
+ # 美洲。巴西與阿根廷只在米西奧內斯接壤,一度寬,這個解析度下由
+ # 巴拉圭與烏拉圭隔開是可以接受的,不列。
+ ("CAN", "USA"), ("USA", "MEX"), ("ARG", "CHL"),
+]
+
+SEA_BETWEEN = [
+ # 島國對大陸
+ ("GBR", "FRA"), ("GBR", "IRL"), ("GBR", "BEL"), ("GBR", "NLD"),
+ ("JPN", "KOR"), ("JPN", "PRK"), ("JPN", "CHN"), ("JPN", "RUS"),
+ ("TWN", "CHN"), ("LKA", "IND"), ("CUB", "USA"), ("MDG", "MOZ"),
+ ("AUS", "IDN"), ("AUS", "PNG"), ("NZL", "AUS"), ("PHL", "CHN"),
+ ("PHL", "MYS"), ("ISL", "GBR"), ("ISL", "NOR"),
+ # 波羅的海與北海:芬蘭灣、波的尼亞灣、斯卡格拉克。
+ ("FIN", "LVA"), ("FIN", "BLR"), ("SWE", "LVA"), ("SWE", "POL"),
+ ("SWE", "DEU"), ("NOR", "DNK"),
+ # 地中海
+ ("ITA", "TUN"), ("ITA", "LBY"), ("ESP", "MAR"), ("GRC", "EGY"),
+ ("GRC", "LBY"), ("TUR", "EGY"), ("SYR", "EGY"),
+ # 紅海、曼德海峽、荷莫茲、阿拉伯海
+ ("SAU", "SDN"), ("SAU", "EGY"), ("YEM", "ETH"), ("YEM", "SOM"),
+ ("ARE", "IRN"), ("OMN", "IRN"), ("OMN", "PAK"), ("OMN", "IND"),
+ ("SAU", "IRN"),
+]
+
+
+def _neighbours(grid, tile, wrap):
+ col, row = tile % grid.cols, tile // grid.cols
+ odd = row % 2
+ for dc, dr in ((1, 0), (-1, 0),
+ (1 if odd else 0, -1), (0 if odd else -1, -1),
+ (1 if odd else 0, 1), (0 if odd else -1, 1)):
+ c, r = col + dc, row + dr
+ if not 0 <= r < grid.rows:
+ continue
+ if wrap:
+ c %= grid.cols
+ elif not 0 <= c < grid.cols:
+ continue
+ yield grid.index(c, r)
+
+
+def nation_land_borders(built, wrap):
+ """{(A, B): 相鄰的格子邊數},A < B,以 places 的國家歸屬計算。"""
+ nation = [p[2] for p in built.provinces]
+ out = {}
+ for tile, land in enumerate(built.is_land):
+ if not land:
+ continue
+ a = nation[built.province_of[tile]]
+ for other in _neighbours(built.grid, tile, wrap):
+ if not built.is_land[other]:
+ continue
+ b = nation[built.province_of[other]]
+ if a < b:
+ out[(a, b)] = out.get((a, b), 0) + 1
+ return out
+
+
+def check(built, wrap=True):
+ """回傳違規說明的串列;空串列代表通過。"""
+ present = {p[2] for p in built.provinces}
+ borders = nation_land_borders(built, wrap)
+
+ def touching(a, b):
+ return borders.get((min(a, b), max(a, b)), 0) > 0
+
+ errors = []
+ for a, b in LAND_BORDERS:
+ if a in present and b in present and not touching(a, b):
+ errors.append("%s 與 %s 應該陸地接壤,地圖上卻不相連" % (a, b))
+ for a, b in SEA_BETWEEN:
+ if a in present and b in present and touching(a, b):
+ errors.append("%s 與 %s 之間應該隔著海,地圖上卻陸地相鄰" % (a, b))
+ return errors
From 694ddfc794d5c19e72e5eeb298a1faa83905f20b Mon Sep 17 00:00:00 2001
From: AcideFluorhydrique
<139669368+AcideFluorhydrique@users.noreply.github.com>
Date: Tue, 22 Sep 2026 15:42:42 +0800
Subject: [PATCH 02/11] Make losing your last city a surrender, and win
conquest by taking enemy cities
This follows the reference game's observable rules, written down in the new
docs/original-behavior.md together with what is still unknown about them.
A nation that loses its last city surrenders on the spot. Every unit it has
left disappears, including ships at sea and troops deep in someone else's
land, and whatever provinces it still holds go to the nation that took that
last city. Before, a nation was only gone once it had no provinces and no
units at all, so a beaten country lingered for as long as one destroyer was
still afloat somewhere. A nation that never had a city is unaffected and
still disappears only when it has nothing left.
Conquest is won by taking every city of every enemy: the members of the
opposing bloc, plus anyone you are at war with, such as a neutral you
declared war on. Allies and neutrals you left alone do not count. Since an
enemy surrenders with its last city, "every enemy has surrendered" and
"every enemy city is taken" are the same test. The old fallback of holding
80% of the world is gone; it could only be met by fighting allies and
neutrals. With no enemy at all there is no conquest victory; you have to
declare war first.
The objectives panel, the event ticker, the README and the store listing say
the same thing. Tests cover a surrender with a leftover province and a ship,
a lost city that was not the last, a win that leaves a neutral alone, a
declared-on neutral that must be beaten too, and a map with no enemy.
---
README.md | 3 +-
README.zh.md | 2 +-
.../mapconquer/game/Session.kt | 71 +++++---
.../mapconquer/render/PanelRenderer.kt | 4 +-
app/src/main/res/values-b+zh+Hans/strings.xml | 5 +-
app/src/main/res/values-b+zh+Hant/strings.xml | 5 +-
app/src/main/res/values/strings.xml | 5 +-
.../mapconquer/game/SessionTest.kt | 146 ++++++++++++++++
docs/original-behavior.md | 160 ++++++++++++++++++
.../android/en-US/full_description.txt | 3 +-
.../android/zh-CN/full_description.txt | 2 +-
.../android/zh-TW/full_description.txt | 2 +-
tools/genstrings.py | 11 +-
13 files changed, 380 insertions(+), 39 deletions(-)
create mode 100644 docs/original-behavior.md
diff --git a/README.md b/README.md
index 6957fe2..172c763 100644
--- a/README.md
+++ b/README.md
@@ -16,7 +16,8 @@ Two modes:
that has to be taken by sea and air, a defensive battle you win by not losing,
and a mountain offensive where your vehicles cannot follow you.
- **Conquest** — the whole world map, a hundred-odd nations, everyone at peace on
- turn one. Pick anyone and take 80% of the planet.
+ turn one. Pick anyone and take every city your enemies hold — a nation
+ that loses its last city surrenders.
Traditional Chinese, Simplified Chinese and English, switchable inside the app.
diff --git a/README.zh.md b/README.zh.md
index 2a91d01..644d5a6 100644
--- a/README.zh.md
+++ b/README.zh.md
@@ -13,7 +13,7 @@ Android 上的六角格回合制大戰略遊戲。自由軟體,沒有廣告、
- **戰役** —— 五場演習,每一關只教一件事:渡海登陸、把補給線拉過沙漠、
只能靠海空拿下的島鏈、靠「不輸」取勝的防禦戰,以及輪車與履帶跟不上你的山地攻勢。
- **征服** —— 整張世界地圖、一百多個國家,第一回合所有人都還在和平狀態。
- 挑一個國家,拿下全球八成的省份。
+ 挑一個國家,攻下所有敵國的城市 —— 丟掉最後一座城的國家就會投降。
正體中文、简体中文、English,可以在 app 內切換。
diff --git a/app/src/main/java/io/github/acidefluorhydrique/mapconquer/game/Session.kt b/app/src/main/java/io/github/acidefluorhydrique/mapconquer/game/Session.kt
index a57a2c5..760405e 100644
--- a/app/src/main/java/io/github/acidefluorhydrique/mapconquer/game/Session.kt
+++ b/app/src/main/java/io/github/acidefluorhydrique/mapconquer/game/Session.kt
@@ -294,10 +294,40 @@ class Session(
province.capitalTile,
newOwner
)
- if (old >= 0) checkElimination(old)
+ if (old >= 0) {
+ if (province.hasCity && !ownsAnyCity(old)) surrender(old, newOwner) else checkElimination(old)
+ }
return true
}
+ fun ownsAnyCity(nationId: Int): Boolean =
+ map.provinces.any { it.hasCity && provinceOwner[it.id] == nationId }
+
+ /**
+ * 投降:失去最後一座城市的國家退出戰局。
+ *
+ * 規則取自原版的可觀察行為(docs/original-behavior.md「投降」):它剩下的
+ * 部隊全部消失 —— 包括還在海上、還在別國境內的 —— 剩下的領土歸給攻下
+ * 最後那座城的國家。這讓「打下它的城市」就是打垮一個國家的全部條件,
+ * 不必把散在各處的最後幾支部隊一一追殺乾淨。
+ */
+ private fun surrender(nationId: Int, captor: Int) {
+ val nation = nations[nationId]
+ if (nation.eliminated) return
+ for (pid in provinceOwner.indices) {
+ if (provinceOwner[pid] == nationId) provinceOwner[pid] = captor
+ }
+ // 載具沉沒時會連同貨艙一起處理,已經死掉的就跳過,免得重複計入損失。
+ for (unit in units.filter { it.nationId == nationId }) if (unit.isAlive) destroyUnit(unit)
+ nation.eliminated = true
+ pushEvent(
+ "event_nation_surrendered",
+ listOf(nation.nameKey, nations[captor].nameKey),
+ -1,
+ nationId
+ )
+ }
+
private fun checkElimination(nationId: Int) {
val nation = nations[nationId]
if (nation.eliminated) return
@@ -622,26 +652,15 @@ class Session(
status = SessionStatus.VICTORY
return
}
- // 征服模式沒寫目標時的預設:打垮敵對陣營。
- //
- // 原本是「拿下地圖上八成的省份」,那條規則會逼玩家去打友軍與中立國 ——
- // 八成的地圖本來就不可能只從敵人身上拿。這個模式是兩大陣營之間的
- // 戰爭,贏的定義就該是敵人沒了。
+ // 征服模式沒寫目標時的預設:攻下所有敵國的城市(見 docs/original-behavior.md
+ // 「征服的勝利條件」)。敵國失去最後一座城就投降,所以「敵人全部投降」
+ // 跟「敵人的城市全在你手上」是同一件事。盟國與中立國不算 —— 原本的
+ // 「拿下八成地圖」會逼玩家去打它們,那不是這個模式的勝利。
if (objectives.isEmpty()) {
- val enemies = blocEnemiesOf(playerNationId)
- if (enemies.isNotEmpty()) {
- if (enemies.all { it.eliminated }) {
- status = SessionStatus.VICTORY
- return
- }
- } else {
- // 玩家選了中立國:沒有陣營可打垮,回到面積規則。
- val owned = provincesOf(playerNationId)
- val total = map.provinces.count { it.tiles.isNotEmpty() }
- if (total > 0 && owned * 100 / total >= CONQUEST_VICTORY_PERCENT) {
- status = SessionStatus.VICTORY
- return
- }
+ val enemies = conquestEnemiesOf(playerNationId)
+ if (enemies.isNotEmpty() && enemies.all { it.eliminated }) {
+ status = SessionStatus.VICTORY
+ return
}
}
if (scenario.turnLimit > 0 && turn > scenario.turnLimit) {
@@ -857,6 +876,16 @@ class Session(
}
}
+ /**
+ * 征服模式裡 [nationId] 必須打垮的國家:敵對陣營的全部成員(包括還沒到
+ * 參戰回合的),加上目前跟它交戰中的任何國家(例如被它宣戰的中立國)。
+ * 盟國與沒有交戰的中立國不在其中。
+ */
+ fun conquestEnemiesOf(nationId: Int): List {
+ val bloc = blocEnemiesOf(nationId)
+ return nations.filter { it.id != nationId && (it in bloc || diplomacy.isAtWar(nationId, it.id)) }
+ }
+
/** 與 [nationId] 分屬敵對陣營的國家;兩邊都要有陣營才算數。 */
fun blocEnemiesOf(nationId: Int): List {
val bloc = nations.getOrNull(nationId)?.bloc.orEmpty()
@@ -938,8 +967,6 @@ class Session(
const val CITY_REPAIR = 22
const val FIELD_REPAIR = 6
- const val CONQUEST_VICTORY_PERCENT = 80
-
/**
* 有守軍時城防每回合的修復量。
*
diff --git a/app/src/main/java/io/github/acidefluorhydrique/mapconquer/render/PanelRenderer.kt b/app/src/main/java/io/github/acidefluorhydrique/mapconquer/render/PanelRenderer.kt
index ba5554d..08a963b 100644
--- a/app/src/main/java/io/github/acidefluorhydrique/mapconquer/render/PanelRenderer.kt
+++ b/app/src/main/java/io/github/acidefluorhydrique/mapconquer/render/PanelRenderer.kt
@@ -376,8 +376,8 @@ class PanelRenderer(private val session: Session) {
if (objectives.isEmpty()) {
Widgets.leftFit(
canvas,
- if (session.blocEnemiesOf(session.playerNationId).isEmpty()) {
- Strings.format(R.string.objective_conquest_solo, Session.CONQUEST_VICTORY_PERCENT)
+ if (session.conquestEnemiesOf(session.playerNationId).isEmpty()) {
+ Strings.get(R.string.objective_conquest_solo)
} else {
Strings.get(R.string.objective_conquest)
},
diff --git a/app/src/main/res/values-b+zh+Hans/strings.xml b/app/src/main/res/values-b+zh+Hans/strings.xml
index 80ea259..4e781fc 100644
--- a/app/src/main/res/values-b+zh+Hans/strings.xml
+++ b/app/src/main/res/values-b+zh+Hans/strings.xml
@@ -116,6 +116,7 @@
%2$s 攻下 %1$s
%2$s 占领 %1$s
%1$s 已被消灭
+ %1$s 向 %2$s 投降
%2$s 损失一支 %1$s
%1$s 补给耗尽
%2$s 生产了 %1$s
@@ -127,8 +128,8 @@
消灭 %3$s
撑过第 %2$d 回合
控制 %1$d 个省份
- 消灭敌对阵营的所有国家
- 控制世界 %1$d%% 的省份
+ 攻下所有敌国的全部城市(盟国与中立国不算)
+ 你与所有国家和平相处,宣战之后才有征服的对象
新兵
军官
指挥官
diff --git a/app/src/main/res/values-b+zh+Hant/strings.xml b/app/src/main/res/values-b+zh+Hant/strings.xml
index 7b3a7c9..47523cc 100644
--- a/app/src/main/res/values-b+zh+Hant/strings.xml
+++ b/app/src/main/res/values-b+zh+Hant/strings.xml
@@ -116,6 +116,7 @@
%2$s 攻下 %1$s
%2$s 佔領 %1$s
%1$s 已被消滅
+ %1$s 向 %2$s 投降
%2$s 損失一支 %1$s
%1$s 補給耗盡
%2$s 生產了 %1$s
@@ -127,8 +128,8 @@
消滅 %3$s
撐過第 %2$d 回合
控制 %1$d 個省份
- 消滅敵對陣營的所有國家
- 控制世界 %1$d%% 的省份
+ 攻下所有敵國的全部城市(盟國與中立國不算)
+ 你與所有國家和平相處,宣戰之後才有征服的對象
新兵
軍官
指揮官
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index d5dd88a..ce892f3 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -116,6 +116,7 @@
%1$s captured by %2$s
%2$s occupies %1$s
%1$s has been eliminated
+ %1$s has surrendered to %2$s
%2$s lost a %1$s
%1$s ran out of supply
%1$s built in %2$s
@@ -127,8 +128,8 @@
Eliminate %3$s
Survive until turn %2$d
Control %1$d provinces
- Eliminate every nation of the opposing bloc
- Control %1$d%% of the world
+ Take every city of every nation at war with you (allies and neutrals don\'t count)
+ You are at peace with everyone: declare war to have something to conquer
Recruit
Officer
Commander
diff --git a/app/src/test/java/io/github/acidefluorhydrique/mapconquer/game/SessionTest.kt b/app/src/test/java/io/github/acidefluorhydrique/mapconquer/game/SessionTest.kt
index 98b5e53..fb14cd0 100644
--- a/app/src/test/java/io/github/acidefluorhydrique/mapconquer/game/SessionTest.kt
+++ b/app/src/test/java/io/github/acidefluorhydrique/mapconquer/game/SessionTest.kt
@@ -712,6 +712,152 @@ class SessionTest {
assertEquals(SessionStatus.VICTORY, s.status)
}
+ // ------------------------------------------------------------------
+ // 投降與征服的勝利條件(docs/original-behavior.md)
+ // ------------------------------------------------------------------
+
+ /**
+ * 三省地圖:A 省(AAA 的城)、B 省(BBB 的城)、C 省([cTier] 級,歸 [cOwner])。
+ * 最下面一列是海。
+ */
+ private fun threeProvinceSession(
+ cTier: Int,
+ cOwner: String,
+ units: List,
+ relations: List>
+ ): Session {
+ val text = """
+ format 1
+ id test3
+ cols 9
+ rows 6
+
+ [terrain]
+ .........
+ .........
+ .........
+ .........
+ .........
+ ~~~~~~~~~
+
+ [provinces]
+ 3:0 3:1 3:2
+ 3:0 3:1 3:2
+ 3:0 3:1 3:2
+ 3:0 3:1 3:2
+ 3:0 3:1 3:2
+ 9:-1
+
+ [meta]
+ 0|prov_a|3|1,1
+ 1|prov_b|3|4,1
+ 2|prov_c|$cTier|7,1
+ """.trimIndent()
+ val map = MapLoader.parse(text.reader().buffered(), "test3")
+ val nations = listOf(
+ ScenarioNation("AAA", "nation_aaa", "#FF0000", 0, AiProfile.BALANCED, 5000, IntArray(6)),
+ ScenarioNation("BBB", "nation_bbb", "#0000FF", 1, AiProfile.BALANCED, 5000, IntArray(6)),
+ ScenarioNation("CCC", "nation_ccc", "#00FF00", if (cOwner == "CCC") 2 else -1,
+ AiProfile.BALANCED, 5000, IntArray(6))
+ )
+ val ownership = mutableMapOf("AAA" to intArrayOf(0), "BBB" to intArrayOf(1))
+ ownership[cOwner] = (ownership[cOwner] ?: IntArray(0)) + 2
+ val scenario = Scenario(
+ id = "test3", mapId = "test3", mode = GameMode.CONQUEST,
+ nameKey = "n", descKey = "d", order = 1, turnLimit = 50,
+ startYear = 2026, startMonth = 1, nations = nations, relations = relations,
+ ownership = ownership, startingUnits = units, playable = listOf("AAA"),
+ objectives = emptyList(), starTurns = intArrayOf(10, 20)
+ )
+ return Session(map, scenario, Difficulty.OFFICER, "AAA", 4321L)
+ }
+
+ /** 讓 AAA 在 (3,1) 的步兵走進 B 省的城,城防先歸零。 */
+ private fun takeCityB(s: Session) {
+ val unit = s.units.first { it.nationId == 0 && it.kind == UnitKind.INFANTRY }
+ s.cityHp[1] = 0
+ Orders.computeReachable(s, unit, ArrayList())
+ Orders.move(s, unit, s.map.provinces[1].capitalTile, ArrayList())
+ assertEquals("步兵該站上 B 城", s.map.provinces[1].capitalTile, unit.tile)
+ }
+
+ @Test
+ fun `losing the last city is a surrender - units vanish, leftover land goes to the captor`() {
+ val s = threeProvinceSession(
+ cTier = 0, cOwner = "BBB",
+ units = listOf(
+ ScenarioUnit("AAA", 3, 1, "INFANTRY", 1, ""),
+ ScenarioUnit("BBB", 7, 3, "INFANTRY", 1, ""),
+ ScenarioUnit("BBB", 7, 5, "DESTROYER", 1, "")
+ ),
+ relations = listOf(Triple("AAA", "BBB", Relation.WAR))
+ )
+ assertFalse("C 省沒有城", s.map.provinces[2].hasCity)
+ takeCityB(s)
+
+ val bbb = s.nationByCode("BBB")!!
+ assertTrue("最後一座城丟了就投降", bbb.eliminated)
+ assertTrue("投降國的部隊全部消失,包括海上的", s.unitsOf(bbb.id).isEmpty())
+ assertEquals("剩下的領土歸攻下最後一城的國家", 0, s.provinceOwner[2])
+ assertTrue(s.events.any { it.key == "event_nation_surrendered" })
+ assertEquals("唯一的敵國投降,征服完成", SessionStatus.VICTORY, s.status)
+ }
+
+ @Test
+ fun `losing one of several cities is not a surrender`() {
+ val s = threeProvinceSession(
+ cTier = 2, cOwner = "BBB",
+ units = listOf(
+ ScenarioUnit("AAA", 3, 1, "INFANTRY", 1, ""),
+ ScenarioUnit("BBB", 7, 3, "INFANTRY", 1, "")
+ ),
+ relations = listOf(Triple("AAA", "BBB", Relation.WAR))
+ )
+ takeCityB(s)
+
+ val bbb = s.nationByCode("BBB")!!
+ assertFalse("還有一座城就還在打", bbb.eliminated)
+ assertEquals(1, s.unitsOf(bbb.id).size)
+ assertEquals(bbb.id, s.provinceOwner[2])
+ assertEquals(SessionStatus.PLAYING, s.status)
+ }
+
+ @Test
+ fun `conquest is won without touching neutrals`() {
+ val s = threeProvinceSession(
+ cTier = 2, cOwner = "CCC",
+ units = listOf(ScenarioUnit("AAA", 3, 1, "INFANTRY", 1, "")),
+ relations = listOf(Triple("AAA", "BBB", Relation.WAR))
+ )
+ takeCityB(s)
+ assertFalse("中立國不必打", s.nationByCode("CCC")!!.eliminated)
+ assertEquals(SessionStatus.VICTORY, s.status)
+ }
+
+ @Test
+ fun `a neutral you declared war on has to be conquered too`() {
+ val s = threeProvinceSession(
+ cTier = 2, cOwner = "CCC",
+ units = listOf(ScenarioUnit("AAA", 3, 1, "INFANTRY", 1, "")),
+ relations = listOf(Triple("AAA", "BBB", Relation.WAR))
+ )
+ assertTrue(Orders.declareWar(s, 0, 2))
+ takeCityB(s)
+ assertEquals("被宣戰的中立國就是敵國,還沒打下來", SessionStatus.PLAYING, s.status)
+ }
+
+ @Test
+ fun `nobody to fight means no conquest victory`() {
+ val s = threeProvinceSession(
+ cTier = 2, cOwner = "CCC",
+ units = listOf(ScenarioUnit("AAA", 1, 1, "INFANTRY", 1, "")),
+ relations = emptyList()
+ )
+ repeat(s.nations.size) { s.advanceToNextNation() }
+ s.refreshOutcome()
+ assertEquals(SessionStatus.PLAYING, s.status)
+ }
+
@Test
fun `losing everything ends the game`() {
val s = session(
diff --git a/docs/original-behavior.md b/docs/original-behavior.md
new file mode 100644
index 0000000..30daf49
--- /dev/null
+++ b/docs/original-behavior.md
@@ -0,0 +1,160 @@
+
+
+# 原版行為規格
+
+這份文件記錄我們對參考遊戲(同類型的回合制戰略手遊)**可觀察行為**的了解:
+在什麼輸入下,玩家會看到什麼結果。它描述的是「原版表現如何」,不是「原版的程式
+碼長什麼樣」 —— 這裡沒有、也不應該出現任何原版的原始碼、資源或資料表內容。
+
+本專案的實作是依照這份規格獨立設計的;規格與實作之間的對應寫在每一節的
+「本專案」一欄。
+
+## 來源與標記
+
+| 來源代碼 | 意思 |
+|---|---|
+| 觀察 | 維護者實際遊玩原版所觀察到的行為 |
+| 說明 | 原版遊戲內的說明文字(未加密的文字資源),此處只轉述意思,不引用原文 |
+
+| 標記 | 意思 |
+|---|---|
+| ✅ | 已確認(多次觀察一致,或觀察與說明文字互相印證) |
+| 🟡 | 有力推測,尚未以控制實驗驗證 |
+| ❓ | **UNKNOWN BEHAVIOR** —— 證據不足,本專案的做法是近似值 |
+
+不使用的來源:原版加密資料檔的解密內容、反組譯或反編譯的程式碼。
+
+---
+
+## 1. 戰役的勝利條件
+
+### 觀察到的行為
+
+| 行為 | 來源 | 狀態 |
+|---|---|---|
+| 每一關的勝利條件是「攻佔指定城市」或「堅守指定城市」其中之一 | 觀察 | ✅ |
+
+### 本專案
+
+- `ObjectiveType.CAPTURE_PROVINCES`:指定的省份全部歸玩家時勝利。
+- `ObjectiveType.HOLD_PROVINCES`:到了指定回合時,指定省份仍全部在玩家手上即勝利。
+- 另有 `ELIMINATE_NATION`、`SURVIVE_TURNS`、`CONTROL_COUNT` 三種目標,是本專案
+ 自己的擴充,原版沒有對應。
+- 實作:`game/Session.kt` 的 `objectiveProgress`、`isObjectiveMet`、`evaluateOutcome`。
+- 測試:`SessionTest` 的 ``objectives drive victory``。
+
+### UNKNOWN BEHAVIOR
+
+1. **超過回合上限時的結果。** 本專案判定為失敗(`turnLimit`)。
+ 原版可能是失敗,也可能只是拿不到星等。
+ *實驗*:在原版任一關刻意拖過回合上限,記錄是結束關卡還是繼續進行。
+2. **「堅守」的判定時點。** 是「到了第 N 回合那一刻仍持有」,還是「從開局到第 N
+ 回合之間一次都不能丟」?本專案採前者。
+ *實驗*:在堅守關卡中途讓城市失守再奪回,看最後是否仍判定勝利。
+3. **戰役中丟掉自己的首都是否直接失敗。** 本專案不會;只有失去最後一座城才出局
+ (見第 3 節)。
+
+---
+
+## 2. 征服模式的勝利條件
+
+### 觀察到的行為
+
+| 行為 | 來源 | 狀態 |
+|---|---|---|
+| 勝利條件是攻下**所有敵國**的城市 | 觀察 | ✅ |
+| 盟國與中立國的城市不在勝利條件之內 | 觀察 | ✅ |
+| 可以對中立國宣戰,被宣戰的中立國從此成為敵國 | 說明 | ✅ |
+
+### 規格
+
+```text
+enemies(P) = 與玩家 P 分屬敵對陣營的國家 ∪ 目前與 P 交戰中的國家
+勝利 ⇔ enemies(P) 不為空,且 enemies(P) 中每一國都已投降(見第 3 節)
+```
+
+敵國失去最後一座城就投降,所以「所有敵國都投降」與「所有敵國的城市都在我方
+陣營手上」是同一件事。
+
+### 本專案
+
+- 實作:`Session.conquestEnemiesOf`、`Session.evaluateOutcome`。
+- 舊版規則「控制世界八成省份」已移除:它會逼玩家去打盟國與中立國。
+- 測試:`SessionTest` 的 ``conquest is won without touching neutrals``、
+ ``a neutral you declared war on has to be conquered too``、
+ ``nobody to fight means no conquest victory``。
+
+### UNKNOWN BEHAVIOR
+
+1. **還沒到參戰回合的敵對陣營國家算不算敵國。** 例如 1939 年的美國要到第 6 回合
+ 才參戰。若玩家在那之前就打垮了所有已參戰的敵國,原版是立即勝利,還是要等美國
+ 參戰後把它也打下來?本專案**把它算進去**(陣營是敵對的就算),這是保守的近似。
+ *實驗*:原版 1939 以軸心國開局,在美國參戰前攻下所有交戰中的同盟國城市,
+ 觀察是否跳出勝利。
+2. **玩家選擇的是沒有陣營的國家,而且誰都沒宣戰。** 本專案的敵國集合是空的,
+ 所以不會勝利,玩家必須先宣戰。原版在這種情況下的行為未觀察。
+3. **盟軍攻下敵國最後一座城。** 敵國照樣投降,領土歸那個盟國(第 3 節),玩家
+ 的勝利條件照樣成立。原版是否相同未確認。
+
+---
+
+## 3. 投降
+
+### 觀察到的行為
+
+| 行為 | 來源 | 狀態 |
+|---|---|---|
+| 一個國家的所有城市都被攻下之後,它立刻投降 | 觀察 | ✅ |
+| 投降國剩下的所有部隊立刻消失 | 觀察 | ✅ |
+| 投降國最後那座城市對應的領土歸攻下它的一方 | 觀察 | ✅ |
+
+### 規格
+
+```text
+觸發:國家 N 的某座城被國家 C 攻下,且 N 因此一座城都不剩
+效果:
+ 1. N 的所有部隊移除(不論在陸上、海上、或他國境內)
+ 2. N 名下剩餘的所有省份改歸 C
+ 3. N 退出戰局(不再有回合)
+邊界:
+ N 還有任何一座城 → 不投降,部隊與領土都不動
+```
+
+### 本專案
+
+- 實作:`Session.captureProvince` → `Session.surrender`;`Session.ownsAnyCity`。
+- 事件:`event_nation_surrendered`(「%1$s 向 %2$s 投降」)。
+- 測試:`SessionTest` 的
+ ``losing the last city is a surrender - units vanish, leftover land goes to the captor``、
+ ``losing one of several cities is not a surrender``。
+- 沒有城市、只剩部隊的國家(例如只有遠征軍的劇本勢力)不會因為這條規則出局;
+ 它們沿用舊規則:沒有任何省份也沒有任何部隊時才消失。
+
+### UNKNOWN BEHAVIOR
+
+1. **AI 對 AI 是否同樣適用。** 觀察都是從玩家視角出發。本專案對所有國家一視同仁,
+ 🟡。*實驗*:原版征服中觀察兩個 AI 國家交戰,某國最後一座城陷落時,它的部隊
+ 是否同時消失。
+2. **「領土」的範圍。** 原版的領土是城市轄下的格子;本專案的單位是省份,一省
+ 對應一座城。兩者在「最後一座城的領土歸攻方」這一點上結果相同。若原版還有不
+ 屬於任何城市的格子,那些格子投降後歸誰未知;本專案把投降國名下的所有省份都
+ 交給攻方。
+3. **投降國的運輸艦上載著他國部隊時。** 本專案沿用「載具沉沒、乘客一起沉」的
+ 既有規則。原版未觀察。
+
+---
+
+## 4. 待研究
+
+以下行為會影響後續的實作,但目前沒有足夠證據,先列出來:
+
+- 傷害公式與隨機範圍(最小攻擊到最大攻擊之間的分佈、取整時點)
+- 編隊、等級對攻擊與生命值的影響
+- 城市與部隊同格時的傷害分攤
+- 經濟:每回合收入的計算方式與時點
+
+每一項都應該先在原版上做控制實驗(固定兵種、地形、編隊,重複攻擊並記錄結果),
+把輸入與輸出寫進這份文件,再決定本專案的實作。
diff --git a/fastlane/metadata/android/en-US/full_description.txt b/fastlane/metadata/android/en-US/full_description.txt
index bb6522a..cee114e 100644
--- a/fastlane/metadata/android/en-US/full_description.txt
+++ b/fastlane/metadata/android/en-US/full_description.txt
@@ -10,7 +10,8 @@ commanders who then serve you in every later game.
CONQUEST
The whole world map, a hundred-odd nations, everyone at peace on turn one. Pick anyone
-— a superpower or a country with a single city — and take 80% of the planet.
+— a superpower or a country with a single city — and take every city your enemies hold.
+A nation that loses its last city surrenders.
WHAT MAKES A BATTLE
Every unit has four separate attack values: against infantry, armour, ships and
diff --git a/fastlane/metadata/android/zh-CN/full_description.txt b/fastlane/metadata/android/zh-CN/full_description.txt
index 879f538..61fca84 100644
--- a/fastlane/metadata/android/zh-CN/full_description.txt
+++ b/fastlane/metadata/android/zh-CN/full_description.txt
@@ -8,7 +8,7 @@
征服
整张世界地图、一百多个国家,第一回合所有人都还在和平状态。
-挑任何一国 —— 超级强权,或是只有一座城市的小国 —— 拿下全球八成的省份。
+挑任何一国 —— 超级强权,或是只有一座城市的小国 —— 攻下所有敌国的城市。丢掉最后一座城的国家就会投降。
一场仗是怎么打起来的
每支部队都有四个独立的攻击值:对步兵、对装甲、对舰艇、对空。
diff --git a/fastlane/metadata/android/zh-TW/full_description.txt b/fastlane/metadata/android/zh-TW/full_description.txt
index a0641b4..7b60edc 100644
--- a/fastlane/metadata/android/zh-TW/full_description.txt
+++ b/fastlane/metadata/android/zh-TW/full_description.txt
@@ -8,7 +8,7 @@
征服
整張世界地圖、一百多個國家,第一回合所有人都還在和平狀態。
-挑任何一國 —— 超級強權,或是只有一座城市的小國 —— 拿下全球八成的省份。
+挑任何一國 —— 超級強權,或是只有一座城市的小國 —— 攻下所有敵國的城市。丟掉最後一座城的國家就會投降。
一場仗是怎麼打起來的
每支部隊都有四個獨立的攻擊值:對步兵、對裝甲、對艦艇、對空。
diff --git a/tools/genstrings.py b/tools/genstrings.py
index 674131d..f8a4278 100644
--- a/tools/genstrings.py
+++ b/tools/genstrings.py
@@ -172,6 +172,7 @@
"event_city_captured": ("%1$s captured by %2$s", "%2$s 攻下 %1$s", "%2$s 攻下 %1$s"),
"event_province_captured": ("%2$s occupies %1$s", "%2$s 佔領 %1$s", "%2$s 占领 %1$s"),
"event_nation_eliminated": ("%1$s has been eliminated", "%1$s 已被消滅", "%1$s 已被消灭"),
+ "event_nation_surrendered": ("%1$s has surrendered to %2$s", "%1$s 向 %2$s 投降", "%1$s 向 %2$s 投降"),
"event_unit_destroyed": ("%2$s lost a %1$s", "%2$s 損失一支 %1$s", "%2$s 损失一支 %1$s"),
"event_unit_starved": ("%1$s ran out of supply", "%1$s 補給耗盡", "%1$s 补给耗尽"),
"event_unit_built": ("%1$s built in %2$s", "%2$s 生產了 %1$s", "%2$s 生产了 %1$s"),
@@ -185,10 +186,12 @@
"objective_eliminate": ("Eliminate %3$s", "消滅 %3$s", "消灭 %3$s"),
"objective_survive": ("Survive until turn %2$d", "撐過第 %2$d 回合", "撑过第 %2$d 回合"),
"objective_control": ("Control %1$d provinces", "控制 %1$d 個省份", "控制 %1$d 个省份"),
- "objective_conquest": ("Eliminate every nation of the opposing bloc",
- "消滅敵對陣營的所有國家", "消灭敌对阵营的所有国家"),
- "objective_conquest_solo": ("Control %1$d%% of the world",
- "控制世界 %1$d%% 的省份", "控制世界 %1$d%% 的省份"),
+ "objective_conquest": ("Take every city of every nation at war with you (allies and neutrals don't count)",
+ "攻下所有敵國的全部城市(盟國與中立國不算)",
+ "攻下所有敌国的全部城市(盟国与中立国不算)"),
+ "objective_conquest_solo": ("You are at peace with everyone: declare war to have something to conquer",
+ "你與所有國家和平相處,宣戰之後才有征服的對象",
+ "你与所有国家和平相处,宣战之后才有征服的对象"),
# 難度
"difficulty_recruit": ("Recruit", "新兵", "新兵"),
From eea026e006ef2198459695664b117316610d7e9a Mon Sep 17 00:00:00 2001
From: AcideFluorhydrique
<139669368+AcideFluorhydrique@users.noreply.github.com>
Date: Tue, 22 Sep 2026 16:16:15 +0800
Subject: [PATCH 03/11] Let conquest scenarios carry a turn limit, and record
what was confirmed
Running out of turns in conquest is a loss in the reference game. Session
already treats "turn past the limit and not yet won" as defeat for any
scenario; conquest scenarios were just generated with no limit.
write_conquest now takes turn_limit, and a test pins the defeat. The limit
for each year is still to be decided, so the shipped scenarios keep 0.
docs/original-behavior.md now records that an AI ally taking an enemy's
last city has the same effect as the player taking it, and that a bloc
member joining the war late only matters in play that cannot happen
without cheating, so the conservative rule stays.
---
.../mapconquer/game/SessionTest.kt | 20 +++++++++++++--
docs/original-behavior.md | 25 +++++++++++--------
tools/genworld.py | 5 ++--
3 files changed, 36 insertions(+), 14 deletions(-)
diff --git a/app/src/test/java/io/github/acidefluorhydrique/mapconquer/game/SessionTest.kt b/app/src/test/java/io/github/acidefluorhydrique/mapconquer/game/SessionTest.kt
index fb14cd0..4a628e9 100644
--- a/app/src/test/java/io/github/acidefluorhydrique/mapconquer/game/SessionTest.kt
+++ b/app/src/test/java/io/github/acidefluorhydrique/mapconquer/game/SessionTest.kt
@@ -724,7 +724,8 @@ class SessionTest {
cTier: Int,
cOwner: String,
units: List,
- relations: List>
+ relations: List>,
+ turnLimit: Int = 50
): Session {
val text = """
format 1
@@ -764,7 +765,7 @@ class SessionTest {
ownership[cOwner] = (ownership[cOwner] ?: IntArray(0)) + 2
val scenario = Scenario(
id = "test3", mapId = "test3", mode = GameMode.CONQUEST,
- nameKey = "n", descKey = "d", order = 1, turnLimit = 50,
+ nameKey = "n", descKey = "d", order = 1, turnLimit = turnLimit,
startYear = 2026, startMonth = 1, nations = nations, relations = relations,
ownership = ownership, startingUnits = units, playable = listOf("AAA"),
objectives = emptyList(), starTurns = intArrayOf(10, 20)
@@ -846,6 +847,21 @@ class SessionTest {
assertEquals("被宣戰的中立國就是敵國,還沒打下來", SessionStatus.PLAYING, s.status)
}
+ @Test
+ fun `a conquest still undecided past its turn limit is lost`() {
+ val s = threeProvinceSession(
+ cTier = 2, cOwner = "BBB",
+ units = listOf(ScenarioUnit("AAA", 1, 1, "INFANTRY", 1, "")),
+ relations = listOf(Triple("AAA", "BBB", Relation.WAR)),
+ turnLimit = 2
+ )
+ while (s.turn <= 2) {
+ assertEquals("上限之內還在打", SessionStatus.PLAYING, s.status)
+ s.advanceToNextNation()
+ }
+ assertEquals("超過回合上限判負", SessionStatus.DEFEAT, s.status)
+ }
+
@Test
fun `nobody to fight means no conquest victory`() {
val s = threeProvinceSession(
diff --git a/docs/original-behavior.md b/docs/original-behavior.md
index 30daf49..a5dd4ac 100644
--- a/docs/original-behavior.md
+++ b/docs/original-behavior.md
@@ -68,12 +68,15 @@ SPDX-License-Identifier: GPL-3.0-or-later
| 勝利條件是攻下**所有敵國**的城市 | 觀察 | ✅ |
| 盟國與中立國的城市不在勝利條件之內 | 觀察 | ✅ |
| 可以對中立國宣戰,被宣戰的中立國從此成為敵國 | 說明 | ✅ |
+| 敵國被 AI 盟軍攻下最後一座城而投降,效果跟玩家自己攻下一樣 | 觀察 | ✅ |
+| 回合數超過該劇本的上限仍未勝利,判負 | 觀察 | ✅ |
### 規格
```text
enemies(P) = 與玩家 P 分屬敵對陣營的國家 ∪ 目前與 P 交戰中的國家
勝利 ⇔ enemies(P) 不為空,且 enemies(P) 中每一國都已投降(見第 3 節)
+失敗 ⇔ 回合數 > 回合上限,且尚未勝利;或玩家自己投降
```
敵國失去最後一座城就投降,所以「所有敵國都投降」與「所有敵國的城市都在我方
@@ -83,21 +86,24 @@ enemies(P) = 與玩家 P 分屬敵對陣營的國家 ∪ 目前與 P 交戰中
- 實作:`Session.conquestEnemiesOf`、`Session.evaluateOutcome`。
- 舊版規則「控制世界八成省份」已移除:它會逼玩家去打盟國與中立國。
+- 回合上限:劇本檔的 `turnLimit`,由 `tools/genworld.py` 的 `write_conquest(turn_limit=…)`
+ 寫入;判負在 `Session.evaluateOutcome`。
- 測試:`SessionTest` 的 ``conquest is won without touching neutrals``、
``a neutral you declared war on has to be conquered too``、
- ``nobody to fight means no conquest victory``。
+ ``nobody to fight means no conquest victory``、
+ ``a conquest still undecided past its turn limit is lost``。
### UNKNOWN BEHAVIOR
1. **還沒到參戰回合的敵對陣營國家算不算敵國。** 例如 1939 年的美國要到第 6 回合
- 才參戰。若玩家在那之前就打垮了所有已參戰的敵國,原版是立即勝利,還是要等美國
- 參戰後把它也打下來?本專案**把它算進去**(陣營是敵對的就算),這是保守的近似。
- *實驗*:原版 1939 以軸心國開局,在美國參戰前攻下所有交戰中的同盟國城市,
- 觀察是否跳出勝利。
+ 才參戰。本專案**把它算進去**(陣營是敵對的就算)。原版的結果不明,但這個情況
+ 在正常遊玩下幾乎不可能出現(要在參戰回合之前打垮所有已參戰的敵國,實際上
+ 只有作弊才做得到),不值得為它設計實驗;維持保守的做法。
2. **玩家選擇的是沒有陣營的國家,而且誰都沒宣戰。** 本專案的敵國集合是空的,
所以不會勝利,玩家必須先宣戰。原版在這種情況下的行為未觀察。
-3. **盟軍攻下敵國最後一座城。** 敵國照樣投降,領土歸那個盟國(第 3 節),玩家
- 的勝利條件照樣成立。原版是否相同未確認。
+3. ~~盟軍攻下敵國最後一座城~~ —— 已確認,見上表:效果跟玩家自己攻下一樣。
+4. **各年份征服的回合上限數值。** 規則(超過判負)已確認,數值未知;
+ 目前劇本檔寫的是 0(不設限)。
---
@@ -135,9 +141,8 @@ enemies(P) = 與玩家 P 分屬敵對陣營的國家 ∪ 目前與 P 交戰中
### UNKNOWN BEHAVIOR
-1. **AI 對 AI 是否同樣適用。** 觀察都是從玩家視角出發。本專案對所有國家一視同仁,
- 🟡。*實驗*:原版征服中觀察兩個 AI 國家交戰,某國最後一座城陷落時,它的部隊
- 是否同時消失。
+1. **AI 對 AI 是否同樣適用。** 已確認攻方是玩家的 AI 盟軍時同樣投降(第 2 節);
+ 攻守雙方都跟玩家無關的情況未直接觀察,本專案一視同仁,🟡。
2. **「領土」的範圍。** 原版的領土是城市轄下的格子;本專案的單位是省份,一省
對應一座城。兩者在「最後一座城的領土歸攻方」這一點上結果相同。若原版還有不
屬於任何城市的格子,那些格子投降後歸誰未知;本專案把投降國名下的所有省份都
diff --git a/tools/genworld.py b/tools/genworld.py
index 5626397..9fb4495 100644
--- a/tools/genworld.py
+++ b/tools/genworld.py
@@ -413,7 +413,7 @@ def garrison_lines(built, owners, nation_funds):
def write_conquest(built, scenario_id, name_key, desc_key, order, merge,
start_year, turtle=None, blocs=None, overrides=None,
- renames=None, war_turns=None, start_month=None):
+ renames=None, war_turns=None, start_month=None, turn_limit=0):
"""把 places 的國家分佈展開成一份征服劇本。"""
owners = {}
for pid, (key, _tier, nation, _tile) in enumerate(built.provinces):
@@ -447,7 +447,8 @@ def nation_row(code):
lines.append("nameKey %s" % name_key)
lines.append("descKey %s" % desc_key)
lines.append("order %d" % order)
- lines.append("turnLimit 0")
+ # 超過回合上限判負(docs/original-behavior.md「征服的勝利條件」)。0 = 不設限。
+ lines.append("turnLimit %d" % turn_limit)
lines.append("startYear %d" % start_year)
if start_month:
lines.append("startMonth %d" % start_month)
From 8bf5659b9471a63774553d59fb00f784f6867234 Mon Sep 17 00:00:00 2001
From: AcideFluorhydrique
<139669368+AcideFluorhydrique@users.noreply.github.com>
Date: Tue, 22 Sep 2026 16:32:36 +0800
Subject: [PATCH 04/11] Widen the world map's land-share guard to fit the
stretched map
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The guard asserted 20–45% land, and the map was already at 44%: the oceans
are squeezed on purpose, so land takes far more of the grid than the real
world's 30% the comment claimed. Drawing Finland, Jutland and the Indus
valley and giving 60–72°N proper rows brings it to 46%. The test exists to
catch a generator that turned everything to sea or land, and 20–55% still
does that.
---
.../acidefluorhydrique/mapconquer/world/MapAssetTest.kt | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/app/src/test/java/io/github/acidefluorhydrique/mapconquer/world/MapAssetTest.kt b/app/src/test/java/io/github/acidefluorhydrique/mapconquer/world/MapAssetTest.kt
index 828904f..cec40b1 100644
--- a/app/src/test/java/io/github/acidefluorhydrique/mapconquer/world/MapAssetTest.kt
+++ b/app/src/test/java/io/github/acidefluorhydrique/mapconquer/world/MapAssetTest.kt
@@ -119,8 +119,11 @@ class MapAssetTest {
val world = TestAssets.cachedMap("world")
val land = (0 until world.tileCount).count { world.isLand(it) }
val ratio = land * 100 / world.tileCount
- // 排除南極與高緯度之後,陸地大約佔三成。這是防止產生器徹底壞掉的護欄。
- assertTrue("陸地比例 $ratio% 不合理", ratio in 20..45)
+ // 這是防止產生器徹底壞掉(整張變海或整張變陸)的護欄,不是真實世界的
+ // 海陸比。世界地圖刻意把太平洋與大西洋壓扁、把北緯 60–72 度拉寬,
+ // 陸地佔比本來就遠高於真實的三成 —— 補上芬蘭、日德蘭、印度河流域之後
+ // 約在 46%。
+ assertTrue("陸地比例 $ratio% 不合理", ratio in 20..55)
assertTrue("城市太少", world.provinces.count { it.hasCity } > 100)
assertTrue("首都級城市太少", world.provinces.count { it.cityTier >= 4 } >= 8)
}
From d935601b8f4a33783e1d5f49fd422174a91fafe1 Mon Sep 17 00:00:00 2001
From: AcideFluorhydrique
<139669368+AcideFluorhydrique@users.noreply.github.com>
Date: Tue, 22 Sep 2026 18:03:52 +0800
Subject: [PATCH 05/11] Fix the next round of map and scenario errors
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Denmark touched Sweden: Copenhagen's hex bridged the Øresund. Jutland and
Zealand now never touch Scandinavia by land (geodata.SEAS), and Zealand
has its own polygon so Copenhagen sits on it.
Norway was in two pieces. The Scandinavian polygon's north coast only
reached the grid's top land row at the North Cape, so an inland Swedish
province ran to the Arctic between Narvik and the far north. The coast is
drawn up to 71.3°N, Trondheim and Hammerfest give Norway its middle and
north, and Luleå replaces Kiruna as Sweden's northern city so it stops
winning ties on the Norwegian coast. topology.py now also checks that a
list of countries' mainland is one piece; it found Chile cut in two by
Bariloche's province, so Argentina's Patagonian cities are now Neuquén
and Comodoro Rivadavia on the east side and Chile gets Temuco and
Coyhaique on the west.
Vladivostok was an island: the Siberian polygon cut straight from 135°E
48°N to 130°E 44°N and left Primorye out. The Philippines were one blob
from 120°E to 126.5°E that counted the Sibuyan Sea as land; they are now
Luzon, the Visayas and Mindanao.
Hong Kong, Gibraltar (new) and Belfast (new, Northern Ireland) are
places.SINGLE_TILE provinces: one hex, no territory grown around them.
The Strait of Gibraltar line moved to the southern half of the strait so
Gibraltar stands on the Iberian side, and Europe never touches Africa by
land. GBR–IRL is now a required land border and GBR–ESP one too.
Cuba, the Dominican Republic and Panama are independent neutrals in 1939
and 1943, not part of the United States. Ethiopia is neutral in 1943
instead of an Allied member. In 1939 and 1943 the Republic of China is
shown as "China" under 🇹🇼; from 1950 China is the People's Republic 🇨🇳
and Taiwan the Republic of China 🇹🇼. The Republic of China starts 1950
with its remnants: two infantry in the Shan States, one south-east of
Kunming, and ships off Zhoushan, off Fujian and in the strait.
---
app/src/main/assets/maps/andes.map | 117 +--
app/src/main/assets/maps/europe.map | 186 ++---
app/src/main/assets/maps/north_africa.map | 121 +--
app/src/main/assets/maps/sea_asia.map | 62 +-
app/src/main/assets/maps/world.map | 691 +++++++++---------
.../assets/scenarios/campaign_cw_01_suez.scn | 59 +-
.../scenarios/campaign_cw_01_suez_west.scn | 59 +-
.../scenarios/campaign_cw_02_indochina.scn | 2 +-
.../campaign_cw_02_indochina_west.scn | 2 +-
.../campaign_cw_03_central_front.scn | 104 +--
.../campaign_cw_03_central_front_pact.scn | 104 +--
.../scenarios/campaign_ww2_01_poland.scn | 86 +--
.../scenarios/campaign_ww2_01_poland_axis.scn | 86 +--
.../scenarios/campaign_ww2_02_france.scn | 84 +--
.../campaign_ww2_02_france_allies.scn | 84 +--
.../scenarios/campaign_ww2_03_desert.scn | 46 +-
.../scenarios/campaign_ww2_03_desert_axis.scn | 46 +-
.../scenarios/campaign_ww2_04_south_seas.scn | 12 +-
.../campaign_ww2_04_south_seas_allies.scn | 12 +-
.../scenarios/campaign_ww2_06_philippines.scn | 2 +-
.../campaign_ww2_06_philippines_axis.scn | 2 +-
.../main/assets/scenarios/conquest_1939.scn | 182 ++---
.../main/assets/scenarios/conquest_1943.scn | 172 ++---
.../main/assets/scenarios/conquest_1950.scn | 277 +++----
.../main/assets/scenarios/conquest_1980.scn | 393 +++++-----
app/src/main/res/values-b+zh+Hans/strings.xml | 12 +-
app/src/main/res/values-b+zh+Hant/strings.xml | 12 +-
app/src/main/res/values/strings.xml | 12 +-
.../mapconquer/world/MapAssetTest.kt | 4 +-
tools/genstrings.py | 1 +
tools/genworld.py | 54 +-
tools/geodata.py | 40 +-
tools/places.py | 52 +-
tools/scenarios.py | 9 +-
tools/topology.py | 36 +-
35 files changed, 1709 insertions(+), 1514 deletions(-)
diff --git a/app/src/main/assets/maps/andes.map b/app/src/main/assets/maps/andes.map
index b234faa..fdf7ea9 100644
--- a/app/src/main/assets/maps/andes.map
+++ b/app/src/main/assets/maps/andes.map
@@ -59,56 +59,56 @@ rows 50
~~~~~~~~~~-^^^^^^^dhh.-~~~~~~~~~~~~~~~~~
[provinces]
-10:-1 1:2 11:1 3:15 15:-1
-4:-1 1:0 3:-1 2:2 11:1 5:15 14:-1
-7:-1 3:2 11:1 9:15 10:-1
-6:-1 4:2 11:1 11:15 8:-1
-6:-1 4:2 11:1 12:15 2:16 5:-1
-5:-1 4:2 11:1 12:15 3:16 5:-1
-6:-1 1:3 2:2 11:1 13:15 3:16 4:-1
-5:-1 3:3 11:1 13:15 4:16 4:-1
-5:-1 4:3 10:1 14:15 4:16 3:-1
-4:-1 6:3 8:1 14:15 6:16 2:-1
-4:-1 1:4 6:3 7:1 15:15 7:16
-3:-1 3:4 5:3 6:1 16:15 6:16 1:-1
-4:-1 3:4 5:3 5:1 1:6 16:15 6:16
-3:-1 4:4 5:3 6:6 15:15 7:16
-3:-1 5:4 2:3 2:5 7:6 15:15 6:16
-3:-1 5:4 3:5 8:6 14:15 7:16
-5:-1 6:5 8:6 2:7 13:15 6:16
-5:-1 5:5 8:6 3:7 12:15 7:16
-6:-1 5:5 7:6 4:7 12:15 6:16
-6:-1 4:5 7:6 5:7 11:15 7:16
-7:-1 4:5 6:6 7:7 10:15 6:16
-8:-1 2:5 6:6 9:7 7:15 3:14 5:16
-9:-1 1:5 6:6 11:7 10:14 3:16
-10:-1 5:6 11:7 12:14 2:16
-13:-1 2:6 11:7 13:14 1:17
-14:-1 11:7 13:14 2:17
-15:-1 10:7 13:14 2:17
-14:-1 10:7 13:14 3:17
-15:-1 2:9 7:7 13:14 3:17
-14:-1 4:9 5:7 13:14 4:17
-15:-1 5:9 3:7 13:14 4:17
-14:-1 8:9 1:11 12:14 5:17
-15:-1 6:9 3:11 11:14 5:17
-14:-1 5:9 5:11 9:14 6:17 1:-1
-15:-1 4:9 6:11 8:14 6:17 1:-1
-14:-1 4:9 7:11 7:14 5:17 3:-1
-14:-1 4:8 7:11 2:10 5:14 5:17 3:-1
-14:-1 3:8 8:11 5:10 2:13 4:17 4:-1
-14:-1 4:8 7:11 5:10 3:13 3:17 4:-1
-13:-1 5:8 6:11 5:10 4:13 1:17 6:-1
-14:-1 5:8 5:11 6:10 4:13 6:-1
-13:-1 5:8 5:11 5:10 2:-1 1:13 9:-1
-13:-1 6:8 5:11 5:10 11:-1
-12:-1 6:8 5:11 6:10 11:-1
-12:-1 4:12 3:8 4:11 7:10 10:-1
-11:-1 8:12 3:11 5:10 13:-1
-12:-1 9:12 1:11 2:10 16:-1
-11:-1 11:12 1:10 17:-1
-12:-1 10:12 1:10 17:-1
-11:-1 11:12 18:-1
+10:-1 1:2 11:1 3:16 15:-1
+4:-1 1:0 3:-1 2:2 11:1 5:16 14:-1
+7:-1 3:2 11:1 9:16 10:-1
+6:-1 4:2 11:1 11:16 8:-1
+6:-1 4:2 11:1 12:16 2:17 5:-1
+5:-1 4:2 11:1 12:16 3:17 5:-1
+6:-1 1:3 2:2 11:1 13:16 3:17 4:-1
+5:-1 3:3 11:1 13:16 4:17 4:-1
+5:-1 4:3 10:1 14:16 4:17 3:-1
+4:-1 6:3 8:1 14:16 6:17 2:-1
+4:-1 1:4 6:3 7:1 15:16 7:17
+3:-1 3:4 5:3 6:1 16:16 6:17 1:-1
+4:-1 3:4 5:3 5:1 1:6 16:16 6:17
+3:-1 4:4 5:3 6:6 15:16 7:17
+3:-1 5:4 2:3 2:5 7:6 15:16 6:17
+3:-1 5:4 3:5 8:6 14:16 7:17
+5:-1 6:5 8:6 2:7 13:16 6:17
+5:-1 5:5 8:6 3:7 12:16 7:17
+6:-1 5:5 7:6 4:7 12:16 6:17
+6:-1 4:5 7:6 5:7 11:16 7:17
+7:-1 4:5 6:6 7:7 10:16 6:17
+8:-1 2:5 6:6 9:7 7:16 3:15 5:17
+9:-1 1:5 6:6 11:7 10:15 3:17
+10:-1 5:6 11:7 12:15 2:17
+13:-1 2:6 11:7 13:15 1:18
+14:-1 11:7 13:15 2:18
+15:-1 10:7 13:15 2:18
+14:-1 10:7 13:15 3:18
+15:-1 2:9 7:7 13:15 3:18
+14:-1 4:9 5:7 13:15 4:18
+15:-1 5:9 3:7 13:15 4:18
+14:-1 8:9 1:12 12:15 5:18
+15:-1 6:9 3:12 11:15 5:18
+14:-1 5:9 5:12 9:15 6:18 1:-1
+15:-1 4:9 6:12 8:15 6:18 1:-1
+14:-1 4:9 7:12 7:15 5:18 3:-1
+14:-1 4:8 7:12 2:11 5:15 5:18 3:-1
+14:-1 3:8 8:12 5:11 2:14 4:18 4:-1
+14:-1 4:8 7:12 5:11 3:14 3:18 4:-1
+13:-1 5:8 6:12 5:11 4:14 1:18 6:-1
+14:-1 5:8 5:12 6:11 4:14 6:-1
+13:-1 5:8 5:12 5:11 2:-1 1:14 9:-1
+13:-1 4:8 3:13 4:12 5:11 11:-1
+12:-1 2:10 2:8 5:13 2:12 6:11 11:-1
+12:-1 4:10 7:13 7:11 10:-1
+11:-1 4:10 8:13 4:11 13:-1
+12:-1 4:10 8:13 16:-1
+11:-1 4:10 8:13 17:-1
+12:-1 4:10 7:13 17:-1
+11:-1 4:10 7:13 18:-1
[meta]
0|prov_panama|2|4,1
@@ -121,11 +121,12 @@ rows 50
7|prov_la_paz|1|17,24
8|prov_santiago|3|14,40
9|prov_antofagasta|1|14,31
-10|prov_buenos_aires|4|27,41
-11|prov_cordoba_ar|2|21,38
-12|prov_bariloche|1|13,47
-13|prov_montevideo|1|30,41
-14|prov_asuncion|1|29,32
-15|prov_manaus|2|26,12
-16|prov_belem|1|39,10
-17|prov_porto_alegre|2|35,37
+10|prov_temuco|1|12,45
+11|prov_buenos_aires|4|27,41
+12|prov_cordoba_ar|2|21,38
+13|prov_neuquen|1|17,45
+14|prov_montevideo|1|30,41
+15|prov_asuncion|1|29,32
+16|prov_manaus|2|26,12
+17|prov_belem|1|39,10
+18|prov_porto_alegre|2|35,37
diff --git a/app/src/main/assets/maps/europe.map b/app/src/main/assets/maps/europe.map
index 79bdc0f..4c6ab3d 100644
--- a/app/src/main/assets/maps/europe.map
+++ b/app/src/main/assets/maps/europe.map
@@ -13,12 +13,12 @@ rows 42
~~~~~~~~~~~~~~~-^^^^hhhhffffff-~~-------ffffffffffffff
~~~~~~~---~~~~~~-hhhhhhfffffff-~~~~-ffffffffffffffffff
~~~~~--ff-~~~~~~-------ffffff-~~~~-fffffffffffffffffff
-~~~~~-ffff-~~~~~~~~~~-fffffff-~~~~-fffffffffffffffffff
+~~~~~-ffff-~~~~~~~~~~~-ffffff-~~~~-fffffffffffffffffff
~~~~~-ffff-~~~~~~~~-----ffff-~~~~-fffffffffffffffffffr
-~~~~~~-fff-~~~~~~~~-fff--ff--~~~~-ffffffffffffffffffff
-~~~~---fff-~~~~~~~~-ff--f--~~~~~-fffffffffffffffffffff
+~~~~~~-fff-~~~~~~~~-fff---f--~~~~-ffffffffffffffffffff
+~~~~---fff-~~~~~~~~-fff-f--~~~~~-fffffffffffffffffffff
~~---f-fff-~~~~~~~~~-f-----------fffffffffffffffffffff
-~-fff--ff-~~~~~~~~~-f-ff-fffffffffffff:::::::::::::::f
+~-ffff-ff-~~~~~~~~~-f-ff-fffffffffffff:::::::::::::::f
~-ffff-fff-~~~~~~----ffffffff:::::::::::::::::::::::::
-ffff--ff-~--~~--ffff:::::::::::::::::::::::::::::::::
~-fff-~-ff--f-~-r:::::::::::::::::::::::::::::::::::::
@@ -45,102 +45,104 @@ rows 42
~-.........-~~~~~~~--~~----.-~~-....--..............hh
~~-........-~~----------...--~~~-...-~-..............h
~-.......-----hh^^^^^h----.-~~~~-..-~~--............hh
-~~----------hh^^^^^^^^h-~~--~~~~~---~~~~---..........h
+~~---..-----hh^^^^^^^^h-~~--~~~~~---~~~~---..........h
~~~~------hh^^^^^^^^^hh-~~~~~~~~~~~---~~~~-----.....hh
~~~~-hhhhhh^^^^^^^^^^^h-~~~~~~~~~~~-..-~~~~~~~~-.....h
~~~-hhhhh^^^^^^^^^^hhh.-~~~~~~~~~~~---~~~~~~~~-......-
[provinces]
-17:-1 9:32 4:30 3:-1 7:35 9:42 5:41
-16:-1 10:32 3:30 4:-1 7:35 8:42 6:41
-17:-1 9:32 5:30 3:-1 4:35 4:-1 6:42 6:41
-16:-1 10:32 4:30 10:-1 7:42 7:41
-17:-1 7:32 2:31 4:30 6:-1 3:36 8:42 7:41
-7:-1 2:2 14:-1 3:31 3:30 6:-1 4:36 7:42 8:41
-6:-1 4:2 12:-1 5:31 2:30 6:-1 5:36 6:42 8:41
-6:-1 4:2 14:-1 1:31 2:33 1:30 6:-1 6:36 5:42 9:41
-7:-1 3:2 10:-1 3:34 2:-1 2:33 7:-1 6:36 3:40 2:42 9:41
-7:-1 3:2 10:-1 2:34 2:-1 1:33 8:-1 5:36 6:40 10:41
-5:-1 1:3 1:-1 3:2 11:-1 1:18 11:-1 1:23 4:36 7:40 9:41
-2:-1 3:3 2:-1 2:1 11:-1 1:18 1:-1 1:18 1:17 1:-1 4:17 6:23 1:36 8:40 1:37 9:41
-2:-1 4:3 1:-1 3:1 11:-1 3:18 5:17 7:23 8:40 1:37 2:39 7:41
-1:-1 4:3 2:-1 2:1 8:-1 2:8 4:18 6:17 7:23 6:40 3:37 5:39 4:41
-2:-1 3:3 3:-1 2:1 2:-1 1:0 3:-1 3:8 1:20 3:18 6:17 8:23 4:40 4:37 7:39 2:41
-1:-1 1:3 5:-1 1:1 5:0 2:-1 2:7 3:20 2:18 7:17 7:23 3:40 6:37 9:39
-7:-1 1:1 5:0 2:-1 3:7 4:20 3:17 4:22 4:24 4:23 1:40 7:37 9:39
-14:-1 1:4 2:7 4:20 2:19 5:22 1:21 8:24 8:37 8:39 1:43
-12:-1 4:4 2:7 2:20 2:16 3:19 2:22 3:21 7:24 8:37 7:39 2:43
-8:-1 9:4 1:7 3:16 4:19 1:22 4:21 7:24 8:37 5:39 4:43
-7:-1 10:4 5:16 4:19 4:21 3:25 4:24 1:26 6:37 2:38 4:39 4:43
-8:-1 2:6 6:4 1:5 5:16 4:19 3:21 7:25 3:26 1:37 6:38 2:39 6:43
-9:-1 3:6 3:4 3:5 3:16 2:14 3:19 4:21 6:25 4:26 7:38 7:43
-10:-1 3:6 5:5 1:16 5:14 2:19 3:21 3:25 3:27 5:26 7:38 7:43
-10:-1 3:6 6:5 7:14 3:21 1:25 5:27 6:26 4:-1 2:38 4:-1 3:43
-10:-1 3:6 6:5 6:14 1:13 1:21 8:27 5:26 13:-1 1:43
-10:-1 4:6 5:5 3:14 2:-1 2:13 1:-1 7:27 2:28 4:26 11:-1 2:45 1:-1
-10:-1 3:6 1:10 5:5 3:-1 4:13 1:-1 6:27 3:28 3:26 12:-1 3:45
-2:-1 1:12 6:9 4:6 4:10 6:-1 3:13 3:-1 4:27 4:28 3:26 12:-1 2:45
-2:-1 1:12 7:9 1:6 4:10 8:-1 3:13 5:-1 1:27 5:28 2:26 14:-1 1:45
-3:-1 1:12 7:9 4:10 9:-1 2:13 2:15 3:-1 1:27 6:28 2:26 13:-1 1:45
-2:-1 2:12 7:9 3:10 6:-1 1:47 4:-1 4:15 2:-1 7:28 1:26 1:-1 3:44 11:45
-3:-1 2:12 7:9 2:10 6:-1 2:47 4:-1 4:15 2:-1 6:28 3:-1 2:44 11:45
-2:-1 3:12 7:9 8:-1 1:47 5:-1 3:15 2:-1 6:29 1:-1 2:46 2:44 12:45
-3:-1 2:12 1:11 6:9 8:-1 1:47 6:-1 2:15 3:-1 5:29 4:46 2:44 11:45
-2:-1 2:12 3:11 4:9 16:-1 1:15 4:-1 4:29 2:-1 4:46 12:45
-3:-1 1:12 5:11 2:9 13:-1 3:47 6:-1 3:29 3:-1 3:46 12:45
-2:-1 1:12 6:11 5:-1 4:48 4:47 4:-1 1:47 6:-1 2:29 5:-1 2:46 12:45
-12:-1 6:48 5:47 20:-1 11:45
-10:-1 8:48 5:47 24:-1 7:45
-5:-1 13:48 5:47 13:-1 2:29 10:-1 6:45
-4:-1 14:48 5:47 24:-1 6:45 1:-1
+17:-1 9:34 4:32 3:-1 7:37 9:44 5:43
+16:-1 10:34 3:32 4:-1 7:37 8:44 6:43
+17:-1 9:34 5:32 3:-1 4:37 4:-1 6:44 6:43
+16:-1 10:34 4:32 10:-1 7:44 7:43
+17:-1 7:34 2:33 4:32 6:-1 3:38 8:44 7:43
+7:-1 2:2 14:-1 3:33 3:32 6:-1 4:38 7:44 8:43
+6:-1 4:2 13:-1 4:33 2:32 6:-1 5:38 6:44 8:43
+6:-1 4:2 14:-1 3:33 1:32 6:-1 6:38 5:44 9:43
+7:-1 3:2 10:-1 3:36 3:-1 1:33 7:-1 6:38 3:42 2:44 9:43
+7:-1 3:2 10:-1 3:36 1:-1 1:35 8:-1 5:38 6:42 10:43
+5:-1 1:3 1:-1 3:2 11:-1 1:20 11:-1 1:25 4:38 7:42 9:43
+2:-1 3:3 1:4 1:-1 2:1 11:-1 1:20 1:-1 1:20 1:19 1:-1 4:19 6:25 1:38 8:42 1:39 9:43
+2:-1 4:3 1:-1 3:1 11:-1 3:20 5:19 7:25 8:42 1:39 2:41 7:43
+1:-1 4:3 2:-1 2:1 8:-1 2:9 4:20 6:19 7:25 6:42 3:39 5:41 4:43
+2:-1 3:3 3:-1 2:1 2:-1 1:0 3:-1 3:9 1:22 3:20 6:19 8:25 4:42 4:39 7:41 2:43
+1:-1 1:3 5:-1 1:1 5:0 2:-1 2:8 3:22 2:20 7:19 7:25 3:42 6:39 9:41
+7:-1 1:1 5:0 2:-1 3:8 4:22 3:19 4:24 4:26 4:25 1:42 7:39 9:41
+14:-1 1:5 2:8 4:22 2:21 5:24 1:23 8:26 8:39 8:41 1:45
+12:-1 4:5 2:8 2:22 2:18 3:21 2:24 3:23 7:26 8:39 7:41 2:45
+8:-1 9:5 1:8 3:18 4:21 1:24 4:23 7:26 8:39 5:41 4:45
+7:-1 10:5 5:18 4:21 4:23 3:27 4:26 1:28 6:39 2:40 4:41 4:45
+8:-1 2:7 6:5 1:6 5:18 4:21 3:23 7:27 3:28 1:39 6:40 2:41 6:45
+9:-1 3:7 3:5 3:6 3:18 2:16 3:21 4:23 6:27 4:28 7:40 7:45
+10:-1 3:7 5:6 1:18 5:16 2:21 3:23 3:27 3:29 5:28 7:40 7:45
+10:-1 3:7 6:6 7:16 3:23 1:27 5:29 6:28 4:-1 2:40 4:-1 3:45
+10:-1 3:7 6:6 6:16 1:15 1:23 8:29 5:28 13:-1 1:45
+10:-1 4:7 5:6 3:16 2:-1 2:15 1:-1 7:29 2:30 4:28 11:-1 2:47 1:-1
+10:-1 3:7 1:11 5:6 3:-1 4:15 1:-1 6:29 3:30 3:28 12:-1 3:47
+2:-1 1:14 6:10 4:7 4:11 6:-1 3:15 3:-1 4:29 4:30 3:28 12:-1 2:47
+2:-1 1:14 7:10 1:7 4:11 8:-1 3:15 5:-1 1:29 5:30 2:28 14:-1 1:47
+3:-1 1:14 7:10 4:11 9:-1 2:15 2:17 3:-1 1:29 6:30 2:28 13:-1 1:47
+2:-1 2:14 7:10 3:11 6:-1 1:49 4:-1 4:17 2:-1 7:30 1:28 1:-1 3:46 11:47
+3:-1 2:14 7:10 2:11 6:-1 2:49 4:-1 4:17 2:-1 6:30 3:-1 2:46 11:47
+2:-1 3:14 7:10 8:-1 1:49 5:-1 3:17 2:-1 6:31 1:-1 2:48 2:46 12:47
+3:-1 2:14 1:12 6:10 8:-1 1:49 6:-1 2:17 3:-1 5:31 4:48 2:46 11:47
+2:-1 2:14 3:12 4:10 16:-1 1:17 4:-1 4:31 2:-1 4:48 12:47
+3:-1 1:14 5:12 2:10 13:-1 3:49 6:-1 3:31 3:-1 3:48 12:47
+2:-1 1:14 6:12 5:-1 4:50 4:49 4:-1 1:49 6:-1 2:31 5:-1 2:48 12:47
+5:-1 1:12 1:13 5:-1 6:50 5:49 20:-1 11:47
+10:-1 8:50 5:49 24:-1 7:47
+5:-1 13:50 5:49 13:-1 2:31 10:-1 6:47
+4:-1 14:50 5:49 24:-1 6:47 1:-1
[meta]
0|prov_london|4|11,15
1|prov_manchester|2|9,12
2|prov_edinburgh|2|8,9
3|prov_dublin|2|5,12
-4|prov_paris|4|13,19
-5|prov_lyon|2|16,24
-6|prov_bordeaux|2|10,25
-7|prov_brussels|2|16,16
-8|prov_amsterdam|2|16,14
-9|prov_madrid|3|8,32
-10|prov_barcelona|2|14,30
-11|prov_seville|2|5,37
-12|prov_lisbon|2|2,35
-13|prov_rome|3|24,30
-14|prov_milan|3|21,24
-15|prov_naples|2|25,31
-16|prov_zurich|2|19,21
-17|prov_berlin|4|25,14
-18|prov_hamburg|2|21,12
-19|prov_munich|3|23,20
-20|prov_cologne|2|18,16
-21|prov_vienna|3|28,20
-22|prov_prague|2|25,17
-23|prov_warsaw|3|32,14
-24|prov_krakow|2|31,17
-25|prov_budapest|2|30,21
-26|prov_bucharest|2|38,26
-27|prov_belgrade|2|31,25
-28|prov_sofia|1|35,28
-29|prov_athens|2|35,36
-30|prov_stockholm|2|29,3
-31|prov_gothenburg|1|23,6
-32|prov_oslo|2|22,3
-33|prov_copenhagen|2|24,9
-34|prov_aarhus|1|22,8
-35|prov_helsinki|2|36,2
-36|prov_riga|1|35,7
-37|prov_kyiv|3|41,17
-38|prov_odesa|2|42,23
-39|prov_kharkiv|2|47,17
-40|prov_minsk|2|39,12
-41|prov_moscow|4|49,9
-42|prov_petersburg|3|41,3
-43|prov_rostov|2|51,22
-44|prov_istanbul|3|40,31
-45|prov_ankara|2|44,33
-46|prov_izmir|2|38,35
-47|prov_tunis|2|21,37
-48|prov_algiers|2|14,37
+4|prov_belfast|1|5,11
+5|prov_paris|4|13,19
+6|prov_lyon|2|16,24
+7|prov_bordeaux|2|10,25
+8|prov_brussels|2|16,16
+9|prov_amsterdam|2|16,14
+10|prov_madrid|3|8,32
+11|prov_barcelona|2|14,30
+12|prov_seville|2|5,37
+13|prov_gibraltar|1|6,38
+14|prov_lisbon|2|2,35
+15|prov_rome|3|24,30
+16|prov_milan|3|21,24
+17|prov_naples|2|25,31
+18|prov_zurich|2|19,21
+19|prov_berlin|4|25,14
+20|prov_hamburg|2|21,12
+21|prov_munich|3|23,20
+22|prov_cologne|2|18,16
+23|prov_vienna|3|28,20
+24|prov_prague|2|25,17
+25|prov_warsaw|3|32,14
+26|prov_krakow|2|31,17
+27|prov_budapest|2|30,21
+28|prov_bucharest|2|38,26
+29|prov_belgrade|2|31,25
+30|prov_sofia|1|35,28
+31|prov_athens|2|35,36
+32|prov_stockholm|2|29,3
+33|prov_gothenburg|1|23,6
+34|prov_oslo|2|22,3
+35|prov_copenhagen|2|24,9
+36|prov_aarhus|1|22,8
+37|prov_helsinki|2|36,2
+38|prov_riga|1|35,7
+39|prov_kyiv|3|41,17
+40|prov_odesa|2|42,23
+41|prov_kharkiv|2|47,17
+42|prov_minsk|2|39,12
+43|prov_moscow|4|49,9
+44|prov_petersburg|3|41,3
+45|prov_rostov|2|51,22
+46|prov_istanbul|3|40,31
+47|prov_ankara|2|44,33
+48|prov_izmir|2|38,35
+49|prov_tunis|2|21,37
+50|prov_algiers|2|14,37
diff --git a/app/src/main/assets/maps/north_africa.map b/app/src/main/assets/maps/north_africa.map
index c7fa970..3b6908f 100644
--- a/app/src/main/assets/maps/north_africa.map
+++ b/app/src/main/assets/maps/north_africa.map
@@ -11,8 +11,8 @@ rows 36
~~~-.........-~~~~~~~~~~~---.-~~-....-..............hh
~~~~-........-~-----------..--~~~-...---.............h
~~~~-....------h^^^^^^hh----~~~~~-.--~~-............hh
-~~~~~-------hh^^^^^^^^^h-~~~~~~~~~--~~~~--------.....h
-~~~~~--hhhh^^^^^^^^^^^hh-~~~~~~~~~~~~~~~~~~~~~-......-
+~~~~~---.---hh^^^^^^^^^h-~~~~~~~~~--~~~~--------.....h
+~~~~~----hh^^^^^^^^^^^hh-~~~~~~~~~~~~~~~~~~~~~-......-
~~~~~-hh^^^^^^^^^^^hhhh..---~~~~~~~~~~~~~~~~~~~-......
~~~~-^^^^^^^^^^hhhhh.......--~~~~~~~~~~~~~~~~~-......-
~~~~-^^^^^^^^^hhh............--~~~~------------.......
@@ -45,64 +45,65 @@ dddddddddddddddddddddddddddddddddddddddddddrrdd..-dddd
~~-jjjjjjjjjjjjjjjjjj...........................hh^^^-
[provinces]
-5:-1 1:1 1:0 21:-1 2:12 3:-1 1:2 8:-1 12:3
-4:-1 2:1 7:0 15:-1 1:12 4:-1 4:2 1:-1 4:4 8:3 4:5
-5:-1 1:1 7:0 13:-1 2:12 6:-1 3:2 3:-1 3:4 6:3 5:5
-5:-1 4:0 6:-1 4:13 5:12 10:-1 1:2 5:-1 2:4 5:3 7:5
-12:-1 7:13 5:12 24:-1 6:5
-7:-1 4:15 8:13 5:12 23:-1 6:5 1:-1
-6:-1 6:15 7:13 4:12 2:11 23:-1 6:5
-5:-1 6:15 8:13 2:12 6:11 20:-1 6:5 1:-1
-5:-1 7:15 7:13 2:12 8:11 18:-1 2:6 5:5
-4:-1 7:15 8:13 1:12 10:11 5:-1 7:9 3:8 4:6 5:5
-4:-1 8:15 7:13 1:12 13:11 9:9 4:8 4:6 4:5
-2:-1 9:15 3:13 6:14 13:11 8:9 4:8 5:6 4:5
-2:-1 10:15 1:13 9:14 11:11 8:9 5:8 2:-1 3:6 2:5 1:7
-11:15 11:14 11:11 7:9 5:8 1:10 1:-1 4:6 3:7
-11:15 12:14 10:11 7:9 3:8 4:10 1:-1 6:7
-10:15 14:14 9:11 6:9 2:8 6:10 1:-1 5:7 1:-1
-1:-1 4:15 6:17 15:14 7:11 6:9 9:10 1:-1 5:7
-3:15 8:17 16:14 6:11 5:9 10:10 1:-1 5:7
-3:16 9:17 17:14 3:11 2:20 4:9 11:10 1:-1 4:7
-3:16 10:17 15:14 6:20 3:9 12:10 1:-1 4:7
-4:16 10:17 13:14 8:20 2:9 13:10 2:-1 2:7
-4:16 10:17 11:14 1:19 9:20 12:21 2:10 3:-1 2:7
-5:16 10:17 9:14 2:19 10:20 14:21 3:-1 1:7
-5:16 10:17 7:14 3:19 10:20 15:21 3:-1 1:7
-6:16 10:17 3:14 6:19 11:20 15:21 3:-1
-7:16 9:17 1:14 8:19 10:20 15:21 4:-1
-8:16 9:17 8:19 11:20 15:21 3:-1
-8:16 8:17 9:19 11:20 13:21 3:22 2:-1
-10:16 6:17 9:19 12:20 11:21 5:22 1:-1
-11:16 3:17 2:18 9:19 12:20 10:21 7:22
-12:16 2:17 4:18 7:19 13:20 9:21 7:22
-12:16 7:18 6:19 12:20 8:21 9:22
-1:-1 11:16 8:18 5:19 13:20 6:21 10:22
-1:-1 10:16 9:18 5:19 12:20 6:21 11:22
-3:-1 8:16 11:18 3:19 13:20 5:21 11:22
-3:-1 7:16 13:18 2:19 12:20 5:21 11:22 1:-1
+5:-1 1:2 1:0 21:-1 2:13 3:-1 1:3 8:-1 12:4
+4:-1 2:2 7:0 15:-1 1:13 4:-1 4:3 1:-1 4:5 8:4 4:6
+5:-1 1:2 7:0 13:-1 2:13 6:-1 3:3 3:-1 3:5 6:4 5:6
+5:-1 4:0 6:-1 4:14 5:13 10:-1 1:3 5:-1 2:5 5:4 7:6
+8:-1 1:1 3:-1 7:14 5:13 24:-1 6:6
+9:-1 2:16 8:14 5:13 23:-1 6:6 1:-1
+6:-1 6:16 7:14 4:13 2:12 23:-1 6:6
+5:-1 6:16 8:14 2:13 6:12 20:-1 6:6 1:-1
+5:-1 7:16 7:14 2:13 8:12 18:-1 2:7 5:6
+4:-1 7:16 8:14 1:13 10:12 5:-1 7:10 3:9 4:7 5:6
+4:-1 8:16 7:14 1:13 13:12 9:10 4:9 4:7 4:6
+2:-1 9:16 3:14 6:15 13:12 8:10 4:9 5:7 4:6
+2:-1 10:16 1:14 9:15 11:12 8:10 5:9 2:-1 3:7 2:6 1:8
+11:16 11:15 11:12 7:10 5:9 1:11 1:-1 4:7 3:8
+11:16 12:15 10:12 7:10 3:9 4:11 1:-1 6:8
+10:16 14:15 9:12 6:10 2:9 6:11 1:-1 5:8 1:-1
+1:-1 4:16 6:18 15:15 7:12 6:10 9:11 1:-1 5:8
+3:16 8:18 16:15 6:12 5:10 10:11 1:-1 5:8
+3:17 9:18 17:15 3:12 2:21 4:10 11:11 1:-1 4:8
+3:17 10:18 15:15 6:21 3:10 12:11 1:-1 4:8
+4:17 10:18 13:15 8:21 2:10 13:11 2:-1 2:8
+4:17 10:18 11:15 1:20 9:21 12:22 2:11 3:-1 2:8
+5:17 10:18 9:15 2:20 10:21 14:22 3:-1 1:8
+5:17 10:18 7:15 3:20 10:21 15:22 3:-1 1:8
+6:17 10:18 3:15 6:20 11:21 15:22 3:-1
+7:17 9:18 1:15 8:20 10:21 15:22 4:-1
+8:17 9:18 8:20 11:21 15:22 3:-1
+8:17 8:18 9:20 11:21 13:22 3:23 2:-1
+10:17 6:18 9:20 12:21 11:22 5:23 1:-1
+11:17 3:18 2:19 9:20 12:21 10:22 7:23
+12:17 2:18 4:19 7:20 13:21 9:22 7:23
+12:17 7:19 6:20 12:21 8:22 9:23
+1:-1 11:17 8:19 5:20 13:21 6:22 10:23
+1:-1 10:17 9:19 5:20 12:21 6:22 11:23
+3:-1 8:17 11:19 3:20 13:21 5:22 11:23
+3:-1 7:17 13:19 2:20 12:21 5:22 11:23 1:-1
[meta]
0|prov_seville|2|7,2
-1|prov_lisbon|2|4,1
-2|prov_athens|2|36,2
-3|prov_ankara|2|45,0
-4|prov_izmir|2|39,1
-5|prov_damascus|2|48,6
-6|prov_jerusalem|2|47,8
-7|prov_jeddah|2|50,19
-8|prov_cairo|4|43,10
-9|prov_alexandria|2|41,9
-10|prov_aswan|1|45,16
-11|prov_tripoli|2|25,7
-12|prov_tunis|2|22,3
-13|prov_algiers|2|15,3
-14|prov_tamanrasset|1|18,18
-15|prov_casablanca|2|6,6
-16|prov_bamako|1|5,29
-17|prov_timbuktu|1|10,24
-18|prov_lagos|3|16,35
-19|prov_kano|2|21,29
-20|prov_ndjamena|1|27,29
-21|prov_khartoum|2|44,25
-22|prov_addis|2|50,32
+1|prov_gibraltar|1|8,4
+2|prov_lisbon|2|4,1
+3|prov_athens|2|36,2
+4|prov_ankara|2|45,0
+5|prov_izmir|2|39,1
+6|prov_damascus|2|48,6
+7|prov_jerusalem|2|47,8
+8|prov_jeddah|2|50,19
+9|prov_cairo|4|43,10
+10|prov_alexandria|2|41,9
+11|prov_aswan|1|45,16
+12|prov_tripoli|2|25,7
+13|prov_tunis|2|22,3
+14|prov_algiers|2|15,3
+15|prov_tamanrasset|1|18,18
+16|prov_casablanca|2|6,6
+17|prov_bamako|1|5,29
+18|prov_timbuktu|1|10,24
+19|prov_lagos|3|16,35
+20|prov_kano|2|21,29
+21|prov_ndjamena|1|27,29
+22|prov_khartoum|2|44,25
+23|prov_addis|2|50,32
diff --git a/app/src/main/assets/maps/sea_asia.map b/app/src/main/assets/maps/sea_asia.map
index 725a58f..b4d2b1c 100644
--- a/app/src/main/assets/maps/sea_asia.map
+++ b/app/src/main/assets/maps/sea_asia.map
@@ -14,21 +14,21 @@ rows 40
-...-..--:::...-----~~~---~~~~~~~~~~~~~~~~~~~~~~~~~~~~
....---.::::.--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-.jj--jjj:::..-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-.jj-jjjj::::.-~~~~~~~~~-----~~~~~~~~~~~~~~~~~~~~~~~~~~
---j-jjjjj:::..-~~~~~~~~-....-~~~~~~~~~~~~~~~~~~~~~~~~~
--jjjjjjj::::..-~~~~~~~~-....-~~~~~~~~~~~~~~~~~~~~~~~~~
-~--jjjjjj:::j.-~~~~~~~~-.....-~~~~~~~~~~~~~~~~~~~~~~~~
-~~-jjjjj::::j.-~~~~~~~~-.....-~~~~~~~~~~~~~~~~~~~~~~~~
-~~-jjjjjj:::j.-~~~~~~~~-......-~~~~~~~~~~~~~~~~~~~~~~~
-~~-jjjjjj:::j-~~~~~~~~~-.....-~~~~~~~~~~~~~~~~~~~~~~~~
-~~~---jjj:::j-~~~~~~~~~-......-~~~~~~~~~~~~~~~~~~~~~~~
-~~~~-jjjj:::-~~~~~~~~~~-.....-~~~~~~~~~~~~~~~~~~~~~~~~
-~~~~~-jjj::--~~~~~~~~~~-......-~~~~~~~~~~~~~~~~~~~~~~~
-~~~~-jjj.:-~~~~~~~~~~~~-......-~~~~~~~~~~~~~~~~~~~~~~~
-~~~~~-....-~~~~~~~~~~~~~-.....-~~~~~~~~~~~~~~~~~~~~~~~
-~~~~-..---~~~~~~~~~--~~~-.....-~~~~~~~~~~~~~~~~~~~~~~~
-~~~~~----~~~~~~~~~~-.-~~~-...--~~~~~~~~~~~~~~~~~~~~~~~
-~--~-jjj-~~~~~~~~~~--~~~~----~~~~~~~~~~~~~~~~~~~~~~~~~
+.jj-jjjj::::.-~~~~~~~~~---~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+--j-jjjjj:::..-~~~~~~~~-..-~~~~~~~~~~~~~~~~~~~~~~~~~~~
+-jjjjjjj::::..-~~~~~~~~-..-~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~--jjjjjj:::j.-~~~~~~~~-..-~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~-jjjjj::::j.-~~~~~~~~-.-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~-jjjjjj:::j.-~~~~~~~~~-.--~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~-jjjjjj:::j-~~~~~~~~~~--.-~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~---jjj:::j-~~~~~~~~~~~~-.--~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~-jjjj:::-~~~~~~~~~~~~-...-~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~-jjj::--~~~~~~~~~~~~-...-~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~-jjj.:-~~~~~~~~~~~~~~---.-~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~-....-~~~~~~~~~~~~~~~-...-~~~~~~~~~~~~~~~~~~~~~~~
+~~~~-..---~~~~~~~~~--~~~~-....-~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~----~~~~~~~~~~-.-~~~~--..-~~~~~~~~~~~~~~~~~~~~~~~
+~--~-jjj-~~~~~~~~~~--~~~~~~---~~~~~~~~~~~~~~~~~~~~~~~~
~-j---jjj-~~~~~~-------~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~-jj--jjj-~~~~--jjjjjj-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~-jjj-jj-~~~~-jjjjjjj-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -49,27 +49,27 @@ rows 40
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-..-~~~-...-~~~~~~~~
[provinces]
-2:-1 11:1 1:9 6:0 3:2 2:-1 1:3 28:-1
-2:-1 10:1 1:9 6:0 2:2 3:-1 1:3 29:-1
-4:-1 7:1 3:9 5:0 2:2 3:-1 1:4 1:3 28:-1
+2:-1 11:1 1:9 9:0 2:-1 1:3 28:-1
+2:-1 10:1 1:9 8:0 3:-1 1:3 29:-1
+4:-1 7:1 3:9 7:0 3:-1 1:4 1:3 28:-1
1:-1 2:6 1:-1 5:1 4:9 5:0 1:2 4:-1 2:4 29:-1
1:-1 3:6 1:-1 2:1 2:-1 5:9 1:0 39:-1
4:6 3:-1 6:9 41:-1
1:-1 2:6 1:5 2:-1 2:8 6:9 40:-1
3:5 1:-1 4:8 5:9 41:-1
-2:-1 1:5 1:-1 4:8 1:7 5:9 10:-1 4:20 26:-1
-1:-1 3:5 2:8 3:7 5:9 10:-1 4:20 26:-1
-3:-1 2:5 6:7 3:9 10:-1 5:20 25:-1
-3:-1 1:5 6:7 4:10 10:-1 5:20 25:-1
-3:-1 7:7 4:10 10:-1 5:20 1:21 24:-1
-3:-1 5:7 2:11 3:10 11:-1 3:20 2:21 25:-1
-6:-1 2:7 3:11 2:10 11:-1 2:20 4:21 24:-1
-5:-1 2:7 3:11 2:10 12:-1 5:21 25:-1
-6:-1 1:7 4:11 13:-1 6:21 24:-1
-5:-1 1:7 4:11 14:-1 6:21 24:-1
-6:-1 4:11 15:-1 5:21 24:-1
-5:-1 2:11 18:-1 5:21 24:-1
-20:-1 1:13 5:-1 3:21 25:-1
+2:-1 1:5 1:-1 4:8 1:7 5:9 10:-1 2:20 28:-1
+1:-1 3:5 2:8 3:7 5:9 10:-1 2:20 28:-1
+3:-1 2:5 6:7 3:9 10:-1 2:20 28:-1
+3:-1 1:5 6:7 4:10 10:-1 1:20 29:-1
+3:-1 7:7 4:10 11:-1 1:20 28:-1
+3:-1 5:7 2:11 3:10 13:-1 1:21 27:-1
+6:-1 2:7 3:11 2:10 14:-1 1:21 26:-1
+5:-1 2:7 3:11 2:10 14:-1 3:21 25:-1
+6:-1 1:7 4:11 15:-1 3:21 25:-1
+5:-1 1:7 4:11 18:-1 1:21 25:-1
+6:-1 4:11 17:-1 3:21 24:-1
+5:-1 2:11 19:-1 4:21 24:-1
+20:-1 1:13 7:-1 2:21 24:-1
5:-1 3:12 46:-1
2:-1 1:17 3:-1 3:12 45:-1
2:-1 2:17 2:-1 3:12 7:-1 6:18 32:-1
diff --git a/app/src/main/assets/maps/world.map b/app/src/main/assets/maps/world.map
index cc5c1fe..8cbbc39 100644
--- a/app/src/main/assets/maps/world.map
+++ b/app/src/main/assets/maps/world.map
@@ -8,8 +8,8 @@ rows 76
wrap x
[terrain]
-~~~~~~~~~~~~~~~~~~~~~~~---~~~~-********-~~~~~~~~~~~~~~~~~~~~~--~~~~~~~~~~~~~~~~----------*********------------------~~~~
-~--------~~~~~~~~~~~~--tt---~~-ttttttt-~~~~~~~~~~~~~~~~~-----t---~--~~~~~~~~~--tttttttttttttttttttttttttttttttttttt---~~
+~~~~~~~~~~~~~~~~~~~~~~~---~~~~-********-~~~~~~~~~~~~~~~~~~--------~~~~~~~~~~~~~----------*********------------------~~~~
+~--------~~~~~~~~~~~~--tt---~~-ttttttt-~~~~~~~~~~~~~~~~~--ttttttt---~~~~~~~~~--tttttttttttttttttttttttttttttttttttt---~~
~-ttttttt-------------tttttt-~~-tttttt-~~~~~~~~~~~~~~~~--^^^^^^tt--t---~~-----^^tttttttttttttttttttttttttttttttttttttt--
-ttttttttttttttttttttttttttt-~~-ttttt---~~~~~~~~~~~~~~-^^^^^^ttttttttt---tttt^^tttttttttttttttttttttttttttttttttttttttt-
~-fh^hhffffffffffffffffffffff-~~-ffff--f-~~~~~~~~~~~~~-^^^^hh-fffffffffffffffh^^hfrrffffffffffffffffffffffffffffffffffff
@@ -20,28 +20,28 @@ wrap x
-fh^^^^hffffffffff-~~~~-fffff-~~~--~~~~~~~~~~~~~~-^^^hhffff---f--fffffffffffh^^hfffrffffffffffffffffhhhhhhhhhhhhhhffh^-~
~-fh--^hhffffffffff-~~~-ffffff-~~~~~~~~~~~~~---~~~-hhhhffff-~----ffffffffffffh^^ffffrffffffffffffhhhhhhh^^^^^^^^hhhff^-~
-ff-~-^hhfffffffff-----ffffff-~~~~~~~~~~~~~-ff-~~~----ffff-~-fffffffffffffffh^^hfffrrffffffffhhhhhhh^^^^^^^^^^^^^hh-h-~~
-~-ff-~-^hfffffffffffffffffffff-~~~~~~~~~~~~~-ff-~~~~---fff-~-fffffffffffrrfffh^hffffrffffffhhhhhh^^^^^^^^^^^^^^^^hh---~~
--ff-~-^hhfffffffffffffffffffff-~~~~~~~~~~~--ff-~~~~-fff-----ffffffffffffrrffh^^-ffffrfffffhhh^^^^^^^^^^^^^^^^^^^^---h-~~
-~---~~-^hhfffffffffffffffffffff-~~~~~~~~~--f-ff-~~~~-f-----fffffffffff::frrffh^--ffffrffffh^^^^^^^^^^^^^^^^^^^^^h-~~--~~
+~-ff-~-^hfffffffffffffffffffff-~~~~~~~~~~~~~-ff-~~~~----ff-~-fffffffffffrrfffh^hffffrffffffhhhhhh^^^^^^^^^^^^^^^^hh---~~
+-ff-~-^hhfffffffffffffffffffff-~~~~~~~~~~~---f-~~~~-fff-----ffffffffffffrrffh^^-ffffrfffffhhh^^^^^^^^^^^^^^^^^^^^---h-~~
+~---~~-^hhfffffffffffffffffffff-~~~~~~~~~--ff-f-~~~~-f-----fffffffffff::frrffh^--ffffrffffh^^^^^^^^^^^^^^^^^^^^^h-~~--~~
~~~~~~-^hhfffffffffffffffffffff-~~~~~~~~-fff-f-~~----fffff:::::::::::::::rffh^^ffffffffffh^^^^^^^^^^^^hhhhhhhhhh-~~-^-~~
~~~~~~~-^hhffffffffffffffffffff-~~~~~~~~~-ff-ff---ff::::::::::::::::::::::rffh^hfff-fffhhhh^^^^^^^^hhhhhhhhhhhhhf-~~-^-~
~~~~~~-^^hhfffffffffffffffffff--~~~~~~~~-f---ff:-rr::::::::::::::::::::::rrff^^fffffffhh^^^^^^^hhhhhhffffffffffff-~~--~~
~~~~~~~-^^hhffffffffffffffffff-f-~~~~~~~~--~~-----:r::::::hhhh:::::::::::frffh^hffffffh^^^---hhhhhfffffffffffffff-~~~~~~
~~~~~~-^^^hhfffffffffffffffff-ff-~~~~~~~~~~~---::::rhhhhhh^^^^h:::::::::ffrffhhffffffh^^--^^hhfffffffffffffffffff-~~~~~~
-~~~~~~~-^^^hhfffffffffffffffff-f-~~~~~~~~~~~-fff:hhhr^^^^^^^^^^h:::::::::fffffhfffffff^^-^^^hhffffffffffffffffff--~~~~~~
-~~~~~~~-^^^hhfffffffffffffffff--~~~~~~~~~~~~-fffhh^^^^^^^^^^^^^hh::::::::frffffffffffh^^hhhhfffffffffffffffff---~~~~~~~~
-~~~~~~~-^^^^hhfff::ffffffhhhff-~~~~~~~~~~~~~~--ffh^^^^^^^^^^^^^^hh-::::ffff-ffffffffffhhhffffffffffffffffffff-~~--~~~~~~
-~~~~~~~-^^^^hhff::r--fffh^^hf-~~~~~~~~~~~~~~~-ffh^^^^^hhhr^^^^^^--------hhf-fffffhhhhhhhhfdddddfffffffffffff-~~-f--~~~~~
-~~~~~~~-^^^^^hhf:::r-----^^h-f-~~~~~~~~~~~-----hhhhhh-hh-hhrr^^^-~~~~~-^^----ffffhhhh^^^hfddddddddffffffffff--~~-ff-~~~~
-~~~~~~~-^^^^^hh.::::---h-^^---~~~~~~~~~~~-...^^^^h----..--..hhhh-~~~~~-^^^-~-....^^^-^^^h.dddddddd.........-.-~-..-~~~~~
+~~~~~~~-^^^hhfffffffffffffffff-f-~~~~~~~~~~~-fff:hhhr^^^^^^^^^^h:::::::::fffffhfffffff^^-^^^hhfffffffffffffffffff-~~~~~~
+~~~~~~~-^^^hhfffffffffffffffff--~~~~~~~~~~~~-fffhh^^^^^^^^^^^^^hh::::::::frffffffffffh^^hhhhffffffffffffffffffff-~~~~~~~
+~~~~~~~-^^^^hhfff::ffffffhhhff-~~~~~~~~~~~~~~--ffh^^^^^^^^^^^^^^hh-::::ffff-ffffffffffhhhfffffffffffffffffffffff--~~~~~~
+~~~~~~~-^^^^hhff::r--fffh^^hf-~~~~~~~~~~~~~~~-ffh^^^^^hhhr^^^^^^--------hhf-fffffhhhhhhhhfdddddffffffffffffffff-f--~~~~~
+~~~~~~~-^^^^^hhf:::r-----^^h-f-~~~~~~~~~~~-----hhhhhh-hh-hhrr^^^-~~~~~-^^----ffffhhhh^^^hfddddddddfffffffffffff--ff-~~~~
+~~~~~~~-^^^^^hh.::::---h-^^---~~~~~~~~~~~-...^^^^h----..--..hhhh-~~~~~-^^^-~-....^^^-^^^h.dddddddd...........---..-~~~~~
~~~~~~~-h^^^^^^h:::r:::-^^^-~~~~~~~~~~~~~-...h^^^^-~---..--...hh--------^^^--.dddh^^-^^^h.ddddddddd.........--~-.h-~~~~~
~~~~~~~-^^^^^^hh:::r::h^^^-~~~~~~~~~~~~~~-....hhh-~-.--...-....-.......hhh^h-ddd.h--^^^d...ddddddd.........-~~--^-~~~~~~
~~~~~~~~-^d^^^^h::::::h^^^-~~~~~~~~~~~~~~-......--~~--~--.-....--........hh--.ddd--~-dddh..........:.......-~~-.^^-~~~~~
~~~~~~~-^^d^^^^h:::r::^^^-~~~~~~~~~~~~~~-......-~~~~~~--.---..-.........h^h--ddd----ddddhhh.......::::.--..-~-.^^-~~~~~~
~~~~~~~~-^dd^^^hh:::r:^^^-~~~~~~~~~~~~~~~-.....--------..-~-..--........h^^-..dd-h^-ddddhhhh.......::r---..-~-h^^h-~~~~~
-~~~~~~~~-^dd^^^h.::r:^^^h-~~~~~~~~~~~~~~~-------h^^^^h---~~---~-.......hh^^h.d--^^^^^^^^^hhhhr....:rr:-~-..--h^^h-~~~~~~
-~~~~~~~~~-^dd^^^h:::rh^^h-~~~~~~~~~~~~~~~~~----h^^^^^^-~~~~~~~~~-----...h^^^...-^^^^^^^^^^^hhrrrrrrrr:-~~-..-.h^h-~~~~~~
-~~~~~~~~~-^d^^^h.:.rh^^h-~~~~~~~~~~~~~~~~~-hhh^^^^^^hh--~~~~~~~~~~~-....h^^hdd.h^^^^^^^^^^^hh..rrrr:::-~~---..hh.-~~~~~~
+~~~~~~~~-^dd^^^h.::r:^^^h-~~~~~~~~~~~~~~~--..---h^^^^h---~~---~-.......hh^^h.d--^^^^^^^^^hhhhr....:rr:-~-..--h^^h-~~~~~~
+~~~~~~~~~-^dd^^^h:::rh^^h-~~~~~~~~~~~~~~~~~-.--h^^^^^^-~~~~~~~~~-----...h^^^...-^^^^^^^^^^^hhrrrrrrrr:-~~-..-.h^h-~~~~~~
+~~~~~~~~~-^d^^^h.:.rh^^h-~~~~~~~~~~~~~~~~~---h^^^^^^hh--~~~~~~~~~~~-....h^^hdd.h^^^^^^^^^^^hh..rrrr:::-~~---..hh.-~~~~~~
~~~~~~~~~-^dd^^^h...r^^h-~~~~~~~~~~~~~~~~~-^^^^^^^hhh...-~~~~~~~~~~~-....h^^hdd.^hh^^^^^^^^^hh.....::::-~~-.-..---~~~~~~
~~~~~~~~~-d.h^^hh..rh^h-~~~~~~~~~~~~~~~~~-^^^^^^hh......--~~--------.....h^^ddd.hhh^^^^^^^^hh.....::::r-~~-.---~~~~~~~~~
~~~~~~~~~~-.h^^^h...rhh.-~~~~~~~~~~~~~~~~-^^^^^hh.........---.....-.......h^^dd...:h^^^^^^^^hh....rrrrr.-~~--~~~~~~~~~~~
@@ -51,15 +51,15 @@ wrap x
~~--~~~~~~~~-.h^^.-~~~---~~~~~~~~~~~~~~-ddddddddddddddddddddddddddrd.-dddddddhh--.d..:hrhh-..........--.-~~~~~~~~~~~~~~~
~-.-~~~~~~~~-.^^^-~---.--~~~~~~~~~~~~~~-ddddddddddddddddddddddddddrd.-ddddddd.-~--.....r.-.........---.-~~~~~~~~~~~~~~~~
~~--~~~~~~~~~--^^^--.--..---~~~~~~~~~~~-dddddddddddddddddddddddddddrd.-dddddd..-~~-....---..-.::.---~~--~~~~~~~~~~~~~~~~
-~~~~~~~~~~~~~~--^^-..----..-~~~~~~~~~~-...ddddddddddddddddddddddddr...-ddddd..-~~-....-~~-jjj::.-~~~~----~~~~~~~~~~~~~~~
-~~~~~~~~~~~~~~~~--^^j-~~~---~~~~~~~~~~~-.....dddddddddddddddddddd..r...--.dd.--~~~-...-~~-.jjj::.-~~~-...-~~~~~~~~~~~~~~
-~~~~~~~~~~~~~~~~~--hj-~~~~~~~~~~~~~~~~-..............ddddddddd....rhhh--....-~~~~~-..-~~~--jj::j-~~~~-...-~~~~~~~~~~~~~~
-~~~~~~~~~~~~~~~~~~~-----~~--~~~~~~~~~~~-...........................r^^hh--.--~~~~~-...-~~~-jjj::-~~~~-....-~~~~~~~~~~~~~
-~~~~~~~~~~~~~~~~~~~~~-j-~-h---~~~~~~~~~-..........................r^^^^h.--.-~~~~~-.--~~~~--jj:.-~~~~-...-~~~~~~~~~~~~~~
-~~~~~~~~~~~~~~~~~~~~~~-.--^h..-~~~~~~~~-..........................rhh^^^hh..-~~~~~~--.-~~~~-jj:--~~~~-....-~~~~~~~~~~~~~
-~~~~~~~~~~~~~~~~~~~~~~-.h^^h..--~~~~~~~--jjjjjjjj...................h^^^^h.-~~~~~~~-.-~~~~~-.--~~~~---...-~~~~~~~~~~~~~~
-~~~~~~~~~~~~~~~~~~~~~~~-h^^h....-~~~~~~~~-jjjjjjjj-jj................hh^^h.-~~~~~~~~--~~~~---j-~~~--.--.--~~~~~~~~~~~~~~
-~~~~~~~~~~~~~~~~~~~~~~~-^^h.....-~~~~~~~~------------.....jj..........hhhh.-~~~~~~~~~~~~~-j-jj-~--jjj---~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~--^^-..----..-~~~~~~~~~~-...ddddddddddddddddddddddddr...-ddddd..-~~-....-~~-jjj::.-~~~~---~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~--^^j-~~~---~~~~~~~~~~~-.....dddddddddddddddddddd..r...--.dd.--~~~-...-~~-.jjj::.-~~~-..-~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~--hj-~~~~~~~~~~~~~~~~-..............ddddddddd....rhhh--....-~~~~~-..-~~~--jj::j-~~~~-.-~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~-----~~--~~~~~~~~~~~-...........................r^^hh--.--~~~~~-...-~~~-jjj::-~~~~~----~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~-j-~-h---~~~~~~~~~-..........................r^^^^h.--.-~~~~~-.--~~~~--jj:.-~~~~~-..-~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~-.--^h..-~~~~~~~~-..........................rhh^^^hh..-~~~~~~--.-~~~~-jj:--~~~~~~-.-~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~-.h^^h..--~~~~~~~--jjjjjjjj...................h^^^^h.-~~~~~~~-.-~~~~~-.--~~~~--~-..-~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~-h^^h....-~~~~~~~~-jjjjjjjj-jj................hh^^h.-~~~~~~~~--~~~~---j-~~~--.-~---~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~-^^h.....-~~~~~~~~------------.....jj..........hhhh.-~~~~~~~~~~~~~-j-jj-~--jjj-~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~-h^^jjjjj.-~~~~~~~~~~~~~~~~~~-jjjjjjjjjjj...........-~~~~~~~~~~~~~~-j--j--jjjj----~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~-h^^jjjjjjj-~~~~~~~~~~~~~~~~~~-jjjjjjjjjrj.........--~~~~~~~~~~~~~~~-jj---jjjj-j..-~~-----~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~-h^^jjjjjrrj--~~~~~~~~~~~~~~~~~-jjjjjjrrrj.........-~~~~~~~~~~~~~~~~~-jj-~-jjjj-j..-~-jjhh---~~~~~
@@ -86,328 +86,335 @@ wrap x
~~~~~~~~~~~~~~~~~~~~~~~~~-^-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[provinces]
-31:-1 8:204 50:-1 9:61 22:-1
-23:-1 2:202 6:-1 7:204 23:-1 1:33 17:-1 19:61 15:59 2:60 5:-1
-2:-1 6:195 1:203 13:-1 6:202 4:-1 6:204 19:-1 2:41 4:33 2:38 2:-1 1:53 10:-1 2:54 19:61 14:59 5:60 2:-1
-1:-1 7:195 11:203 9:202 4:-1 5:204 18:-1 3:41 4:33 3:38 5:53 3:-1 6:54 1:52 18:61 14:59 7:60 1:-1
-2:-1 6:195 11:203 10:202 4:-1 4:204 2:-1 1:40 15:-1 2:32 1:41 3:33 1:-1 4:38 4:53 9:54 3:52 16:61 15:59 7:60
-1:-1 7:195 11:203 2:202 2:-1 6:202 4:-1 3:204 3:-1 1:40 14:-1 5:32 1:33 2:-1 4:38 3:53 9:54 5:52 14:61 15:59 7:60 1:-1
-2:-1 6:195 12:203 4:-1 5:202 3:-1 4:204 3:-1 1:40 13:-1 2:34 4:32 2:-1 5:38 3:47 8:54 7:52 9:61 4:57 1:58 15:59 7:60
-1:-1 7:195 11:203 5:-1 5:202 4:-1 2:204 16:-1 4:34 3:32 2:-1 4:37 5:47 7:54 8:52 7:61 5:57 2:58 14:59 7:60 1:-1
-2:-1 7:195 10:203 5:-1 5:202 5:-1 1:204 16:-1 5:34 2:32 3:-1 4:37 5:47 5:54 2:48 7:52 3:55 9:57 3:58 13:59 7:60 1:-1
-1:-1 7:195 10:203 6:-1 5:202 21:-1 5:34 1:31 3:30 3:-1 1:37 2:-1 4:47 3:46 4:48 1:49 6:52 3:55 1:56 8:57 4:58 12:59 7:60 2:-1
-2:-1 2:195 2:-1 3:195 10:203 5:-1 6:202 21:-1 3:34 2:31 3:30 6:-1 3:47 4:46 4:48 2:49 5:52 3:55 2:56 7:57 5:58 11:59 7:60 2:-1
-1:-1 2:195 3:-1 2:195 9:203 1:200 5:-1 6:202 15:-1 2:2 8:-1 2:31 2:30 3:-1 3:39 3:47 5:46 3:48 2:49 5:52 3:55 3:56 6:57 6:58 11:59 4:60 1:-1 1:60 3:-1
-2:-1 2:195 3:-1 2:195 8:199 6:200 7:202 15:-1 2:2 8:-1 2:31 1:30 3:-1 5:39 1:47 5:46 3:48 3:49 4:52 3:55 3:56 6:57 7:58 10:59 4:60 5:-1
-1:-1 2:195 3:-1 2:195 8:199 7:200 7:202 14:-1 2:2 6:-1 2:36 1:35 5:-1 4:39 2:45 6:46 3:48 3:49 1:52 1:-1 1:52 4:55 3:56 5:57 8:58 10:59 2:60 3:-1 1:60 3:-1
-7:-1 2:198 7:199 8:200 7:202 12:-1 1:3 1:-1 2:1 6:-1 1:18 5:-1 3:23 1:39 4:45 5:46 3:48 3:49 1:52 2:-1 4:55 4:56 4:57 9:58 5:59 5:63 1:60 7:-1
-7:-1 2:198 6:199 8:200 8:197 10:-1 3:3 1:-1 1:1 7:-1 1:18 4:17 4:23 4:45 1:42 5:46 3:48 3:49 1:52 1:67 5:55 3:56 4:57 9:58 4:142 7:63 4:-1 1:64 3:-1
-8:-1 2:198 6:199 7:200 8:197 11:-1 2:3 1:-1 2:1 3:-1 3:8 1:18 4:17 5:23 2:45 3:42 3:44 1:46 4:48 1:49 3:67 2:65 1:55 1:-1 1:55 4:56 3:57 10:58 4:142 7:63 4:-1 1:64 2:-1
-7:-1 3:198 5:199 7:200 8:197 11:-1 1:3 3:-1 3:0 1:-1 2:7 1:20 1:18 3:17 2:22 1:24 3:23 1:45 4:42 5:44 4:50 4:67 4:65 1:55 4:56 2:57 10:58 5:142 7:63 7:-1
-8:-1 3:198 4:199 8:200 7:197 1:-1 1:201 18:-1 1:7 2:20 1:19 1:17 3:22 3:24 2:23 5:42 4:44 4:50 4:67 6:65 4:56 3:-1 3:58 5:72 6:142 6:63 7:-1
-7:-1 4:198 3:199 8:200 7:197 1:-1 2:201 15:-1 3:4 1:7 1:20 1:16 2:19 1:22 2:21 3:24 1:23 5:42 4:44 1:51 4:50 4:67 6:65 2:56 2:-1 3:58 8:72 6:142 6:63 7:-1
-8:-1 4:192 3:199 5:200 3:187 6:197 1:201 1:-1 1:201 13:-1 7:4 2:16 2:19 3:21 1:25 2:24 1:23 4:42 3:44 2:51 5:50 3:67 6:65 2:145 1:-1 1:145 11:72 6:142 5:63 8:-1
-8:-1 5:192 1:199 3:200 5:187 6:197 2:201 15:-1 2:6 3:4 1:5 3:16 2:19 2:21 4:25 1:26 4:43 2:44 3:51 5:50 3:67 5:65 5:145 10:72 7:142 2:63 11:-1
-8:-1 6:192 9:187 5:197 2:201 17:-1 1:6 1:4 3:5 3:14 1:19 2:21 2:25 2:27 2:26 2:43 1:-1 1:43 1:44 4:51 2:50 1:-1 2:50 2:67 2:65 4:66 5:145 9:72 8:142 1:63 11:-1
-8:-1 4:192 1:188 6:187 2:-1 1:187 5:197 1:180 1:201 17:-1 2:6 3:5 4:14 1:13 1:21 1:25 3:27 3:26 8:-1 3:50 1:-1 2:50 1:67 1:68 5:66 6:145 7:72 2:147 1:134 2:141 5:142 4:-1 1:159 7:-1
-8:-1 4:192 3:188 5:187 5:-1 1:197 2:180 1:-1 1:201 17:-1 2:6 3:5 1:14 1:-1 2:13 1:-1 1:25 3:27 1:28 2:26 7:-1 2:71 4:-1 1:50 3:68 5:66 6:145 4:72 4:147 2:134 4:141 2:142 5:-1 2:159 5:-1
-8:-1 3:191 5:188 3:187 1:181 3:-1 1:196 1:-1 2:180 15:-1 4:9 2:6 2:10 4:-1 2:13 2:-1 2:27 2:28 2:26 7:-1 3:71 3:-1 4:68 3:66 1:-1 7:145 2:72 5:147 3:134 5:141 1:-1 1:62 3:-1 2:159 6:-1
-8:-1 4:191 5:188 1:187 4:181 1:182 1:-1 1:196 2:178 15:-1 1:12 5:9 2:10 5:-1 2:13 2:-1 1:27 3:28 1:26 8:-1 3:71 2:-1 1:69 5:68 1:66 1:-1 6:145 3:144 5:147 3:134 5:141 1:154 4:-1 2:159 6:-1
-8:-1 3:191 7:188 4:181 1:182 3:178 16:-1 1:12 4:9 2:10 3:-1 1:14 2:-1 3:15 1:-1 4:28 1:-1 2:73 4:74 4:71 2:70 1:-1 1:69 4:68 2:-1 6:145 4:144 5:147 3:134 3:141 2:154 5:-1 1:158 7:-1
-9:-1 3:191 7:188 4:181 2:179 1:178 16:-1 1:12 1:11 4:9 9:-1 1:15 1:-1 4:29 2:-1 1:73 5:74 3:71 1:78 2:-1 3:69 1:68 4:-1 5:145 6:144 3:147 4:134 2:141 1:153 1:154 4:-1 3:158 6:-1
-8:-1 4:191 6:188 3:181 4:179 16:-1 2:12 2:11 2:9 9:-1 1:15 3:-1 2:29 1:-1 2:75 1:73 5:74 4:78 2:-1 3:69 4:-1 1:88 4:145 7:144 2:147 5:134 2:-1 1:153 1:151 3:-1 3:158 7:-1
-9:-1 3:191 7:188 2:181 4:179 17:-1 1:12 4:11 8:-1 2:15 3:-1 2:29 2:-1 2:75 5:74 4:78 1:-1 4:69 1:-1 2:88 1:-1 3:88 1:145 8:144 2:140 4:134 3:-1 2:151 3:-1 2:155 2:158 6:-1
-9:-1 1:191 3:189 4:188 2:186 3:183 3:179 23:-1 3:94 3:93 10:-1 1:75 4:74 2:81 3:78 3:76 1:69 2:-1 7:88 8:144 3:140 4:134 3:-1 2:151 2:-1 1:156 3:155 7:-1
-10:-1 1:190 4:189 5:186 4:183 1:179 22:-1 5:94 2:93 15:-1 3:81 2:79 4:76 1:69 1:-1 7:88 2:146 6:144 5:140 2:134 4:-1 2:152 1:-1 2:156 2:155 7:-1
-10:-1 1:190 4:189 4:186 5:183 19:-1 3:96 5:94 2:93 1:92 14:-1 3:81 4:79 3:76 1:69 7:88 4:146 4:144 5:140 2:137 1:135 6:-1 3:156 2:155 7:-1
-10:-1 1:190 4:189 5:186 4:183 19:-1 4:96 5:94 4:92 13:-1 3:81 3:79 5:77 4:88 2:130 1:121 4:146 5:138 2:140 3:137 2:135 4:-1 1:157 1:-1 2:156 9:-1
-10:-1 1:190 3:189 6:186 3:183 19:-1 5:96 4:94 5:92 12:-1 1:82 2:81 4:79 4:77 3:88 3:130 1:121 1:133 4:146 5:138 1:140 4:137 2:135 4:-1 1:157 12:-1
-11:-1 4:189 5:185 4:183 18:-1 5:96 4:94 7:92 3:-1 5:90 1:-1 3:82 2:81 2:79 3:80 3:77 1:88 4:130 1:121 2:133 3:146 6:138 4:137 3:135 16:-1
-11:-1 3:189 6:185 2:183 1:184 18:-1 6:96 5:95 7:92 8:89 3:82 1:81 2:79 4:80 2:77 2:129 2:130 3:121 2:133 3:146 3:138 3:139 4:137 2:135 17:-1
-1:194 11:-1 2:189 3:207 2:185 4:-1 1:184 17:-1 6:96 6:95 7:92 8:89 1:-1 2:82 1:81 2:83 1:80 1:-1 2:80 1:77 3:129 4:121 2:133 4:128 1:143 1:138 3:139 1:136 3:137 2:135 17:-1
-12:-1 2:206 3:207 6:-1 1:184 16:-1 6:96 8:95 5:92 7:89 2:91 1:-1 2:84 4:83 4:-1 3:129 4:121 1:133 4:128 3:143 2:139 2:136 3:148 19:-1
-13:-1 3:206 2:207 22:-1 3:97 4:99 9:95 4:92 5:89 4:91 1:-1 2:84 4:83 2:85 1:87 2:-1 2:129 3:121 2:123 1:131 1:128 1:-1 1:161 4:143 1:164 2:136 2:148 2:-1 1:149 16:-1
-2:-1 1:193 10:-1 3:206 1:205 5:-1 1:211 17:-1 2:97 5:99 10:95 3:104 4:89 5:91 1:-1 2:84 4:83 2:85 4:-1 2:122 2:127 3:123 1:-1 2:161 2:143 2:164 3:136 3:-1 1:150 17:-1
-15:-1 1:206 2:205 2:-1 1:208 2:-1 2:211 15:-1 3:97 5:99 8:95 5:104 3:89 6:91 1:-1 2:84 3:83 3:85 4:-1 1:122 3:127 3:-1 2:161 1:-1 1:143 3:164 23:-1
-16:-1 2:205 1:-1 2:208 4:-1 2:212 12:-1 3:97 1:98 5:99 6:95 1:103 6:104 7:105 2:91 1:-1 2:84 2:86 1:83 2:85 4:-1 2:122 1:126 1:127 4:-1 1:160 3:163 2:164 24:-1
-18:-1 1:205 2:209 19:-1 2:97 2:98 5:99 4:95 2:103 7:104 9:105 2:-1 4:86 6:-1 1:122 2:126 4:-1 2:160 1:163 1:162 3:164 5:-1 3:175 15:-1
-19:-1 2:209 18:-1 3:97 2:98 4:99 2:95 5:103 6:104 9:105 2:-1 4:86 7:-1 1:125 1:124 6:-1 3:162 2:165 6:-1 3:175 15:-1
-40:-1 2:97 4:98 3:99 1:101 5:103 7:104 7:105 3:106 2:-1 1:86 8:-1 2:125 1:124 5:-1 3:162 1:166 1:165 6:-1 3:175 1:176 14:-1
-22:-1 1:210 3:-1 1:215 13:-1 1:97 5:98 1:99 2:101 1:102 5:103 7:104 6:105 5:106 2:-1 1:107 7:-1 1:125 8:-1 1:162 2:166 1:165 6:-1 1:175 2:176 15:-1
-23:-1 1:210 2:-1 1:214 3:215 10:-1 2:97 3:98 2:100 2:101 2:102 4:103 8:104 5:105 7:106 1:107 9:-1 1:132 6:-1 2:162 1:166 7:-1 4:176 14:-1
-23:-1 1:210 2:214 1:213 3:215 11:-1 2:98 3:100 2:101 3:102 4:103 7:104 5:105 6:106 2:107 9:-1 1:132 7:-1 1:167 9:-1 3:176 15:-1
-24:-1 2:214 2:213 4:215 10:-1 5:100 2:101 1:102 1:-1 1:102 3:103 7:104 6:109 5:106 2:107 18:-1 1:167 6:-1 1:168 2:-1 1:176 16:-1
-24:-1 5:213 1:215 2:234 21:-1 2:103 6:104 7:109 4:106 3:107 15:-1 1:172 1:-1 2:167 4:-1 3:168 19:-1
-24:-1 1:216 4:213 3:234 1:235 20:-1 1:103 7:110 7:109 3:108 4:107 16:-1 1:172 2:-1 1:169 2:-1 2:173 2:168 19:-1
-23:-1 2:216 3:213 4:234 1:235 20:-1 8:110 7:109 3:108 2:107 18:-1 2:172 3:-1 4:173 1:-1 3:174 16:-1
-23:-1 1:217 2:216 2:213 4:234 2:235 20:-1 8:110 1:111 5:109 4:108 1:113 19:-1 2:172 3:-1 4:173 1:-1 3:174 3:-1 4:177 8:-1
-23:-1 1:217 2:216 1:213 5:234 3:235 19:-1 7:110 3:111 3:109 3:108 2:113 21:-1 1:172 7:-1 2:174 5:-1 6:177 6:-1
-24:-1 1:217 1:216 1:218 2:219 3:234 3:235 2:233 18:-1 1:112 5:110 5:111 1:109 3:108 2:113 23:-1 2:170 2:171 11:-1 6:177 4:-1
-24:-1 2:218 3:219 2:234 3:231 1:232 2:233 18:-1 2:112 3:110 7:111 2:108 2:113 42:-1 3:177 4:-1
-25:-1 1:218 5:219 4:231 2:232 19:-1 2:112 2:110 8:111 1:108 2:113 49:-1
-24:-1 2:218 4:219 4:231 2:232 19:-1 3:112 1:110 1:116 6:111 2:115 2:113 3:-1 1:120 33:-1 7:242 6:-1
-26:-1 2:219 3:220 4:231 1:232 19:-1 3:112 2:116 6:114 3:115 5:-1 2:120 30:-1 7:242 2:239 5:-1
-26:-1 5:220 3:231 1:229 1:230 19:-1 5:116 5:114 3:115 5:-1 2:120 28:-1 7:242 3:243 2:239 5:-1
-27:-1 4:220 1:228 3:229 1:230 20:-1 5:116 4:114 4:115 5:-1 2:120 25:-1 3:241 4:242 5:243 3:239 4:-1
-27:-1 1:222 1:220 3:228 2:229 1:230 21:-1 5:116 3:117 4:115 6:-1 1:120 23:-1 6:241 2:242 7:243 3:239 4:-1
-27:-1 3:222 3:228 1:229 23:-1 4:116 5:117 1:119 32:-1 5:241 9:243 4:239 3:-1
-27:-1 2:222 4:228 23:-1 4:116 5:117 2:119 32:-1 5:241 8:243 1:238 3:239 4:-1
-27:-1 1:221 2:225 2:228 1:236 24:-1 4:118 5:117 33:-1 6:241 6:243 2:240 1:238 3:239 3:-1
-26:-1 2:221 2:225 2:227 1:236 24:-1 4:118 4:117 34:-1 6:241 4:243 4:240 1:238 2:237 4:-1
-27:-1 2:221 1:225 1:224 1:227 26:-1 4:118 2:117 36:-1 4:241 6:-1 3:240 2:238 2:237 3:-1
-26:-1 3:221 2:224 80:-1 2:240 2:238 1:237 4:-1
-26:-1 2:226 1:221 2:224 88:-1 1:245
-26:-1 3:226 86:-1 1:244 2:-1 1:246 1:-1
-26:-1 3:226 89:-1 1:246 1:-1
-25:-1 3:223 92:-1
-26:-1 2:223 92:-1
-26:-1 1:223 93:-1
+31:-1 8:208 50:-1 9:65 22:-1
+23:-1 2:206 6:-1 7:208 20:-1 1:45 6:38 14:-1 19:65 15:63 2:64 5:-1
+2:-1 6:199 1:207 13:-1 6:206 4:-1 6:208 19:-1 3:45 1:35 4:38 2:-1 1:57 10:-1 2:58 19:65 14:63 5:64 2:-1
+1:-1 7:199 11:207 9:206 4:-1 5:208 18:-1 4:45 3:35 1:38 2:42 5:57 3:-1 6:58 1:56 18:65 14:63 7:64 1:-1
+2:-1 6:199 11:207 10:206 4:-1 4:208 2:-1 1:44 15:-1 1:37 1:34 1:45 3:35 1:-1 4:42 4:57 9:58 3:56 16:65 15:63 7:64
+1:-1 7:199 11:207 2:206 2:-1 6:206 4:-1 3:208 3:-1 1:44 14:-1 1:37 4:34 1:35 2:-1 4:42 3:57 9:58 5:56 14:65 15:63 7:64 1:-1
+2:-1 6:199 12:207 4:-1 5:206 3:-1 4:208 3:-1 1:44 13:-1 3:37 3:34 2:-1 5:42 3:51 8:58 7:56 9:65 4:61 1:62 15:63 7:64
+1:-1 7:199 11:207 5:-1 5:206 4:-1 2:208 16:-1 3:37 1:36 3:34 2:-1 4:41 5:51 7:58 8:56 7:65 5:61 2:62 14:63 7:64 1:-1
+2:-1 7:199 10:207 5:-1 5:206 5:-1 1:208 16:-1 5:36 2:34 3:-1 4:41 5:51 5:58 2:52 7:56 3:59 9:61 3:62 13:63 7:64 1:-1
+1:-1 7:199 10:207 6:-1 5:206 21:-1 5:36 1:33 3:32 3:-1 1:41 2:-1 4:51 3:50 4:52 1:53 6:56 3:59 1:60 8:61 4:62 12:63 7:64 2:-1
+2:-1 2:199 2:-1 3:199 10:207 5:-1 6:206 21:-1 3:36 2:33 3:32 6:-1 3:51 4:50 4:52 2:53 5:56 3:59 2:60 7:61 5:62 11:63 7:64 2:-1
+1:-1 2:199 3:-1 2:199 9:207 1:204 5:-1 6:206 15:-1 2:2 8:-1 2:33 2:32 3:-1 3:43 3:51 5:50 3:52 2:53 5:56 3:59 3:60 6:61 6:62 11:63 4:64 1:-1 1:64 3:-1
+2:-1 2:199 3:-1 2:199 8:203 6:204 7:206 15:-1 2:2 9:-1 1:33 1:32 3:-1 5:43 1:51 5:50 3:52 3:53 4:56 3:59 3:60 6:61 7:62 10:63 4:64 5:-1
+1:-1 2:199 3:-1 2:199 8:203 7:204 7:206 15:-1 1:2 6:-1 2:40 1:39 5:-1 4:43 2:49 6:50 3:52 3:53 1:56 1:-1 1:56 4:59 3:60 5:61 8:62 10:63 2:64 3:-1 1:64 3:-1
+7:-1 2:202 7:203 8:204 7:206 12:-1 1:3 1:4 1:-1 1:1 6:-1 1:20 5:-1 3:25 1:43 4:49 5:50 3:52 3:53 1:56 2:-1 4:59 4:60 4:61 9:62 5:63 5:67 1:64 7:-1
+7:-1 2:202 6:203 8:204 8:201 10:-1 3:3 1:-1 1:1 7:-1 1:20 4:19 4:25 4:49 1:46 5:50 3:52 3:53 1:56 1:71 5:59 3:60 4:61 9:62 4:146 7:67 4:-1 1:68 3:-1
+8:-1 2:202 6:203 7:204 8:201 11:-1 2:3 1:-1 2:1 3:-1 3:9 1:20 4:19 5:25 2:49 3:46 3:48 1:50 4:52 1:53 3:71 2:69 1:59 1:-1 1:59 4:60 3:61 10:62 4:146 7:67 4:-1 1:68 2:-1
+7:-1 3:202 5:203 7:204 8:201 11:-1 1:3 3:-1 3:0 1:-1 2:8 1:22 1:20 3:19 2:24 1:26 3:25 1:49 4:46 5:48 4:54 4:71 4:69 1:59 4:60 2:61 10:62 5:146 7:67 7:-1
+8:-1 3:202 4:203 8:204 7:201 1:-1 1:205 18:-1 1:8 2:22 1:21 1:19 3:24 3:26 2:25 5:46 4:48 4:54 4:71 6:69 4:60 3:-1 3:62 5:76 6:146 6:67 7:-1
+7:-1 4:202 3:203 8:204 7:201 1:-1 2:205 15:-1 3:5 1:8 1:22 1:18 2:21 1:24 2:23 3:26 1:25 5:46 4:48 1:55 4:54 4:71 6:69 2:60 2:-1 3:62 8:76 6:146 6:67 7:-1
+8:-1 4:196 3:203 5:204 3:191 6:201 1:205 1:-1 1:205 13:-1 7:5 2:18 2:21 3:23 1:27 2:26 1:25 4:46 3:48 2:55 5:54 3:71 6:69 2:149 1:-1 1:149 11:76 6:146 6:67 7:-1
+8:-1 5:196 1:203 3:204 5:191 6:201 2:205 15:-1 2:7 3:5 1:6 3:18 2:21 2:23 4:27 1:28 4:47 2:48 3:55 5:54 3:71 5:69 5:149 10:76 7:146 5:67 8:-1
+8:-1 6:196 9:191 5:201 2:205 17:-1 1:7 1:5 3:6 3:16 1:21 2:23 2:27 2:29 2:28 2:47 1:-1 1:47 1:48 4:55 2:54 1:-1 2:54 2:71 2:69 4:70 5:149 9:76 8:146 1:66 3:67 8:-1
+8:-1 4:196 1:192 6:191 2:-1 1:191 5:201 1:184 1:205 17:-1 2:7 3:6 4:16 1:15 1:23 1:27 3:29 3:28 8:-1 3:54 1:-1 2:54 1:71 1:72 5:70 6:149 7:76 2:151 1:138 2:145 4:146 4:66 1:-1 1:163 7:-1
+8:-1 4:196 3:192 5:191 5:-1 1:201 2:184 1:-1 1:205 17:-1 2:7 3:6 1:16 1:-1 2:15 1:-1 1:27 3:29 1:30 2:28 7:-1 2:75 4:-1 1:54 3:72 5:70 6:149 4:76 4:151 2:138 4:145 1:146 4:66 2:-1 2:163 5:-1
+8:-1 3:195 5:192 3:191 1:185 3:-1 1:200 1:-1 2:184 15:-1 4:10 2:7 2:11 4:-1 2:15 2:-1 2:29 2:30 2:28 7:-1 3:75 3:-1 4:72 3:70 1:-1 7:149 2:76 5:151 3:138 4:145 3:66 3:-1 2:163 6:-1
+8:-1 4:195 5:192 1:191 4:185 1:186 1:-1 1:200 2:182 15:-1 1:14 5:10 2:11 5:-1 2:15 2:-1 1:29 3:30 1:28 8:-1 3:75 2:-1 1:73 5:72 1:70 1:-1 6:149 3:148 5:151 3:138 5:145 1:66 4:-1 2:163 6:-1
+8:-1 3:195 7:192 4:185 1:186 3:182 16:-1 1:14 4:10 2:11 3:-1 1:16 2:-1 3:17 1:-1 4:30 1:-1 2:77 4:78 4:75 2:74 1:-1 1:73 4:72 2:-1 6:149 4:148 5:151 3:138 3:145 2:158 5:-1 1:162 7:-1
+9:-1 3:195 7:192 4:185 2:183 1:182 16:-1 1:14 1:12 4:10 9:-1 1:17 1:-1 4:31 2:-1 1:77 5:78 3:75 1:82 2:-1 3:73 1:72 4:-1 5:149 6:148 3:151 4:138 2:145 1:157 1:158 4:-1 3:162 6:-1
+8:-1 4:195 6:192 3:185 4:183 16:-1 2:14 2:12 2:10 9:-1 1:17 3:-1 2:31 1:-1 2:79 1:77 5:78 4:82 2:-1 3:73 4:-1 1:92 4:149 7:148 2:151 5:138 2:-1 1:157 1:155 3:-1 3:162 7:-1
+9:-1 3:195 7:192 2:185 4:183 17:-1 1:14 4:12 8:-1 2:17 3:-1 2:31 2:-1 2:79 5:78 4:82 1:-1 4:73 1:-1 2:92 1:-1 3:92 1:149 8:148 2:144 4:138 3:-1 2:155 3:-1 2:159 2:162 6:-1
+9:-1 1:195 3:193 4:192 2:190 3:187 3:183 18:-1 1:12 1:13 3:-1 3:98 3:97 10:-1 1:79 4:78 2:85 3:82 3:80 1:73 2:-1 7:92 8:148 3:144 4:138 3:-1 2:155 2:-1 1:160 3:159 7:-1
+10:-1 1:194 4:193 5:190 4:187 1:183 19:-1 1:12 2:-1 5:98 2:97 15:-1 3:85 2:83 4:80 1:73 1:-1 7:92 2:150 6:148 5:144 2:138 4:-1 2:156 1:-1 2:160 2:159 7:-1
+10:-1 1:194 4:193 4:190 5:187 21:-1 1:100 5:98 2:97 1:96 14:-1 3:85 4:83 3:80 1:73 7:92 4:150 4:148 5:144 2:141 1:139 6:-1 3:160 2:159 7:-1
+10:-1 1:194 4:193 5:190 4:187 19:-1 4:100 5:98 4:96 13:-1 3:85 3:83 5:81 4:92 2:134 1:125 4:150 5:142 2:144 3:141 2:139 4:-1 1:161 1:-1 2:160 9:-1
+10:-1 1:194 3:193 6:190 3:187 19:-1 5:100 4:98 5:96 12:-1 1:86 2:85 4:83 4:81 3:92 3:134 1:125 1:137 4:150 5:142 1:144 4:141 2:139 4:-1 1:161 12:-1
+11:-1 4:193 5:189 4:187 18:-1 5:100 4:98 7:96 3:-1 5:94 1:-1 3:86 2:85 2:83 3:84 3:81 1:92 4:134 1:125 2:137 3:150 6:142 4:141 3:139 16:-1
+11:-1 3:193 6:189 2:187 1:188 18:-1 6:100 5:99 7:96 8:93 3:86 1:85 2:83 4:84 2:81 2:133 2:134 3:125 2:137 3:150 3:142 3:143 4:141 2:139 17:-1
+1:198 11:-1 2:193 3:211 2:189 4:-1 1:188 17:-1 6:100 6:99 7:96 8:93 1:-1 2:86 1:85 2:87 1:84 1:-1 2:84 1:81 3:133 4:125 2:137 4:132 1:147 1:142 3:143 1:140 3:141 2:139 17:-1
+12:-1 2:210 3:211 6:-1 1:188 16:-1 6:100 8:99 5:96 7:93 2:95 1:-1 2:88 4:87 4:-1 3:133 4:125 1:137 4:132 3:147 2:143 4:140 1:141 19:-1
+13:-1 3:210 2:211 22:-1 3:101 4:103 9:99 4:96 5:93 4:95 1:-1 2:88 4:87 2:89 1:91 2:-1 2:133 3:125 2:127 1:135 1:132 1:-1 1:165 4:147 1:168 2:140 1:152 1:140 2:-1 1:153 16:-1
+2:-1 1:197 10:-1 3:210 1:209 5:-1 1:215 17:-1 2:101 5:103 10:99 3:108 4:93 5:95 1:-1 2:88 4:87 2:89 4:-1 2:126 2:131 3:127 1:-1 2:165 2:147 2:168 3:140 3:-1 1:154 17:-1
+15:-1 1:210 2:209 2:-1 1:212 2:-1 2:215 15:-1 3:101 5:103 8:99 5:108 3:93 6:95 1:-1 2:88 3:87 3:89 4:-1 1:126 3:131 3:-1 2:165 1:-1 1:147 3:168 23:-1
+16:-1 2:209 1:-1 2:212 4:-1 2:216 12:-1 3:101 1:102 5:103 6:99 1:107 6:108 7:109 2:95 1:-1 2:88 2:90 1:87 2:89 4:-1 2:126 1:130 1:131 4:-1 1:164 3:167 2:168 24:-1
+18:-1 1:209 2:213 19:-1 2:101 2:102 5:103 4:99 2:107 7:108 9:109 2:-1 4:90 6:-1 1:126 2:130 4:-1 2:164 1:167 1:166 3:168 5:-1 2:179 16:-1
+19:-1 2:213 18:-1 3:101 2:102 4:103 2:99 5:107 6:108 9:109 2:-1 4:90 7:-1 1:129 1:128 6:-1 3:166 2:169 6:-1 1:179 17:-1
+40:-1 2:101 4:102 3:103 1:105 5:107 7:108 7:109 3:110 2:-1 1:90 8:-1 2:129 1:128 5:-1 3:166 1:170 1:169 24:-1
+22:-1 1:214 3:-1 1:219 13:-1 1:101 5:102 1:103 2:105 1:106 5:107 7:108 6:109 5:110 2:-1 1:111 7:-1 1:129 8:-1 1:166 2:170 1:169 7:-1 2:180 15:-1
+23:-1 1:214 2:-1 1:218 3:219 10:-1 2:101 3:102 2:104 2:105 2:106 4:107 8:108 5:109 7:110 1:111 9:-1 1:136 6:-1 2:166 1:170 9:-1 1:180 15:-1
+23:-1 1:214 2:218 1:217 3:219 11:-1 2:102 3:104 2:105 3:106 4:107 7:108 5:109 6:110 2:111 9:-1 1:136 7:-1 1:171 10:-1 2:180 15:-1
+24:-1 2:218 2:217 4:219 10:-1 5:104 2:105 1:106 1:-1 1:106 3:107 7:108 6:113 5:110 2:111 18:-1 1:171 6:-1 1:172 19:-1
+24:-1 5:217 1:219 2:241 21:-1 2:107 6:108 7:113 4:110 3:111 15:-1 1:176 1:-1 2:171 4:-1 3:172 19:-1
+24:-1 1:220 4:217 3:241 1:242 20:-1 1:107 7:114 7:113 3:112 4:111 16:-1 1:176 2:-1 1:173 2:-1 2:177 2:172 19:-1
+23:-1 2:220 3:217 4:241 1:242 20:-1 8:114 7:113 3:112 2:111 18:-1 2:176 3:-1 4:177 1:-1 3:178 16:-1
+23:-1 1:221 2:220 2:217 4:241 2:242 20:-1 8:114 1:115 5:113 4:112 1:117 19:-1 2:176 3:-1 4:177 1:-1 3:178 3:-1 4:181 8:-1
+23:-1 1:221 2:220 1:217 5:241 3:242 19:-1 7:114 3:115 3:113 3:112 2:117 21:-1 1:176 7:-1 2:178 5:-1 6:181 6:-1
+24:-1 1:221 1:220 1:222 2:223 3:241 3:242 2:240 18:-1 1:116 5:114 5:115 1:113 3:112 2:117 23:-1 2:174 2:175 11:-1 6:181 4:-1
+24:-1 2:222 3:223 2:241 3:238 1:239 2:240 18:-1 2:116 3:114 7:115 2:112 2:117 42:-1 3:181 4:-1
+25:-1 1:222 5:223 4:238 2:239 19:-1 2:116 2:114 8:115 1:112 2:117 49:-1
+24:-1 2:222 4:223 4:238 2:239 19:-1 3:116 1:114 1:120 6:115 2:119 2:117 3:-1 1:124 33:-1 7:249 6:-1
+26:-1 2:223 3:224 4:238 1:239 19:-1 3:116 2:120 6:118 3:119 5:-1 2:124 30:-1 7:249 2:246 5:-1
+26:-1 5:224 3:238 1:236 1:237 19:-1 5:120 5:118 3:119 5:-1 2:124 28:-1 7:249 3:250 2:246 5:-1
+27:-1 4:224 1:235 3:236 1:237 20:-1 5:120 4:118 4:119 5:-1 2:124 25:-1 3:248 4:249 5:250 3:246 4:-1
+27:-1 1:226 1:224 3:235 2:236 1:237 21:-1 5:120 3:121 4:119 6:-1 1:124 23:-1 6:248 2:249 7:250 3:246 4:-1
+27:-1 3:226 3:235 1:236 23:-1 4:120 5:121 1:123 32:-1 5:248 9:250 4:246 3:-1
+27:-1 2:226 4:235 23:-1 4:120 5:121 2:123 32:-1 5:248 8:250 1:245 3:246 4:-1
+27:-1 1:225 2:231 2:235 1:243 24:-1 4:122 5:121 33:-1 6:248 6:250 2:247 1:245 3:246 3:-1
+26:-1 2:225 2:231 2:234 1:243 24:-1 4:122 4:121 34:-1 6:248 4:250 4:247 1:245 2:244 4:-1
+27:-1 2:225 1:231 1:230 1:234 26:-1 4:122 2:121 36:-1 4:248 6:-1 3:247 2:245 2:244 3:-1
+26:-1 3:225 2:230 80:-1 2:247 2:245 1:244 4:-1
+26:-1 1:227 2:232 2:230 88:-1 1:252
+26:-1 1:227 1:232 1:233 86:-1 1:251 2:-1 1:253 1:-1
+26:-1 2:228 1:233 89:-1 1:253 1:-1
+25:-1 2:228 1:233 92:-1
+26:-1 2:229 92:-1
+26:-1 1:229 93:-1
[meta]
0|prov_london|4|47,17
1|prov_manchester|2|45,15
2|prov_edinburgh|2|45,13
3|prov_dublin|2|43,15
-4|prov_paris|4|49,20
-5|prov_lyon|2|50,22
-6|prov_bordeaux|2|46,23
-7|prov_brussels|2|50,18
-8|prov_amsterdam|2|50,16
-9|prov_madrid|3|45,27
-10|prov_barcelona|2|48,27
-11|prov_seville|2|44,30
-12|prov_lisbon|2|41,29
-13|prov_rome|3|55,26
-14|prov_milan|3|52,23
-15|prov_naples|2|55,27
-16|prov_zurich|2|52,21
-17|prov_berlin|4|55,16
-18|prov_hamburg|2|53,15
-19|prov_munich|3|54,20
-20|prov_cologne|2|51,18
-21|prov_vienna|3|57,20
-22|prov_prague|2|56,18
-23|prov_warsaw|3|60,16
-24|prov_krakow|2|59,18
-25|prov_budapest|2|58,21
-26|prov_bucharest|2|63,24
-27|prov_belgrade|2|59,23
-28|prov_sofia|1|61,25
-29|prov_athens|2|61,30
-30|prov_stockholm|2|58,10
-31|prov_gothenburg|1|54,11
-32|prov_sundsvall|1|57,7
-33|prov_kiruna|1|59,3
-34|prov_oslo|2|53,9
-35|prov_copenhagen|2|54,13
-36|prov_aarhus|1|53,13
-37|prov_helsinki|2|62,9
-38|prov_oulu|1|62,5
-39|prov_riga|1|62,12
-40|prov_reykjavik|1|39,6
-41|prov_narvik|1|58,2
-42|prov_kyiv|3|65,18
-43|prov_odesa|2|65,22
-44|prov_kharkiv|2|68,19
-45|prov_minsk|2|63,15
-46|prov_moscow|4|69,13
-47|prov_petersburg|3|65,9
-48|prov_nizhny|2|73,13
-49|prov_kazan|2|75,13
-50|prov_volgograd|2|74,20
-51|prov_rostov|2|70,21
-52|prov_yekaterinburg|2|79,12
-53|prov_murmansk|1|67,2
-54|prov_arkhangelsk|1|71,5
-55|prov_omsk|2|83,14
-56|prov_novosibirsk|2|86,14
-57|prov_krasnoyarsk|2|89,13
-58|prov_irkutsk|1|94,16
-59|prov_yakutsk|1|106,7
-60|prov_magadan|1|116,10
-61|prov_norilsk|1|88,2
-62|prov_vladivostok|2|108,25
-63|prov_khabarovsk|1|110,20
-64|prov_petropavlovsk|1|117,16
-65|prov_astana|2|82,18
-66|prov_almaty|2|83,25
-67|prov_aktobe|1|78,18
-68|prov_tashkent|2|81,27
-69|prov_ashgabat|1|78,30
-70|prov_baku|2|75,27
-71|prov_tbilisi|1|74,26
-72|prov_ulaanbaatar|1|95,20
-73|prov_istanbul|3|64,27
-74|prov_ankara|2|67,28
-75|prov_izmir|2|63,29
-76|prov_tehran|3|76,32
-77|prov_isfahan|2|76,34
-78|prov_tabriz|1|74,29
-79|prov_baghdad|3|74,34
-80|prov_basra|2|75,36
-81|prov_damascus|2|69,34
-82|prov_jerusalem|2|68,35
-83|prov_riyadh|3|74,40
-84|prov_jeddah|2|71,42
-85|prov_dubai|2|77,40
-86|prov_sanaa|1|73,45
-87|prov_muscat|1|78,40
-88|prov_kabul|2|81,33
-89|prov_cairo|4|65,37
-90|prov_alexandria|2|65,36
-91|prov_aswan|1|67,40
-92|prov_tripoli|2|55,34
-93|prov_tunis|2|53,31
-94|prov_algiers|2|49,31
-95|prov_tamanrasset|1|50,41
-96|prov_casablanca|2|43,34
-97|prov_dakar|2|39,45
-98|prov_bamako|1|43,46
-99|prov_timbuktu|1|45,44
-100|prov_abidjan|2|45,50
-101|prov_accra|2|47,50
-102|prov_lagos|3|49,50
-103|prov_kano|2|52,47
-104|prov_ndjamena|1|56,47
-105|prov_khartoum|2|66,45
-106|prov_addis|2|70,48
-107|prov_mogadishu|1|74,52
-108|prov_nairobi|2|69,54
-109|prov_kampala|1|66,53
-110|prov_kinshasa|3|56,55
-111|prov_lubumbashi|1|64,58
-112|prov_luanda|2|55,57
-113|prov_dar_es_salaam|2|71,56
-114|prov_lusaka|1|64,60
-115|prov_harare|1|65,61
-116|prov_windhoek|1|57,63
-117|prov_johannesburg|3|63,65
-118|prov_cape_town|2|58,68
-119|prov_maputo|1|66,65
-120|prov_antananarivo|1|75,62
-121|prov_delhi|4|84,38
-122|prov_mumbai|3|82,43
-123|prov_kolkata|3|87,41
-124|prov_chennai|2|85,46
-125|prov_bangalore|2|84,46
-126|prov_hyderabad|2|84,44
-127|prov_nagpur|1|85,42
-128|prov_guwahati|1|88,39
-129|prov_karachi|3|81,40
-130|prov_lahore|2|83,36
-131|prov_dhaka|2|88,40
-132|prov_colombo|1|84,49
-133|prov_kathmandu|1|87,38
-134|prov_beijing|4|100,28
-135|prov_shanghai|4|103,36
-136|prov_guangzhou|3|98,41
-137|prov_wuhan|3|99,36
-138|prov_chengdu|3|94,36
-139|prov_chongqing|2|94,37
-140|prov_xian|2|96,33
-141|prov_shenyang|2|104,26
-142|prov_harbin|2|105,22
-143|prov_kunming|2|93,40
-144|prov_lanzhou|1|93,31
-145|prov_urumqi|1|87,24
-146|prov_lhasa|1|88,37
-147|prov_hohhot|1|97,27
-148|prov_hong_kong|3|99,40
-149|prov_taipei|3|103,40
-150|prov_kaohsiung|2|102,41
-151|prov_seoul|3|106,30
-152|prov_busan|2|107,32
-153|prov_pyongyang|2|105,29
-154|prov_hamhung|1|106,28
-155|prov_tokyo|4|112,32
-156|prov_osaka|3|109,33
-157|prov_fukuoka|2|107,34
-158|prov_sendai|2|112,29
-159|prov_sapporo|2|112,25
-160|prov_yangon|2|90,44
-161|prov_mandalay|1|90,41
-162|prov_bangkok|3|92,46
-163|prov_chiang_mai|1|91,43
-164|prov_hanoi|2|95,42
-165|prov_ho_chi_minh|3|95,47
-166|prov_phnom_penh|1|94,47
-167|prov_kuala_lumpur|2|92,51
-168|prov_kota_kinabalu|1|100,50
-169|prov_singapore|3|94,52
-170|prov_jakarta|3|95,56
-171|prov_surabaya|2|98,56
-172|prov_medan|2|91,52
-173|prov_banjarmasin|1|99,54
-174|prov_makassar|1|101,55
-175|prov_manila|3|102,45
-176|prov_cebu|1|104,48
-177|prov_port_moresby|1|115,57
-178|prov_new_york|4|25,27
-179|prov_washington|3|24,29
-180|prov_boston|2|26,25
-181|prov_chicago|3|21,26
-182|prov_detroit|2|22,26
-183|prov_atlanta|2|22,34
-184|prov_miami|2|23,39
-185|prov_houston|3|17,37
-186|prov_dallas|2|17,35
-187|prov_minneapolis|2|18,23
-188|prov_denver|2|15,28
-189|prov_phoenix|2|12,34
-190|prov_los_angeles|4|10,34
-191|prov_san_francisco|3|8,29
-192|prov_seattle|2|8,21
-193|prov_honolulu|2|2,41
-194|prov_midway|1|0,38
-195|prov_anchorage|1|4,8
-196|prov_toronto|3|23,25
-197|prov_montreal|2|25,23
-198|prov_vancouver|2|8,19
-199|prov_calgary|2|11,17
-200|prov_winnipeg|1|17,19
-201|prov_halifax|1|29,24
-202|prov_iqaluit|1|27,6
-203|prov_yellowknife|1|11,7
-204|prov_nuuk|1|32,6
-205|prov_mexico_city|4|16,43
-206|prov_guadalajara|2|15,42
-207|prov_monterrey|2|16,39
-208|prov_merida|1|20,42
-209|prov_guatemala|1|19,45
-210|prov_panama|2|23,48
-211|prov_havana|2|22,41
-212|prov_santo_domingo|1|26,43
-213|prov_bogota|3|25,51
-214|prov_medellin|2|25,50
-215|prov_caracas|2|28,48
-216|prov_quito|1|23,53
-217|prov_guayaquil|1|23,54
-218|prov_lima|3|24,59
-219|prov_cusco|1|26,59
-220|prov_la_paz|1|27,61
-221|prov_santiago|3|27,68
-222|prov_antofagasta|1|27,64
-223|prov_punta_arenas|1|26,75
-224|prov_buenos_aires|4|30,69
-225|prov_cordoba_ar|2|28,67
-226|prov_bariloche|1|26,71
-227|prov_montevideo|1|31,68
-228|prov_asuncion|1|30,65
-229|prov_sao_paulo|4|33,63
-230|prov_rio|3|34,63
-231|prov_brasilia|2|33,60
-232|prov_salvador|2|35,59
-233|prov_recife|2|36,57
-234|prov_manaus|2|30,54
-235|prov_belem|1|33,54
-236|prov_porto_alegre|2|32,67
-237|prov_sydney|3|116,68
-238|prov_melbourne|3|114,69
-239|prov_brisbane|2|116,66
-240|prov_adelaide|2|111,69
-241|prov_perth|2|99,67
-242|prov_darwin|1|107,59
-243|prov_alice_springs|1|109,64
-244|prov_hobart|1|115,71
-245|prov_auckland|2|119,70
-246|prov_christchurch|1|118,71
+4|prov_belfast|1|44,14
+5|prov_paris|4|49,20
+6|prov_lyon|2|50,22
+7|prov_bordeaux|2|46,23
+8|prov_brussels|2|50,18
+9|prov_amsterdam|2|50,16
+10|prov_madrid|3|45,27
+11|prov_barcelona|2|48,27
+12|prov_seville|2|44,30
+13|prov_gibraltar|1|44,31
+14|prov_lisbon|2|41,29
+15|prov_rome|3|55,26
+16|prov_milan|3|52,23
+17|prov_naples|2|55,27
+18|prov_zurich|2|52,21
+19|prov_berlin|4|55,16
+20|prov_hamburg|2|53,15
+21|prov_munich|3|54,20
+22|prov_cologne|2|51,18
+23|prov_vienna|3|57,20
+24|prov_prague|2|56,18
+25|prov_warsaw|3|60,16
+26|prov_krakow|2|59,18
+27|prov_budapest|2|58,21
+28|prov_bucharest|2|63,24
+29|prov_belgrade|2|59,23
+30|prov_sofia|1|61,25
+31|prov_athens|2|61,30
+32|prov_stockholm|2|58,10
+33|prov_gothenburg|1|54,11
+34|prov_sundsvall|1|57,7
+35|prov_lulea|1|60,4
+36|prov_oslo|2|53,9
+37|prov_trondheim|1|53,6
+38|prov_hammerfest|1|61,1
+39|prov_copenhagen|2|54,13
+40|prov_aarhus|1|53,13
+41|prov_helsinki|2|62,9
+42|prov_oulu|1|62,5
+43|prov_riga|1|62,12
+44|prov_reykjavik|1|39,6
+45|prov_narvik|1|58,2
+46|prov_kyiv|3|65,18
+47|prov_odesa|2|65,22
+48|prov_kharkiv|2|68,19
+49|prov_minsk|2|63,15
+50|prov_moscow|4|69,13
+51|prov_petersburg|3|65,9
+52|prov_nizhny|2|73,13
+53|prov_kazan|2|75,13
+54|prov_volgograd|2|74,20
+55|prov_rostov|2|70,21
+56|prov_yekaterinburg|2|79,12
+57|prov_murmansk|1|67,2
+58|prov_arkhangelsk|1|71,5
+59|prov_omsk|2|83,14
+60|prov_novosibirsk|2|86,14
+61|prov_krasnoyarsk|2|89,13
+62|prov_irkutsk|1|94,16
+63|prov_yakutsk|1|106,7
+64|prov_magadan|1|116,10
+65|prov_norilsk|1|88,2
+66|prov_vladivostok|2|108,25
+67|prov_khabarovsk|1|110,20
+68|prov_petropavlovsk|1|117,16
+69|prov_astana|2|82,18
+70|prov_almaty|2|83,25
+71|prov_aktobe|1|78,18
+72|prov_tashkent|2|81,27
+73|prov_ashgabat|1|78,30
+74|prov_baku|2|75,27
+75|prov_tbilisi|1|74,26
+76|prov_ulaanbaatar|1|95,20
+77|prov_istanbul|3|64,27
+78|prov_ankara|2|67,28
+79|prov_izmir|2|63,29
+80|prov_tehran|3|76,32
+81|prov_isfahan|2|76,34
+82|prov_tabriz|1|74,29
+83|prov_baghdad|3|74,34
+84|prov_basra|2|75,36
+85|prov_damascus|2|69,34
+86|prov_jerusalem|2|68,35
+87|prov_riyadh|3|74,40
+88|prov_jeddah|2|71,42
+89|prov_dubai|2|77,40
+90|prov_sanaa|1|73,45
+91|prov_muscat|1|78,40
+92|prov_kabul|2|81,33
+93|prov_cairo|4|65,37
+94|prov_alexandria|2|65,36
+95|prov_aswan|1|67,40
+96|prov_tripoli|2|55,34
+97|prov_tunis|2|53,31
+98|prov_algiers|2|49,31
+99|prov_tamanrasset|1|50,41
+100|prov_casablanca|2|43,34
+101|prov_dakar|2|39,45
+102|prov_bamako|1|43,46
+103|prov_timbuktu|1|45,44
+104|prov_abidjan|2|45,50
+105|prov_accra|2|47,50
+106|prov_lagos|3|49,50
+107|prov_kano|2|52,47
+108|prov_ndjamena|1|56,47
+109|prov_khartoum|2|66,45
+110|prov_addis|2|70,48
+111|prov_mogadishu|1|74,52
+112|prov_nairobi|2|69,54
+113|prov_kampala|1|66,53
+114|prov_kinshasa|3|56,55
+115|prov_lubumbashi|1|64,58
+116|prov_luanda|2|55,57
+117|prov_dar_es_salaam|2|71,56
+118|prov_lusaka|1|64,60
+119|prov_harare|1|65,61
+120|prov_windhoek|1|57,63
+121|prov_johannesburg|3|63,65
+122|prov_cape_town|2|58,68
+123|prov_maputo|1|66,65
+124|prov_antananarivo|1|75,62
+125|prov_delhi|4|84,38
+126|prov_mumbai|3|82,43
+127|prov_kolkata|3|87,41
+128|prov_chennai|2|85,46
+129|prov_bangalore|2|84,46
+130|prov_hyderabad|2|84,44
+131|prov_nagpur|1|85,42
+132|prov_guwahati|1|88,39
+133|prov_karachi|3|81,40
+134|prov_lahore|2|83,36
+135|prov_dhaka|2|88,40
+136|prov_colombo|1|84,49
+137|prov_kathmandu|1|87,38
+138|prov_beijing|4|100,28
+139|prov_shanghai|4|103,36
+140|prov_guangzhou|3|98,41
+141|prov_wuhan|3|99,36
+142|prov_chengdu|3|94,36
+143|prov_chongqing|2|94,37
+144|prov_xian|2|96,33
+145|prov_shenyang|2|104,26
+146|prov_harbin|2|105,22
+147|prov_kunming|2|93,40
+148|prov_lanzhou|1|93,31
+149|prov_urumqi|1|87,24
+150|prov_lhasa|1|88,37
+151|prov_hohhot|1|97,27
+152|prov_hong_kong|3|99,40
+153|prov_taipei|3|103,40
+154|prov_kaohsiung|2|102,41
+155|prov_seoul|3|106,30
+156|prov_busan|2|107,32
+157|prov_pyongyang|2|105,29
+158|prov_hamhung|1|106,28
+159|prov_tokyo|4|112,32
+160|prov_osaka|3|109,33
+161|prov_fukuoka|2|107,34
+162|prov_sendai|2|112,29
+163|prov_sapporo|2|112,25
+164|prov_yangon|2|90,44
+165|prov_mandalay|1|90,41
+166|prov_bangkok|3|92,46
+167|prov_chiang_mai|1|91,43
+168|prov_hanoi|2|95,42
+169|prov_ho_chi_minh|3|95,47
+170|prov_phnom_penh|1|94,47
+171|prov_kuala_lumpur|2|92,51
+172|prov_kota_kinabalu|1|100,50
+173|prov_singapore|3|94,52
+174|prov_jakarta|3|95,56
+175|prov_surabaya|2|98,56
+176|prov_medan|2|91,52
+177|prov_banjarmasin|1|99,54
+178|prov_makassar|1|101,55
+179|prov_manila|3|102,45
+180|prov_cebu|1|104,48
+181|prov_port_moresby|1|115,57
+182|prov_new_york|4|25,27
+183|prov_washington|3|24,29
+184|prov_boston|2|26,25
+185|prov_chicago|3|21,26
+186|prov_detroit|2|22,26
+187|prov_atlanta|2|22,34
+188|prov_miami|2|23,39
+189|prov_houston|3|17,37
+190|prov_dallas|2|17,35
+191|prov_minneapolis|2|18,23
+192|prov_denver|2|15,28
+193|prov_phoenix|2|12,34
+194|prov_los_angeles|4|10,34
+195|prov_san_francisco|3|8,29
+196|prov_seattle|2|8,21
+197|prov_honolulu|2|2,41
+198|prov_midway|1|0,38
+199|prov_anchorage|1|4,8
+200|prov_toronto|3|23,25
+201|prov_montreal|2|25,23
+202|prov_vancouver|2|8,19
+203|prov_calgary|2|11,17
+204|prov_winnipeg|1|17,19
+205|prov_halifax|1|29,24
+206|prov_iqaluit|1|27,6
+207|prov_yellowknife|1|11,7
+208|prov_nuuk|1|32,6
+209|prov_mexico_city|4|16,43
+210|prov_guadalajara|2|15,42
+211|prov_monterrey|2|16,39
+212|prov_merida|1|20,42
+213|prov_guatemala|1|19,45
+214|prov_panama|2|23,48
+215|prov_havana|2|22,41
+216|prov_santo_domingo|1|26,43
+217|prov_bogota|3|25,51
+218|prov_medellin|2|25,50
+219|prov_caracas|2|28,48
+220|prov_quito|1|23,53
+221|prov_guayaquil|1|23,54
+222|prov_lima|3|24,59
+223|prov_cusco|1|26,59
+224|prov_la_paz|1|27,61
+225|prov_santiago|3|27,68
+226|prov_antofagasta|1|27,64
+227|prov_temuco|1|26,70
+228|prov_coyhaique|1|26,72
+229|prov_punta_arenas|1|26,75
+230|prov_buenos_aires|4|30,69
+231|prov_cordoba_ar|2|28,67
+232|prov_neuquen|1|27,70
+233|prov_comodoro|1|28,72
+234|prov_montevideo|1|31,68
+235|prov_asuncion|1|30,65
+236|prov_sao_paulo|4|33,63
+237|prov_rio|3|34,63
+238|prov_brasilia|2|33,60
+239|prov_salvador|2|35,59
+240|prov_recife|2|36,57
+241|prov_manaus|2|30,54
+242|prov_belem|1|33,54
+243|prov_porto_alegre|2|32,67
+244|prov_sydney|3|116,68
+245|prov_melbourne|3|114,69
+246|prov_brisbane|2|116,66
+247|prov_adelaide|2|111,69
+248|prov_perth|2|99,67
+249|prov_darwin|1|107,59
+250|prov_alice_springs|1|109,64
+251|prov_hobart|1|115,71
+252|prov_auckland|2|119,70
+253|prov_christchurch|1|118,71
diff --git a/app/src/main/assets/scenarios/campaign_cw_01_suez.scn b/app/src/main/assets/scenarios/campaign_cw_01_suez.scn
index e0c0b41..fdfecc5 100644
--- a/app/src/main/assets/scenarios/campaign_cw_01_suez.scn
+++ b/app/src/main/assets/scenarios/campaign_cw_01_suez.scn
@@ -15,42 +15,42 @@ startYear 1956
starTurns 25,28
[nations]
-EGY|nation_egy|#C4A84C|8|BALANCED|1100|1,1,1,3,0,1|🇪🇬|EAST|1
-FRA|nation_fra|#4C5C9E|13|AGGRESSIVE|1400|2,2,3,2,0,2|🇫🇷|WEST|1
-ISR|nation_isr|#5C86B4|6|AGGRESSIVE|900|1,1,1,0,0,1|🇮🇱|WEST|1
-SAU|nation_sau|#4C8C5C|7|TURTLE|500|1,1,1,0,0,1|🇸🇦||1
+EGY|nation_egy|#C4A84C|9|BALANCED|1100|1,1,1,3,0,1|🇪🇬|EAST|1
+FRA|nation_fra|#4C5C9E|14|AGGRESSIVE|1400|2,2,3,2,0,2|🇫🇷|WEST|1
+ISR|nation_isr|#5C86B4|7|AGGRESSIVE|900|1,1,1,0,0,1|🇮🇱|WEST|1
+SAU|nation_sau|#4C8C5C|8|TURTLE|500|1,1,1,0,0,1|🇸🇦||1
ESP|nation_esp|#B08A3C|0|TURTLE|560|1,1,1,0,0,1|🇪🇸||1
-PRT|nation_prt|#4C8C7A|1|TURTLE|300|1,1,1,0,0,1|🇵🇹||1
-GRC|nation_grc|#4C7AA8|2|TURTLE|300|1,1,1,0,0,1|🇬🇷||1
-TUR|nation_tur|#A84C4C|3|TURTLE|740|1,1,1,0,0,1|🇹🇷||1
-SYR|nation_syr|#7A8C5C|5|TURTLE|260|1,1,1,0,0,1|🇸🇾||1
-LBY|nation_lby|#A89A5C|11|TURTLE|320|1,1,1,0,0,1|🇱🇾||1
-TUN|nation_tun|#9E5C5C|12|TURTLE|240|1,1,1,0,0,1|🇹🇳||1
-MAR|nation_mar|#A85C4C|15|TURTLE|380|1,1,1,0,0,1|🇲🇦||1
-GBR|nation_gbr|#8C4C4C|18|TURTLE|1100|1,1,1,0,0,1|🇬🇧||1
-SDN|nation_sdn|#9E8C4C|21|TURTLE|280|1,1,1,0,0,1|🇸🇩||1
-ETH|nation_eth|#6E9E4C|22|TURTLE|340|1,1,1,0,0,1|🇪🇹||1
+GBR|nation_gbr|#8C4C4C|19|TURTLE|1100|1,1,1,0,0,1|🇬🇧||1
+PRT|nation_prt|#4C8C7A|2|TURTLE|300|1,1,1,0,0,1|🇵🇹||1
+GRC|nation_grc|#4C7AA8|3|TURTLE|300|1,1,1,0,0,1|🇬🇷||1
+TUR|nation_tur|#A84C4C|4|TURTLE|740|1,1,1,0,0,1|🇹🇷||1
+SYR|nation_syr|#7A8C5C|6|TURTLE|260|1,1,1,0,0,1|🇸🇾||1
+LBY|nation_lby|#A89A5C|12|TURTLE|320|1,1,1,0,0,1|🇱🇾||1
+TUN|nation_tun|#9E5C5C|13|TURTLE|240|1,1,1,0,0,1|🇹🇳||1
+MAR|nation_mar|#A85C4C|16|TURTLE|380|1,1,1,0,0,1|🇲🇦||1
+SDN|nation_sdn|#9E8C4C|22|TURTLE|280|1,1,1,0,0,1|🇸🇩||1
+ETH|nation_eth|#6E9E4C|23|TURTLE|340|1,1,1,0,0,1|🇪🇹||1
[relations]
FRA EGY WAR
ISR EGY WAR
[owners]
-EGY: 8-10
-FRA: 13-14,16-17,20
-ISR: 6
-SAU: 7
+EGY: 9-11
+FRA: 14-15,17-18,21
+ISR: 7
+SAU: 8
ESP: 0
-PRT: 1
-GRC: 2
-TUR: 3-4
-SYR: 5
-LBY: 11
-TUN: 12
-MAR: 15
-GBR: 18-19
-SDN: 21
-ETH: 22
+GBR: 1,19-20
+PRT: 2
+GRC: 3
+TUR: 4-5
+SYR: 6
+LBY: 12
+TUN: 13
+MAR: 16
+SDN: 22
+ETH: 23
[units]
EGY|43,10|INFANTRY|2|-
@@ -85,6 +85,7 @@ SAU|50,19|INFANTRY|1|-
SAU|51,19|INFANTRY|1|-
ESP|7,2|INFANTRY|1|-
ETH|50,32|INFANTRY|1|-
+GBR|8,4|INFANTRY|1|-
GBR|16,35|INFANTRY|1|-
GBR|21,29|INFANTRY|1|-
GRC|36,2|INFANTRY|1|-
@@ -101,4 +102,4 @@ TUR|39,1|INFANTRY|1|-
EGY
[objectives]
-HOLD_PROVINCES|8-9|25
+HOLD_PROVINCES|9-10|25
diff --git a/app/src/main/assets/scenarios/campaign_cw_01_suez_west.scn b/app/src/main/assets/scenarios/campaign_cw_01_suez_west.scn
index d5b466f..9d26086 100644
--- a/app/src/main/assets/scenarios/campaign_cw_01_suez_west.scn
+++ b/app/src/main/assets/scenarios/campaign_cw_01_suez_west.scn
@@ -15,42 +15,42 @@ startYear 1956
starTurns 18,24
[nations]
-EGY|nation_egy|#C4A84C|8|TURTLE|1100|1,1,1,3,0,1|🇪🇬|EAST|1
-FRA|nation_fra|#4C5C9E|13|AGGRESSIVE|1400|2,2,3,2,0,2|🇫🇷|WEST|1
-ISR|nation_isr|#5C86B4|6|AGGRESSIVE|900|1,1,1,0,0,1|🇮🇱|WEST|1
-SAU|nation_sau|#4C8C5C|7|TURTLE|500|1,1,1,0,0,1|🇸🇦||1
+EGY|nation_egy|#C4A84C|9|TURTLE|1100|1,1,1,3,0,1|🇪🇬|EAST|1
+FRA|nation_fra|#4C5C9E|14|AGGRESSIVE|1400|2,2,3,2,0,2|🇫🇷|WEST|1
+ISR|nation_isr|#5C86B4|7|AGGRESSIVE|900|1,1,1,0,0,1|🇮🇱|WEST|1
+SAU|nation_sau|#4C8C5C|8|TURTLE|500|1,1,1,0,0,1|🇸🇦||1
ESP|nation_esp|#B08A3C|0|TURTLE|560|1,1,1,0,0,1|🇪🇸||1
-PRT|nation_prt|#4C8C7A|1|TURTLE|300|1,1,1,0,0,1|🇵🇹||1
-GRC|nation_grc|#4C7AA8|2|TURTLE|300|1,1,1,0,0,1|🇬🇷||1
-TUR|nation_tur|#A84C4C|3|TURTLE|740|1,1,1,0,0,1|🇹🇷||1
-SYR|nation_syr|#7A8C5C|5|TURTLE|260|1,1,1,0,0,1|🇸🇾||1
-LBY|nation_lby|#A89A5C|11|TURTLE|320|1,1,1,0,0,1|🇱🇾||1
-TUN|nation_tun|#9E5C5C|12|TURTLE|240|1,1,1,0,0,1|🇹🇳||1
-MAR|nation_mar|#A85C4C|15|TURTLE|380|1,1,1,0,0,1|🇲🇦||1
-GBR|nation_gbr|#8C4C4C|18|TURTLE|1100|1,1,1,0,0,1|🇬🇧||1
-SDN|nation_sdn|#9E8C4C|21|TURTLE|280|1,1,1,0,0,1|🇸🇩||1
-ETH|nation_eth|#6E9E4C|22|TURTLE|340|1,1,1,0,0,1|🇪🇹||1
+GBR|nation_gbr|#8C4C4C|19|TURTLE|1100|1,1,1,0,0,1|🇬🇧||1
+PRT|nation_prt|#4C8C7A|2|TURTLE|300|1,1,1,0,0,1|🇵🇹||1
+GRC|nation_grc|#4C7AA8|3|TURTLE|300|1,1,1,0,0,1|🇬🇷||1
+TUR|nation_tur|#A84C4C|4|TURTLE|740|1,1,1,0,0,1|🇹🇷||1
+SYR|nation_syr|#7A8C5C|6|TURTLE|260|1,1,1,0,0,1|🇸🇾||1
+LBY|nation_lby|#A89A5C|12|TURTLE|320|1,1,1,0,0,1|🇱🇾||1
+TUN|nation_tun|#9E5C5C|13|TURTLE|240|1,1,1,0,0,1|🇹🇳||1
+MAR|nation_mar|#A85C4C|16|TURTLE|380|1,1,1,0,0,1|🇲🇦||1
+SDN|nation_sdn|#9E8C4C|22|TURTLE|280|1,1,1,0,0,1|🇸🇩||1
+ETH|nation_eth|#6E9E4C|23|TURTLE|340|1,1,1,0,0,1|🇪🇹||1
[relations]
FRA EGY WAR
ISR EGY WAR
[owners]
-EGY: 8-10
-FRA: 13-14,16-17,20
-ISR: 6
-SAU: 7
+EGY: 9-11
+FRA: 14-15,17-18,21
+ISR: 7
+SAU: 8
ESP: 0
-PRT: 1
-GRC: 2
-TUR: 3-4
-SYR: 5
-LBY: 11
-TUN: 12
-MAR: 15
-GBR: 18-19
-SDN: 21
-ETH: 22
+GBR: 1,19-20
+PRT: 2
+GRC: 3
+TUR: 4-5
+SYR: 6
+LBY: 12
+TUN: 13
+MAR: 16
+SDN: 22
+ETH: 23
[units]
EGY|43,10|INFANTRY|2|-
@@ -85,6 +85,7 @@ SAU|50,19|INFANTRY|1|-
SAU|51,19|INFANTRY|1|-
ESP|7,2|INFANTRY|1|-
ETH|50,32|INFANTRY|1|-
+GBR|8,4|INFANTRY|1|-
GBR|16,35|INFANTRY|1|-
GBR|21,29|INFANTRY|1|-
GRC|36,2|INFANTRY|1|-
@@ -101,4 +102,4 @@ TUR|39,1|INFANTRY|1|-
FRA
[objectives]
-CAPTURE_PROVINCES|8-9|0
+CAPTURE_PROVINCES|9-10|0
diff --git a/app/src/main/assets/scenarios/campaign_cw_02_indochina.scn b/app/src/main/assets/scenarios/campaign_cw_02_indochina.scn
index 9322635..ad7182a 100644
--- a/app/src/main/assets/scenarios/campaign_cw_02_indochina.scn
+++ b/app/src/main/assets/scenarios/campaign_cw_02_indochina.scn
@@ -19,7 +19,7 @@ VNM|nation_vnm|#B4954C|9|BALANCED|1200|1,1,1,3,0,1|🇻🇳|EAST|1
USA|nation_usa|#4C7BA8|10|AGGRESSIVE|2000|3,3,3,2,0,3|🇺🇸|WEST|1
THA|nation_tha|#5C86A8|7|TURTLE|600|1,1,1,0,0,1|🇹🇭|WEST|1
KHM|nation_khm|#7A8C6E|11|TURTLE|400|1,1,1,0,0,1|🇰🇭||1
-CHN|nation_chn|#B4454C|0|TURTLE|1700|1,1,1,0,0,1|🇨🇳||1
+CHN|nation_prc|#B4454C|0|TURTLE|1700|1,1,1,0,0,1|🇨🇳||1
GBR|nation_gbr|#8C4C4C|2|TURTLE|1100|1,1,1,0,0,1|🇬🇧||1
TWN|nation_roc|#4C86B4|3|TURTLE|520|1,1,1,0,0,1|🇹🇼||1
MMR|nation_mmr|#8C9E4C|5|TURTLE|300|1,1,1,0,0,1|🇲🇲||1
diff --git a/app/src/main/assets/scenarios/campaign_cw_02_indochina_west.scn b/app/src/main/assets/scenarios/campaign_cw_02_indochina_west.scn
index 58e363e..c0a44d7 100644
--- a/app/src/main/assets/scenarios/campaign_cw_02_indochina_west.scn
+++ b/app/src/main/assets/scenarios/campaign_cw_02_indochina_west.scn
@@ -19,7 +19,7 @@ VNM|nation_vnm|#B4954C|9|AGGRESSIVE|1200|1,1,1,3,0,1|🇻🇳|EAST|1
USA|nation_usa|#4C7BA8|10|AGGRESSIVE|2000|3,3,3,2,0,3|🇺🇸|WEST|1
THA|nation_tha|#5C86A8|7|TURTLE|600|1,1,1,0,0,1|🇹🇭|WEST|1
KHM|nation_khm|#7A8C6E|11|TURTLE|400|1,1,1,0,0,1|🇰🇭||1
-CHN|nation_chn|#B4454C|0|TURTLE|1700|1,1,1,0,0,1|🇨🇳||1
+CHN|nation_prc|#B4454C|0|TURTLE|1700|1,1,1,0,0,1|🇨🇳||1
GBR|nation_gbr|#8C4C4C|2|TURTLE|1100|1,1,1,0,0,1|🇬🇧||1
TWN|nation_roc|#4C86B4|3|TURTLE|520|1,1,1,0,0,1|🇹🇼||1
MMR|nation_mmr|#8C9E4C|5|TURTLE|300|1,1,1,0,0,1|🇲🇲||1
diff --git a/app/src/main/assets/scenarios/campaign_cw_03_central_front.scn b/app/src/main/assets/scenarios/campaign_cw_03_central_front.scn
index 7b92638..0f15ced 100644
--- a/app/src/main/assets/scenarios/campaign_cw_03_central_front.scn
+++ b/app/src/main/assets/scenarios/campaign_cw_03_central_front.scn
@@ -15,33 +15,33 @@ startYear 1985
starTurns 30,33
[nations]
-DEU|nation_frg|#6E7A86|19|AGGRESSIVE|1600|3,2,3,3,0,3|🇩🇪|NATO|1
-FRA|nation_fra|#4C5C9E|4|BALANCED|1200|1,1,1,0,0,1|🇫🇷|NATO|1
+DEU|nation_frg|#6E7A86|21|AGGRESSIVE|1600|3,2,3,3,0,3|🇩🇪|NATO|1
+FRA|nation_fra|#4C5C9E|5|BALANCED|1200|1,1,1,0,0,1|🇫🇷|NATO|1
GBR|nation_gbr|#8C4C4C|0|BALANCED|1200|1,1,1,0,0,1|🇬🇧|NATO|1
-NLD|nation_nld|#C4813C|8|TURTLE|500|1,1,1,0,0,1|🇳🇱|NATO|1
-BEL|nation_bel|#9E8C4C|7|TURTLE|500|1,1,1,0,0,1|🇧🇪|NATO|1
-DNK|nation_dnk|#A85C6E|33|TURTLE|500|1,1,1,0,0,1|🇩🇰|NATO|1
-RUS|nation_sun|#8C6E4C|41|AGGRESSIVE|2200|3,3,3,2,0,3|🇷🇺|PACT|1
-POL|nation_pol|#B4535C|23|AGGRESSIVE|800|1,1,1,0,0,1|🇵🇱|PACT|1
-CZE|nation_cze|#8A96A0|22|BALANCED|600|1,1,1,0,0,1|🇨🇿|PACT|1
-HUN|nation_hun|#9E7A4C|25|BALANCED|500|1,1,1,0,0,1|🇭🇺|PACT|1
-DDR|nation_ddr|#8C5A5A|17|BALANCED|600|1,1,1,0,0,1||PACT|1
-CHE|nation_che|#B45C5C|16|TURTLE|500|1,1,1,0,0,1|🇨🇭||1
-AUT|nation_aut|#A0A6AC|21|TURTLE|400|1,1,1,0,0,1|🇦🇹||1
-SWE|nation_swe|#4C6E9E|30|TURTLE|500|1,1,1,0,0,1|🇸🇪||1
+NLD|nation_nld|#C4813C|9|TURTLE|500|1,1,1,0,0,1|🇳🇱|NATO|1
+BEL|nation_bel|#9E8C4C|8|TURTLE|500|1,1,1,0,0,1|🇧🇪|NATO|1
+DNK|nation_dnk|#A85C6E|35|TURTLE|500|1,1,1,0,0,1|🇩🇰|NATO|1
+RUS|nation_sun|#8C6E4C|43|AGGRESSIVE|2200|3,3,3,2,0,3|🇷🇺|PACT|1
+POL|nation_pol|#B4535C|25|AGGRESSIVE|800|1,1,1,0,0,1|🇵🇱|PACT|1
+CZE|nation_cze|#8A96A0|24|BALANCED|600|1,1,1,0,0,1|🇨🇿|PACT|1
+HUN|nation_hun|#9E7A4C|27|BALANCED|500|1,1,1,0,0,1|🇭🇺|PACT|1
+DDR|nation_ddr|#8C5A5A|19|BALANCED|600|1,1,1,0,0,1||PACT|1
+CHE|nation_che|#B45C5C|18|TURTLE|500|1,1,1,0,0,1|🇨🇭||1
+AUT|nation_aut|#A0A6AC|23|TURTLE|400|1,1,1,0,0,1|🇦🇹||1
+SWE|nation_swe|#4C6E9E|32|TURTLE|500|1,1,1,0,0,1|🇸🇪||1
IRL|nation_irl|#4C8C5C|3|TURTLE|300|1,1,1,0,0,1|🇮🇪||1
-ESP|nation_esp|#B08A3C|9|TURTLE|560|1,1,1,0,0,1|🇪🇸||1
-PRT|nation_prt|#4C8C7A|12|TURTLE|300|1,1,1,0,0,1|🇵🇹||1
-ITA|nation_ita|#5C9E6E|13|TURTLE|700|1,1,1,0,0,1|🇮🇹||1
-ROU|nation_rou|#8C7A3C|26|TURTLE|320|1,1,1,0,0,1|🇷🇴||1
-SRB|nation_srb|#8C5C4C|27|TURTLE|260|1,1,1,0,0,1|🇷🇸||1
-BGR|nation_bgr|#6E8C5C|28|TURTLE|240|1,1,1,0,0,1|🇧🇬||1
-GRC|nation_grc|#4C7AA8|29|TURTLE|300|1,1,1,0,0,1|🇬🇷||1
-NOR|nation_nor|#5C7EA8|32|TURTLE|380|1,1,1,0,0,1|🇳🇴||1
-FIN|nation_fin|#7A9EB4|35|TURTLE|320|1,1,1,0,0,1|🇫🇮||1
-TUR|nation_tur|#A84C4C|44|TURTLE|740|1,1,1,0,0,1|🇹🇷||1
-TUN|nation_tun|#9E5C5C|47|TURTLE|240|1,1,1,0,0,1|🇹🇳||1
-DZA|nation_dza|#5C9E5C|48|TURTLE|460|1,1,1,0,0,1|🇩🇿||1
+ESP|nation_esp|#B08A3C|10|TURTLE|560|1,1,1,0,0,1|🇪🇸||1
+PRT|nation_prt|#4C8C7A|14|TURTLE|300|1,1,1,0,0,1|🇵🇹||1
+ITA|nation_ita|#5C9E6E|15|TURTLE|700|1,1,1,0,0,1|🇮🇹||1
+ROU|nation_rou|#8C7A3C|28|TURTLE|320|1,1,1,0,0,1|🇷🇴||1
+SRB|nation_srb|#8C5C4C|29|TURTLE|260|1,1,1,0,0,1|🇷🇸||1
+BGR|nation_bgr|#6E8C5C|30|TURTLE|240|1,1,1,0,0,1|🇧🇬||1
+GRC|nation_grc|#4C7AA8|31|TURTLE|300|1,1,1,0,0,1|🇬🇷||1
+NOR|nation_nor|#5C7EA8|34|TURTLE|380|1,1,1,0,0,1|🇳🇴||1
+FIN|nation_fin|#7A9EB4|37|TURTLE|320|1,1,1,0,0,1|🇫🇮||1
+TUR|nation_tur|#A84C4C|46|TURTLE|740|1,1,1,0,0,1|🇹🇷||1
+TUN|nation_tun|#9E5C5C|49|TURTLE|240|1,1,1,0,0,1|🇹🇳||1
+DZA|nation_dza|#5C9E5C|50|TURTLE|460|1,1,1,0,0,1|🇩🇿||1
[relations]
DEU RUS WAR
@@ -76,33 +76,33 @@ DNK HUN WAR
DNK DDR WAR
[owners]
-DEU: 18-20
-FRA: 4-6
-GBR: 0-2
-NLD: 8
-BEL: 7
-DNK: 33-34
-RUS: 36-43
-POL: 23-24
-CZE: 22
-HUN: 25
-DDR: 17
-CHE: 16
-AUT: 21
-SWE: 30-31
+DEU: 20-22
+FRA: 5-7
+GBR: 0-2,4,13
+NLD: 9
+BEL: 8
+DNK: 35-36
+RUS: 38-45
+POL: 25-26
+CZE: 24
+HUN: 27
+DDR: 19
+CHE: 18
+AUT: 23
+SWE: 32-33
IRL: 3
-ESP: 9-11
-PRT: 12
-ITA: 13-15
-ROU: 26
-SRB: 27
-BGR: 28
-GRC: 29
-NOR: 32
-FIN: 35
-TUR: 44-46
-TUN: 47
-DZA: 48
+ESP: 10-12
+PRT: 14
+ITA: 15-17
+ROU: 28
+SRB: 29
+BGR: 30
+GRC: 31
+NOR: 34
+FIN: 37
+TUR: 46-48
+TUN: 49
+DZA: 50
[units]
DEU|21,12|HEADQUARTERS|2|-
@@ -194,4 +194,4 @@ TUR|38,35|INFANTRY|1|-
DEU
[objectives]
-HOLD_PROVINCES|18-20|30
+HOLD_PROVINCES|20-22|30
diff --git a/app/src/main/assets/scenarios/campaign_cw_03_central_front_pact.scn b/app/src/main/assets/scenarios/campaign_cw_03_central_front_pact.scn
index 4e37df8..795b561 100644
--- a/app/src/main/assets/scenarios/campaign_cw_03_central_front_pact.scn
+++ b/app/src/main/assets/scenarios/campaign_cw_03_central_front_pact.scn
@@ -15,33 +15,33 @@ startYear 1985
starTurns 22,30
[nations]
-DEU|nation_frg|#6E7A86|19|BALANCED|1600|3,2,3,3,0,3|🇩🇪|NATO|1
-FRA|nation_fra|#4C5C9E|4|BALANCED|1200|1,1,1,0,0,1|🇫🇷|NATO|1
+DEU|nation_frg|#6E7A86|21|BALANCED|1600|3,2,3,3,0,3|🇩🇪|NATO|1
+FRA|nation_fra|#4C5C9E|5|BALANCED|1200|1,1,1,0,0,1|🇫🇷|NATO|1
GBR|nation_gbr|#8C4C4C|0|BALANCED|1200|1,1,1,0,0,1|🇬🇧|NATO|1
-NLD|nation_nld|#C4813C|8|TURTLE|500|1,1,1,0,0,1|🇳🇱|NATO|1
-BEL|nation_bel|#9E8C4C|7|TURTLE|500|1,1,1,0,0,1|🇧🇪|NATO|1
-DNK|nation_dnk|#A85C6E|33|TURTLE|500|1,1,1,0,0,1|🇩🇰|NATO|1
-RUS|nation_sun|#8C6E4C|41|AGGRESSIVE|2200|3,3,3,2,0,3|🇷🇺|PACT|1
-POL|nation_pol|#B4535C|23|AGGRESSIVE|800|1,1,1,0,0,1|🇵🇱|PACT|1
-CZE|nation_cze|#8A96A0|22|BALANCED|600|1,1,1,0,0,1|🇨🇿|PACT|1
-HUN|nation_hun|#9E7A4C|25|BALANCED|500|1,1,1,0,0,1|🇭🇺|PACT|1
-DDR|nation_ddr|#8C5A5A|17|BALANCED|600|1,1,1,0,0,1||PACT|1
-CHE|nation_che|#B45C5C|16|TURTLE|500|1,1,1,0,0,1|🇨🇭||1
-AUT|nation_aut|#A0A6AC|21|TURTLE|400|1,1,1,0,0,1|🇦🇹||1
-SWE|nation_swe|#4C6E9E|30|TURTLE|500|1,1,1,0,0,1|🇸🇪||1
+NLD|nation_nld|#C4813C|9|TURTLE|500|1,1,1,0,0,1|🇳🇱|NATO|1
+BEL|nation_bel|#9E8C4C|8|TURTLE|500|1,1,1,0,0,1|🇧🇪|NATO|1
+DNK|nation_dnk|#A85C6E|35|TURTLE|500|1,1,1,0,0,1|🇩🇰|NATO|1
+RUS|nation_sun|#8C6E4C|43|AGGRESSIVE|2200|3,3,3,2,0,3|🇷🇺|PACT|1
+POL|nation_pol|#B4535C|25|AGGRESSIVE|800|1,1,1,0,0,1|🇵🇱|PACT|1
+CZE|nation_cze|#8A96A0|24|BALANCED|600|1,1,1,0,0,1|🇨🇿|PACT|1
+HUN|nation_hun|#9E7A4C|27|BALANCED|500|1,1,1,0,0,1|🇭🇺|PACT|1
+DDR|nation_ddr|#8C5A5A|19|BALANCED|600|1,1,1,0,0,1||PACT|1
+CHE|nation_che|#B45C5C|18|TURTLE|500|1,1,1,0,0,1|🇨🇭||1
+AUT|nation_aut|#A0A6AC|23|TURTLE|400|1,1,1,0,0,1|🇦🇹||1
+SWE|nation_swe|#4C6E9E|32|TURTLE|500|1,1,1,0,0,1|🇸🇪||1
IRL|nation_irl|#4C8C5C|3|TURTLE|300|1,1,1,0,0,1|🇮🇪||1
-ESP|nation_esp|#B08A3C|9|TURTLE|560|1,1,1,0,0,1|🇪🇸||1
-PRT|nation_prt|#4C8C7A|12|TURTLE|300|1,1,1,0,0,1|🇵🇹||1
-ITA|nation_ita|#5C9E6E|13|TURTLE|700|1,1,1,0,0,1|🇮🇹||1
-ROU|nation_rou|#8C7A3C|26|TURTLE|320|1,1,1,0,0,1|🇷🇴||1
-SRB|nation_srb|#8C5C4C|27|TURTLE|260|1,1,1,0,0,1|🇷🇸||1
-BGR|nation_bgr|#6E8C5C|28|TURTLE|240|1,1,1,0,0,1|🇧🇬||1
-GRC|nation_grc|#4C7AA8|29|TURTLE|300|1,1,1,0,0,1|🇬🇷||1
-NOR|nation_nor|#5C7EA8|32|TURTLE|380|1,1,1,0,0,1|🇳🇴||1
-FIN|nation_fin|#7A9EB4|35|TURTLE|320|1,1,1,0,0,1|🇫🇮||1
-TUR|nation_tur|#A84C4C|44|TURTLE|740|1,1,1,0,0,1|🇹🇷||1
-TUN|nation_tun|#9E5C5C|47|TURTLE|240|1,1,1,0,0,1|🇹🇳||1
-DZA|nation_dza|#5C9E5C|48|TURTLE|460|1,1,1,0,0,1|🇩🇿||1
+ESP|nation_esp|#B08A3C|10|TURTLE|560|1,1,1,0,0,1|🇪🇸||1
+PRT|nation_prt|#4C8C7A|14|TURTLE|300|1,1,1,0,0,1|🇵🇹||1
+ITA|nation_ita|#5C9E6E|15|TURTLE|700|1,1,1,0,0,1|🇮🇹||1
+ROU|nation_rou|#8C7A3C|28|TURTLE|320|1,1,1,0,0,1|🇷🇴||1
+SRB|nation_srb|#8C5C4C|29|TURTLE|260|1,1,1,0,0,1|🇷🇸||1
+BGR|nation_bgr|#6E8C5C|30|TURTLE|240|1,1,1,0,0,1|🇧🇬||1
+GRC|nation_grc|#4C7AA8|31|TURTLE|300|1,1,1,0,0,1|🇬🇷||1
+NOR|nation_nor|#5C7EA8|34|TURTLE|380|1,1,1,0,0,1|🇳🇴||1
+FIN|nation_fin|#7A9EB4|37|TURTLE|320|1,1,1,0,0,1|🇫🇮||1
+TUR|nation_tur|#A84C4C|46|TURTLE|740|1,1,1,0,0,1|🇹🇷||1
+TUN|nation_tun|#9E5C5C|49|TURTLE|240|1,1,1,0,0,1|🇹🇳||1
+DZA|nation_dza|#5C9E5C|50|TURTLE|460|1,1,1,0,0,1|🇩🇿||1
[relations]
DEU RUS WAR
@@ -76,33 +76,33 @@ DNK HUN WAR
DNK DDR WAR
[owners]
-DEU: 18-20
-FRA: 4-6
-GBR: 0-2
-NLD: 8
-BEL: 7
-DNK: 33-34
-RUS: 36-43
-POL: 23-24
-CZE: 22
-HUN: 25
-DDR: 17
-CHE: 16
-AUT: 21
-SWE: 30-31
+DEU: 20-22
+FRA: 5-7
+GBR: 0-2,4,13
+NLD: 9
+BEL: 8
+DNK: 35-36
+RUS: 38-45
+POL: 25-26
+CZE: 24
+HUN: 27
+DDR: 19
+CHE: 18
+AUT: 23
+SWE: 32-33
IRL: 3
-ESP: 9-11
-PRT: 12
-ITA: 13-15
-ROU: 26
-SRB: 27
-BGR: 28
-GRC: 29
-NOR: 32
-FIN: 35
-TUR: 44-46
-TUN: 47
-DZA: 48
+ESP: 10-12
+PRT: 14
+ITA: 15-17
+ROU: 28
+SRB: 29
+BGR: 30
+GRC: 31
+NOR: 34
+FIN: 37
+TUR: 46-48
+TUN: 49
+DZA: 50
[units]
DEU|21,12|HEADQUARTERS|2|-
@@ -194,4 +194,4 @@ TUR|38,35|INFANTRY|1|-
RUS
[objectives]
-CAPTURE_PROVINCES|18-19|0
+CAPTURE_PROVINCES|20-21|0
diff --git a/app/src/main/assets/scenarios/campaign_ww2_01_poland.scn b/app/src/main/assets/scenarios/campaign_ww2_01_poland.scn
index 9a7cfd3..bc49d5f 100644
--- a/app/src/main/assets/scenarios/campaign_ww2_01_poland.scn
+++ b/app/src/main/assets/scenarios/campaign_ww2_01_poland.scn
@@ -15,55 +15,55 @@ startYear 1939
starTurns 20,23
[nations]
-POL|nation_pol|#B4535C|23|BALANCED|700|1,1,1,0,0,1|🇵🇱|ALLIES|1
-DEU|nation_deu|#6E7A86|17|AGGRESSIVE|1500|3,3,2,1,0,2|🇩🇪|AXIS|1
-RUS|nation_sun|#8C6E4C|41|TURTLE|600|1,1,1,0,0,1|🇷🇺||1
-SWE|nation_swe|#4C6E9E|30|TURTLE|400|1,1,1,0,0,1|🇸🇪||1
+POL|nation_pol|#B4535C|25|BALANCED|700|1,1,1,0,0,1|🇵🇱|ALLIES|1
+DEU|nation_deu|#6E7A86|19|AGGRESSIVE|1500|3,3,2,1,0,2|🇩🇪|AXIS|1
+RUS|nation_sun|#8C6E4C|43|TURTLE|600|1,1,1,0,0,1|🇷🇺||1
+SWE|nation_swe|#4C6E9E|32|TURTLE|400|1,1,1,0,0,1|🇸🇪||1
GBR|nation_gbr|#8C4C4C|0|TURTLE|1100|1,1,1,0,0,1|🇬🇧||1
IRL|nation_irl|#4C8C5C|3|TURTLE|260|1,1,1,0,0,1|🇮🇪||1
-FRA|nation_fra|#4C5C9E|4|TURTLE|950|1,1,1,0,0,1|🇫🇷||1
-BEL|nation_bel|#9E8C4C|7|TURTLE|320|1,1,1,0,0,1|🇧🇪||1
-NLD|nation_nld|#C4813C|8|TURTLE|380|1,1,1,0,0,1|🇳🇱||1
-ESP|nation_esp|#B08A3C|9|TURTLE|560|1,1,1,0,0,1|🇪🇸||1
-PRT|nation_prt|#4C8C7A|12|TURTLE|300|1,1,1,0,0,1|🇵🇹||1
-ITA|nation_ita|#5C9E6E|13|TURTLE|700|1,1,1,0,0,1|🇮🇹||1
-CHE|nation_che|#B45C5C|16|TURTLE|360|1,1,1,0,0,1|🇨🇭||1
-HUN|nation_hun|#9E7A4C|25|TURTLE|300|1,1,1,0,0,1|🇭🇺||1
-ROU|nation_rou|#8C7A3C|26|TURTLE|320|1,1,1,0,0,1|🇷🇴||1
-SRB|nation_srb|#8C5C4C|27|TURTLE|260|1,1,1,0,0,1|🇷🇸||1
-BGR|nation_bgr|#6E8C5C|28|TURTLE|240|1,1,1,0,0,1|🇧🇬||1
-GRC|nation_grc|#4C7AA8|29|TURTLE|300|1,1,1,0,0,1|🇬🇷||1
-NOR|nation_nor|#5C7EA8|32|TURTLE|380|1,1,1,0,0,1|🇳🇴||1
-DNK|nation_dnk|#A85C6E|33|TURTLE|320|1,1,1,0,0,1|🇩🇰||1
-FIN|nation_fin|#7A9EB4|35|TURTLE|320|1,1,1,0,0,1|🇫🇮||1
-TUR|nation_tur|#A84C4C|44|TURTLE|740|1,1,1,0,0,1|🇹🇷||1
+FRA|nation_fra|#4C5C9E|5|TURTLE|950|1,1,1,0,0,1|🇫🇷||1
+BEL|nation_bel|#9E8C4C|8|TURTLE|320|1,1,1,0,0,1|🇧🇪||1
+NLD|nation_nld|#C4813C|9|TURTLE|380|1,1,1,0,0,1|🇳🇱||1
+ESP|nation_esp|#B08A3C|10|TURTLE|560|1,1,1,0,0,1|🇪🇸||1
+PRT|nation_prt|#4C8C7A|14|TURTLE|300|1,1,1,0,0,1|🇵🇹||1
+ITA|nation_ita|#5C9E6E|15|TURTLE|700|1,1,1,0,0,1|🇮🇹||1
+CHE|nation_che|#B45C5C|18|TURTLE|360|1,1,1,0,0,1|🇨🇭||1
+HUN|nation_hun|#9E7A4C|27|TURTLE|300|1,1,1,0,0,1|🇭🇺||1
+ROU|nation_rou|#8C7A3C|28|TURTLE|320|1,1,1,0,0,1|🇷🇴||1
+SRB|nation_srb|#8C5C4C|29|TURTLE|260|1,1,1,0,0,1|🇷🇸||1
+BGR|nation_bgr|#6E8C5C|30|TURTLE|240|1,1,1,0,0,1|🇧🇬||1
+GRC|nation_grc|#4C7AA8|31|TURTLE|300|1,1,1,0,0,1|🇬🇷||1
+NOR|nation_nor|#5C7EA8|34|TURTLE|380|1,1,1,0,0,1|🇳🇴||1
+DNK|nation_dnk|#A85C6E|35|TURTLE|320|1,1,1,0,0,1|🇩🇰||1
+FIN|nation_fin|#7A9EB4|37|TURTLE|320|1,1,1,0,0,1|🇫🇮||1
+TUR|nation_tur|#A84C4C|46|TURTLE|740|1,1,1,0,0,1|🇹🇷||1
[relations]
DEU POL WAR
[owners]
-POL: 23-24
-DEU: 17-22
-RUS: 36-43
-SWE: 30-31
-GBR: 0-2
+POL: 25-26
+DEU: 19-24
+RUS: 38-45
+SWE: 32-33
+GBR: 0-2,4,13
IRL: 3
-FRA: 4-6,47-48
-BEL: 7
-NLD: 8
-ESP: 9-11
-PRT: 12
-ITA: 13-15
-CHE: 16
-HUN: 25
-ROU: 26
-SRB: 27
-BGR: 28
-GRC: 29
-NOR: 32
-DNK: 33-34
-FIN: 35
-TUR: 44-46
+FRA: 5-7,49-50
+BEL: 8
+NLD: 9
+ESP: 10-12
+PRT: 14
+ITA: 15-17
+CHE: 18
+HUN: 27
+ROU: 28
+SRB: 29
+BGR: 30
+GRC: 31
+NOR: 34
+DNK: 35-36
+FIN: 37
+TUR: 46-48
[units]
POL|32,14|INFANTRY|2|-
@@ -112,6 +112,8 @@ FRA|14,37|INFANTRY|1|-
GBR|11,15|INFANTRY|1|-
GBR|9,12|INFANTRY|1|-
GBR|8,9|INFANTRY|1|-
+GBR|5,11|INFANTRY|1|-
+GBR|6,38|INFANTRY|1|-
GRC|35,36|INFANTRY|1|-
HUN|30,21|INFANTRY|1|-
IRL|5,12|INFANTRY|1|-
@@ -131,4 +133,4 @@ TUR|38,35|INFANTRY|1|-
POL
[objectives]
-HOLD_PROVINCES|23|20
+HOLD_PROVINCES|25|20
diff --git a/app/src/main/assets/scenarios/campaign_ww2_01_poland_axis.scn b/app/src/main/assets/scenarios/campaign_ww2_01_poland_axis.scn
index 4ac9b73..cfd539a 100644
--- a/app/src/main/assets/scenarios/campaign_ww2_01_poland_axis.scn
+++ b/app/src/main/assets/scenarios/campaign_ww2_01_poland_axis.scn
@@ -15,55 +15,55 @@ startYear 1939
starTurns 12,16
[nations]
-POL|nation_pol|#B4535C|23|TURTLE|700|1,1,1,0,0,1|🇵🇱|ALLIES|1
-DEU|nation_deu|#6E7A86|17|AGGRESSIVE|1500|3,3,2,1,0,2|🇩🇪|AXIS|1
-RUS|nation_sun|#8C6E4C|41|TURTLE|600|1,1,1,0,0,1|🇷🇺||1
-SWE|nation_swe|#4C6E9E|30|TURTLE|400|1,1,1,0,0,1|🇸🇪||1
+POL|nation_pol|#B4535C|25|TURTLE|700|1,1,1,0,0,1|🇵🇱|ALLIES|1
+DEU|nation_deu|#6E7A86|19|AGGRESSIVE|1500|3,3,2,1,0,2|🇩🇪|AXIS|1
+RUS|nation_sun|#8C6E4C|43|TURTLE|600|1,1,1,0,0,1|🇷🇺||1
+SWE|nation_swe|#4C6E9E|32|TURTLE|400|1,1,1,0,0,1|🇸🇪||1
GBR|nation_gbr|#8C4C4C|0|TURTLE|1100|1,1,1,0,0,1|🇬🇧||1
IRL|nation_irl|#4C8C5C|3|TURTLE|260|1,1,1,0,0,1|🇮🇪||1
-FRA|nation_fra|#4C5C9E|4|TURTLE|950|1,1,1,0,0,1|🇫🇷||1
-BEL|nation_bel|#9E8C4C|7|TURTLE|320|1,1,1,0,0,1|🇧🇪||1
-NLD|nation_nld|#C4813C|8|TURTLE|380|1,1,1,0,0,1|🇳🇱||1
-ESP|nation_esp|#B08A3C|9|TURTLE|560|1,1,1,0,0,1|🇪🇸||1
-PRT|nation_prt|#4C8C7A|12|TURTLE|300|1,1,1,0,0,1|🇵🇹||1
-ITA|nation_ita|#5C9E6E|13|TURTLE|700|1,1,1,0,0,1|🇮🇹||1
-CHE|nation_che|#B45C5C|16|TURTLE|360|1,1,1,0,0,1|🇨🇭||1
-HUN|nation_hun|#9E7A4C|25|TURTLE|300|1,1,1,0,0,1|🇭🇺||1
-ROU|nation_rou|#8C7A3C|26|TURTLE|320|1,1,1,0,0,1|🇷🇴||1
-SRB|nation_srb|#8C5C4C|27|TURTLE|260|1,1,1,0,0,1|🇷🇸||1
-BGR|nation_bgr|#6E8C5C|28|TURTLE|240|1,1,1,0,0,1|🇧🇬||1
-GRC|nation_grc|#4C7AA8|29|TURTLE|300|1,1,1,0,0,1|🇬🇷||1
-NOR|nation_nor|#5C7EA8|32|TURTLE|380|1,1,1,0,0,1|🇳🇴||1
-DNK|nation_dnk|#A85C6E|33|TURTLE|320|1,1,1,0,0,1|🇩🇰||1
-FIN|nation_fin|#7A9EB4|35|TURTLE|320|1,1,1,0,0,1|🇫🇮||1
-TUR|nation_tur|#A84C4C|44|TURTLE|740|1,1,1,0,0,1|🇹🇷||1
+FRA|nation_fra|#4C5C9E|5|TURTLE|950|1,1,1,0,0,1|🇫🇷||1
+BEL|nation_bel|#9E8C4C|8|TURTLE|320|1,1,1,0,0,1|🇧🇪||1
+NLD|nation_nld|#C4813C|9|TURTLE|380|1,1,1,0,0,1|🇳🇱||1
+ESP|nation_esp|#B08A3C|10|TURTLE|560|1,1,1,0,0,1|🇪🇸||1
+PRT|nation_prt|#4C8C7A|14|TURTLE|300|1,1,1,0,0,1|🇵🇹||1
+ITA|nation_ita|#5C9E6E|15|TURTLE|700|1,1,1,0,0,1|🇮🇹||1
+CHE|nation_che|#B45C5C|18|TURTLE|360|1,1,1,0,0,1|🇨🇭||1
+HUN|nation_hun|#9E7A4C|27|TURTLE|300|1,1,1,0,0,1|🇭🇺||1
+ROU|nation_rou|#8C7A3C|28|TURTLE|320|1,1,1,0,0,1|🇷🇴||1
+SRB|nation_srb|#8C5C4C|29|TURTLE|260|1,1,1,0,0,1|🇷🇸||1
+BGR|nation_bgr|#6E8C5C|30|TURTLE|240|1,1,1,0,0,1|🇧🇬||1
+GRC|nation_grc|#4C7AA8|31|TURTLE|300|1,1,1,0,0,1|🇬🇷||1
+NOR|nation_nor|#5C7EA8|34|TURTLE|380|1,1,1,0,0,1|🇳🇴||1
+DNK|nation_dnk|#A85C6E|35|TURTLE|320|1,1,1,0,0,1|🇩🇰||1
+FIN|nation_fin|#7A9EB4|37|TURTLE|320|1,1,1,0,0,1|🇫🇮||1
+TUR|nation_tur|#A84C4C|46|TURTLE|740|1,1,1,0,0,1|🇹🇷||1
[relations]
DEU POL WAR
[owners]
-POL: 23-24
-DEU: 17-22
-RUS: 36-43
-SWE: 30-31
-GBR: 0-2
+POL: 25-26
+DEU: 19-24
+RUS: 38-45
+SWE: 32-33
+GBR: 0-2,4,13
IRL: 3
-FRA: 4-6,47-48
-BEL: 7
-NLD: 8
-ESP: 9-11
-PRT: 12
-ITA: 13-15
-CHE: 16
-HUN: 25
-ROU: 26
-SRB: 27
-BGR: 28
-GRC: 29
-NOR: 32
-DNK: 33-34
-FIN: 35
-TUR: 44-46
+FRA: 5-7,49-50
+BEL: 8
+NLD: 9
+ESP: 10-12
+PRT: 14
+ITA: 15-17
+CHE: 18
+HUN: 27
+ROU: 28
+SRB: 29
+BGR: 30
+GRC: 31
+NOR: 34
+DNK: 35-36
+FIN: 37
+TUR: 46-48
[units]
POL|32,14|INFANTRY|2|-
@@ -112,6 +112,8 @@ FRA|14,37|INFANTRY|1|-
GBR|11,15|INFANTRY|1|-
GBR|9,12|INFANTRY|1|-
GBR|8,9|INFANTRY|1|-
+GBR|5,11|INFANTRY|1|-
+GBR|6,38|INFANTRY|1|-
GRC|35,36|INFANTRY|1|-
HUN|30,21|INFANTRY|1|-
IRL|5,12|INFANTRY|1|-
@@ -131,4 +133,4 @@ TUR|38,35|INFANTRY|1|-
DEU
[objectives]
-CAPTURE_PROVINCES|23-24|0
+CAPTURE_PROVINCES|25-26|0
diff --git a/app/src/main/assets/scenarios/campaign_ww2_02_france.scn b/app/src/main/assets/scenarios/campaign_ww2_02_france.scn
index 9699e3d..1c23727 100644
--- a/app/src/main/assets/scenarios/campaign_ww2_02_france.scn
+++ b/app/src/main/assets/scenarios/campaign_ww2_02_france.scn
@@ -15,28 +15,28 @@ startYear 1940
starTurns 16,22
[nations]
-DEU|nation_deu|#6E7A86|17|AGGRESSIVE|1600|3,3,2,1,0,2|🇩🇪|AXIS|1
-FRA|nation_fra|#4C5C9E|4|TURTLE|1100|2,1,2,0,0,1|🇫🇷|ALLIES|1
+DEU|nation_deu|#6E7A86|19|AGGRESSIVE|1600|3,3,2,1,0,2|🇩🇪|AXIS|1
+FRA|nation_fra|#4C5C9E|5|TURTLE|1100|2,1,2,0,0,1|🇫🇷|ALLIES|1
GBR|nation_gbr|#8C4C4C|0|BALANCED|1000|1,1,1,0,0,1|🇬🇧|ALLIES|1
-BEL|nation_bel|#9E8C4C|7|TURTLE|400|1,1,1,0,0,1|🇧🇪|ALLIES|1
-NLD|nation_nld|#C4813C|8|TURTLE|400|1,1,1,0,0,1|🇳🇱|ALLIES|1
-CHE|nation_che|#B45C5C|16|TURTLE|500|1,1,1,0,0,1|🇨🇭||1
-ESP|nation_esp|#B08A3C|9|TURTLE|500|1,1,1,0,0,1|🇪🇸||1
+BEL|nation_bel|#9E8C4C|8|TURTLE|400|1,1,1,0,0,1|🇧🇪|ALLIES|1
+NLD|nation_nld|#C4813C|9|TURTLE|400|1,1,1,0,0,1|🇳🇱|ALLIES|1
+CHE|nation_che|#B45C5C|18|TURTLE|500|1,1,1,0,0,1|🇨🇭||1
+ESP|nation_esp|#B08A3C|10|TURTLE|500|1,1,1,0,0,1|🇪🇸||1
IRL|nation_irl|#4C8C5C|3|TURTLE|260|1,1,1,0,0,1|🇮🇪||1
-PRT|nation_prt|#4C8C7A|12|TURTLE|300|1,1,1,0,0,1|🇵🇹||1
-ITA|nation_ita|#5C9E6E|13|TURTLE|700|1,1,1,0,0,1|🇮🇹||1
-POL|nation_pol|#B4535C|23|TURTLE|520|1,1,1,0,0,1|🇵🇱||1
-HUN|nation_hun|#9E7A4C|25|TURTLE|300|1,1,1,0,0,1|🇭🇺||1
-ROU|nation_rou|#8C7A3C|26|TURTLE|320|1,1,1,0,0,1|🇷🇴||1
-SRB|nation_srb|#8C5C4C|27|TURTLE|260|1,1,1,0,0,1|🇷🇸||1
-BGR|nation_bgr|#6E8C5C|28|TURTLE|240|1,1,1,0,0,1|🇧🇬||1
-GRC|nation_grc|#4C7AA8|29|TURTLE|300|1,1,1,0,0,1|🇬🇷||1
-SWE|nation_swe|#4C6E9E|30|TURTLE|420|1,1,1,0,0,1|🇸🇪||1
-NOR|nation_nor|#5C7EA8|32|TURTLE|380|1,1,1,0,0,1|🇳🇴||1
-DNK|nation_dnk|#A85C6E|33|TURTLE|320|1,1,1,0,0,1|🇩🇰||1
-FIN|nation_fin|#7A9EB4|35|TURTLE|320|1,1,1,0,0,1|🇫🇮||1
-RUS|nation_sun|#8C6E4C|41|TURTLE|1500|1,1,1,0,0,1|🇷🇺||1
-TUR|nation_tur|#A84C4C|44|TURTLE|740|1,1,1,0,0,1|🇹🇷||1
+PRT|nation_prt|#4C8C7A|14|TURTLE|300|1,1,1,0,0,1|🇵🇹||1
+ITA|nation_ita|#5C9E6E|15|TURTLE|700|1,1,1,0,0,1|🇮🇹||1
+POL|nation_pol|#B4535C|25|TURTLE|520|1,1,1,0,0,1|🇵🇱||1
+HUN|nation_hun|#9E7A4C|27|TURTLE|300|1,1,1,0,0,1|🇭🇺||1
+ROU|nation_rou|#8C7A3C|28|TURTLE|320|1,1,1,0,0,1|🇷🇴||1
+SRB|nation_srb|#8C5C4C|29|TURTLE|260|1,1,1,0,0,1|🇷🇸||1
+BGR|nation_bgr|#6E8C5C|30|TURTLE|240|1,1,1,0,0,1|🇧🇬||1
+GRC|nation_grc|#4C7AA8|31|TURTLE|300|1,1,1,0,0,1|🇬🇷||1
+SWE|nation_swe|#4C6E9E|32|TURTLE|420|1,1,1,0,0,1|🇸🇪||1
+NOR|nation_nor|#5C7EA8|34|TURTLE|380|1,1,1,0,0,1|🇳🇴||1
+DNK|nation_dnk|#A85C6E|35|TURTLE|320|1,1,1,0,0,1|🇩🇰||1
+FIN|nation_fin|#7A9EB4|37|TURTLE|320|1,1,1,0,0,1|🇫🇮||1
+RUS|nation_sun|#8C6E4C|43|TURTLE|1500|1,1,1,0,0,1|🇷🇺||1
+TUR|nation_tur|#A84C4C|46|TURTLE|740|1,1,1,0,0,1|🇹🇷||1
[relations]
DEU FRA WAR
@@ -45,28 +45,28 @@ DEU BEL WAR
DEU NLD WAR
[owners]
-DEU: 17-22
-FRA: 4-6,47-48
-GBR: 0-2
-BEL: 7
-NLD: 8
-CHE: 16
-ESP: 9-11
+DEU: 19-24
+FRA: 5-7,49-50
+GBR: 0-2,4,13
+BEL: 8
+NLD: 9
+CHE: 18
+ESP: 10-12
IRL: 3
-PRT: 12
-ITA: 13-15
-POL: 23-24
-HUN: 25
-ROU: 26
-SRB: 27
-BGR: 28
-GRC: 29
-SWE: 30-31
-NOR: 32
-DNK: 33-34
-FIN: 35
-RUS: 36-43
-TUR: 44-46
+PRT: 14
+ITA: 15-17
+POL: 25-26
+HUN: 27
+ROU: 28
+SRB: 29
+BGR: 30
+GRC: 31
+SWE: 32-33
+NOR: 34
+DNK: 35-36
+FIN: 37
+RUS: 38-45
+TUR: 46-48
[units]
DEU|25,14|HEADQUARTERS|1|-
@@ -146,4 +146,4 @@ TUR|38,35|INFANTRY|1|-
DEU
[objectives]
-CAPTURE_PROVINCES|4,7|0
+CAPTURE_PROVINCES|5,8|0
diff --git a/app/src/main/assets/scenarios/campaign_ww2_02_france_allies.scn b/app/src/main/assets/scenarios/campaign_ww2_02_france_allies.scn
index 9ae90e7..e53079e 100644
--- a/app/src/main/assets/scenarios/campaign_ww2_02_france_allies.scn
+++ b/app/src/main/assets/scenarios/campaign_ww2_02_france_allies.scn
@@ -15,28 +15,28 @@ startYear 1940
starTurns 20,23
[nations]
-DEU|nation_deu|#6E7A86|17|AGGRESSIVE|1600|3,3,2,1,0,2|🇩🇪|AXIS|1
-FRA|nation_fra|#4C5C9E|4|TURTLE|1100|2,1,2,0,0,1|🇫🇷|ALLIES|1
+DEU|nation_deu|#6E7A86|19|AGGRESSIVE|1600|3,3,2,1,0,2|🇩🇪|AXIS|1
+FRA|nation_fra|#4C5C9E|5|TURTLE|1100|2,1,2,0,0,1|🇫🇷|ALLIES|1
GBR|nation_gbr|#8C4C4C|0|BALANCED|1000|1,1,1,0,0,1|🇬🇧|ALLIES|1
-BEL|nation_bel|#9E8C4C|7|TURTLE|400|1,1,1,0,0,1|🇧🇪|ALLIES|1
-NLD|nation_nld|#C4813C|8|TURTLE|400|1,1,1,0,0,1|🇳🇱|ALLIES|1
-CHE|nation_che|#B45C5C|16|TURTLE|500|1,1,1,0,0,1|🇨🇭||1
-ESP|nation_esp|#B08A3C|9|TURTLE|500|1,1,1,0,0,1|🇪🇸||1
+BEL|nation_bel|#9E8C4C|8|TURTLE|400|1,1,1,0,0,1|🇧🇪|ALLIES|1
+NLD|nation_nld|#C4813C|9|TURTLE|400|1,1,1,0,0,1|🇳🇱|ALLIES|1
+CHE|nation_che|#B45C5C|18|TURTLE|500|1,1,1,0,0,1|🇨🇭||1
+ESP|nation_esp|#B08A3C|10|TURTLE|500|1,1,1,0,0,1|🇪🇸||1
IRL|nation_irl|#4C8C5C|3|TURTLE|260|1,1,1,0,0,1|🇮🇪||1
-PRT|nation_prt|#4C8C7A|12|TURTLE|300|1,1,1,0,0,1|🇵🇹||1
-ITA|nation_ita|#5C9E6E|13|TURTLE|700|1,1,1,0,0,1|🇮🇹||1
-POL|nation_pol|#B4535C|23|TURTLE|520|1,1,1,0,0,1|🇵🇱||1
-HUN|nation_hun|#9E7A4C|25|TURTLE|300|1,1,1,0,0,1|🇭🇺||1
-ROU|nation_rou|#8C7A3C|26|TURTLE|320|1,1,1,0,0,1|🇷🇴||1
-SRB|nation_srb|#8C5C4C|27|TURTLE|260|1,1,1,0,0,1|🇷🇸||1
-BGR|nation_bgr|#6E8C5C|28|TURTLE|240|1,1,1,0,0,1|🇧🇬||1
-GRC|nation_grc|#4C7AA8|29|TURTLE|300|1,1,1,0,0,1|🇬🇷||1
-SWE|nation_swe|#4C6E9E|30|TURTLE|420|1,1,1,0,0,1|🇸🇪||1
-NOR|nation_nor|#5C7EA8|32|TURTLE|380|1,1,1,0,0,1|🇳🇴||1
-DNK|nation_dnk|#A85C6E|33|TURTLE|320|1,1,1,0,0,1|🇩🇰||1
-FIN|nation_fin|#7A9EB4|35|TURTLE|320|1,1,1,0,0,1|🇫🇮||1
-RUS|nation_sun|#8C6E4C|41|TURTLE|1500|1,1,1,0,0,1|🇷🇺||1
-TUR|nation_tur|#A84C4C|44|TURTLE|740|1,1,1,0,0,1|🇹🇷||1
+PRT|nation_prt|#4C8C7A|14|TURTLE|300|1,1,1,0,0,1|🇵🇹||1
+ITA|nation_ita|#5C9E6E|15|TURTLE|700|1,1,1,0,0,1|🇮🇹||1
+POL|nation_pol|#B4535C|25|TURTLE|520|1,1,1,0,0,1|🇵🇱||1
+HUN|nation_hun|#9E7A4C|27|TURTLE|300|1,1,1,0,0,1|🇭🇺||1
+ROU|nation_rou|#8C7A3C|28|TURTLE|320|1,1,1,0,0,1|🇷🇴||1
+SRB|nation_srb|#8C5C4C|29|TURTLE|260|1,1,1,0,0,1|🇷🇸||1
+BGR|nation_bgr|#6E8C5C|30|TURTLE|240|1,1,1,0,0,1|🇧🇬||1
+GRC|nation_grc|#4C7AA8|31|TURTLE|300|1,1,1,0,0,1|🇬🇷||1
+SWE|nation_swe|#4C6E9E|32|TURTLE|420|1,1,1,0,0,1|🇸🇪||1
+NOR|nation_nor|#5C7EA8|34|TURTLE|380|1,1,1,0,0,1|🇳🇴||1
+DNK|nation_dnk|#A85C6E|35|TURTLE|320|1,1,1,0,0,1|🇩🇰||1
+FIN|nation_fin|#7A9EB4|37|TURTLE|320|1,1,1,0,0,1|🇫🇮||1
+RUS|nation_sun|#8C6E4C|43|TURTLE|1500|1,1,1,0,0,1|🇷🇺||1
+TUR|nation_tur|#A84C4C|46|TURTLE|740|1,1,1,0,0,1|🇹🇷||1
[relations]
DEU FRA WAR
@@ -45,28 +45,28 @@ DEU BEL WAR
DEU NLD WAR
[owners]
-DEU: 17-22
-FRA: 4-6,47-48
-GBR: 0-2
-BEL: 7
-NLD: 8
-CHE: 16
-ESP: 9-11
+DEU: 19-24
+FRA: 5-7,49-50
+GBR: 0-2,4,13
+BEL: 8
+NLD: 9
+CHE: 18
+ESP: 10-12
IRL: 3
-PRT: 12
-ITA: 13-15
-POL: 23-24
-HUN: 25
-ROU: 26
-SRB: 27
-BGR: 28
-GRC: 29
-SWE: 30-31
-NOR: 32
-DNK: 33-34
-FIN: 35
-RUS: 36-43
-TUR: 44-46
+PRT: 14
+ITA: 15-17
+POL: 25-26
+HUN: 27
+ROU: 28
+SRB: 29
+BGR: 30
+GRC: 31
+SWE: 32-33
+NOR: 34
+DNK: 35-36
+FIN: 37
+RUS: 38-45
+TUR: 46-48
[units]
DEU|25,14|HEADQUARTERS|1|-
@@ -146,4 +146,4 @@ TUR|38,35|INFANTRY|1|-
FRA
[objectives]
-HOLD_PROVINCES|4|20
+HOLD_PROVINCES|5|20
diff --git a/app/src/main/assets/scenarios/campaign_ww2_03_desert.scn b/app/src/main/assets/scenarios/campaign_ww2_03_desert.scn
index 52b2b68..76d8c62 100644
--- a/app/src/main/assets/scenarios/campaign_ww2_03_desert.scn
+++ b/app/src/main/assets/scenarios/campaign_ww2_03_desert.scn
@@ -15,47 +15,47 @@ startYear 1942
starTurns 20,28
[nations]
-GBR|nation_gbr|#8C4C4C|8|BALANCED|1300|1,1,1,0,0,1|🇬🇧|ALLIES|1
-ITA|nation_ita|#5C9E6E|11|BALANCED|800|1,1,1,0,0,1|🇮🇹|AXIS|1
-DEU|nation_deu|#6E7A86|12|AGGRESSIVE|1000|1,1,1,0,0,1|🇩🇪|AXIS|1
-TUR|nation_tur|#A84C4C|3|TURTLE|500|1,1,1,0,0,1|🇹🇷||1
+GBR|nation_gbr|#8C4C4C|9|BALANCED|1300|1,1,1,0,0,1|🇬🇧|ALLIES|1
+ITA|nation_ita|#5C9E6E|12|BALANCED|800|1,1,1,0,0,1|🇮🇹|AXIS|1
+DEU|nation_deu|#6E7A86|13|AGGRESSIVE|1000|1,1,1,0,0,1|🇩🇪|AXIS|1
+TUR|nation_tur|#A84C4C|4|TURTLE|500|1,1,1,0,0,1|🇹🇷||1
ESP|nation_esp|#B08A3C|0|TURTLE|500|1,1,1,0,0,1|🇪🇸||1
-PRT|nation_prt|#4C8C7A|1|TURTLE|300|1,1,1,0,0,1|🇵🇹||1
-GRC|nation_grc|#4C7AA8|2|TURTLE|300|1,1,1,0,0,1|🇬🇷||1
-FRA|nation_fra|#4C5C9E|5|TURTLE|950|1,1,1,0,0,1|🇫🇷||1
-SAU|nation_sau|#4C8C5C|7|TURTLE|820|1,1,1,0,0,1|🇸🇦||1
+PRT|nation_prt|#4C8C7A|2|TURTLE|300|1,1,1,0,0,1|🇵🇹||1
+GRC|nation_grc|#4C7AA8|3|TURTLE|300|1,1,1,0,0,1|🇬🇷||1
+FRA|nation_fra|#4C5C9E|6|TURTLE|950|1,1,1,0,0,1|🇫🇷||1
+SAU|nation_sau|#4C8C5C|8|TURTLE|820|1,1,1,0,0,1|🇸🇦||1
[relations]
ITA GBR WAR
DEU GBR WAR
[owners]
-GBR: 6,8-10,18-19,21
-ITA: 11,22
-DEU: 12
-TUR: 3-4
-ESP: 0,15
-PRT: 1
-GRC: 2
-FRA: 5,13-14,16-17,20
-SAU: 7
+GBR: 1,7,9-11,19-20,22
+ITA: 12,23
+DEU: 13
+TUR: 4-5
+ESP: 0,16
+PRT: 2
+GRC: 3
+FRA: 6,14-15,17-18,21
+SAU: 8
[units]
GBR|43,10|INFANTRY|2|-
GBR|41,9|INFANTRY|2|-
GBR|45,16|INFANTRY|2|-
GBR|44,25|INFANTRY|2|-
+GBR|8,4|ARMOUR|2|-
GBR|47,8|ARMOUR|2|-
GBR|16,35|ARMOUR|2|-
-GBR|21,29|ARMOUR|2|-
+GBR|21,29|SUPPLY_TRUCK|1|-
GBR|44,10|SUPPLY_TRUCK|1|-
GBR|43,9|SUPPLY_TRUCK|1|-
-GBR|42,9|SUPPLY_TRUCK|1|-
+GBR|42,9|ARTILLERY|2|-
GBR|42,10|ARTILLERY|2|-
-GBR|42,11|ARTILLERY|2|-
+GBR|42,11|RECON|2|-
GBR|43,11|RECON|2|-
-GBR|40,9|RECON|2|-
-GBR|46,7|DESTROYER|2|-
+GBR|9,4|DESTROYER|2|-
ITA|25,7|INFANTRY|2|-
ITA|50,32|INFANTRY|2|-
ITA|26,7|INFANTRY|2|-
@@ -89,4 +89,4 @@ SAU|50,19|INFANTRY|1|-
GBR
[objectives]
-CAPTURE_PROVINCES|11-12|0
+CAPTURE_PROVINCES|12-13|0
diff --git a/app/src/main/assets/scenarios/campaign_ww2_03_desert_axis.scn b/app/src/main/assets/scenarios/campaign_ww2_03_desert_axis.scn
index b9026c6..819f76e 100644
--- a/app/src/main/assets/scenarios/campaign_ww2_03_desert_axis.scn
+++ b/app/src/main/assets/scenarios/campaign_ww2_03_desert_axis.scn
@@ -15,47 +15,47 @@ startYear 1942
starTurns 24,32
[nations]
-GBR|nation_gbr|#8C4C4C|8|BALANCED|1300|1,1,1,0,0,1|🇬🇧|ALLIES|1
-ITA|nation_ita|#5C9E6E|11|BALANCED|800|1,1,1,0,0,1|🇮🇹|AXIS|1
-DEU|nation_deu|#6E7A86|12|AGGRESSIVE|1000|1,1,1,0,0,1|🇩🇪|AXIS|1
-TUR|nation_tur|#A84C4C|3|TURTLE|500|1,1,1,0,0,1|🇹🇷||1
+GBR|nation_gbr|#8C4C4C|9|BALANCED|1300|1,1,1,0,0,1|🇬🇧|ALLIES|1
+ITA|nation_ita|#5C9E6E|12|BALANCED|800|1,1,1,0,0,1|🇮🇹|AXIS|1
+DEU|nation_deu|#6E7A86|13|AGGRESSIVE|1000|1,1,1,0,0,1|🇩🇪|AXIS|1
+TUR|nation_tur|#A84C4C|4|TURTLE|500|1,1,1,0,0,1|🇹🇷||1
ESP|nation_esp|#B08A3C|0|TURTLE|500|1,1,1,0,0,1|🇪🇸||1
-PRT|nation_prt|#4C8C7A|1|TURTLE|300|1,1,1,0,0,1|🇵🇹||1
-GRC|nation_grc|#4C7AA8|2|TURTLE|300|1,1,1,0,0,1|🇬🇷||1
-FRA|nation_fra|#4C5C9E|5|TURTLE|950|1,1,1,0,0,1|🇫🇷||1
-SAU|nation_sau|#4C8C5C|7|TURTLE|820|1,1,1,0,0,1|🇸🇦||1
+PRT|nation_prt|#4C8C7A|2|TURTLE|300|1,1,1,0,0,1|🇵🇹||1
+GRC|nation_grc|#4C7AA8|3|TURTLE|300|1,1,1,0,0,1|🇬🇷||1
+FRA|nation_fra|#4C5C9E|6|TURTLE|950|1,1,1,0,0,1|🇫🇷||1
+SAU|nation_sau|#4C8C5C|8|TURTLE|820|1,1,1,0,0,1|🇸🇦||1
[relations]
ITA GBR WAR
DEU GBR WAR
[owners]
-GBR: 6,8-10,18-19,21
-ITA: 11,22
-DEU: 12
-TUR: 3-4
-ESP: 0,15
-PRT: 1
-GRC: 2
-FRA: 5,13-14,16-17,20
-SAU: 7
+GBR: 1,7,9-11,19-20,22
+ITA: 12,23
+DEU: 13
+TUR: 4-5
+ESP: 0,16
+PRT: 2
+GRC: 3
+FRA: 6,14-15,17-18,21
+SAU: 8
[units]
GBR|43,10|INFANTRY|2|-
GBR|41,9|INFANTRY|2|-
GBR|45,16|INFANTRY|2|-
GBR|44,25|INFANTRY|2|-
+GBR|8,4|ARMOUR|2|-
GBR|47,8|ARMOUR|2|-
GBR|16,35|ARMOUR|2|-
-GBR|21,29|ARMOUR|2|-
+GBR|21,29|SUPPLY_TRUCK|1|-
GBR|44,10|SUPPLY_TRUCK|1|-
GBR|43,9|SUPPLY_TRUCK|1|-
-GBR|42,9|SUPPLY_TRUCK|1|-
+GBR|42,9|ARTILLERY|2|-
GBR|42,10|ARTILLERY|2|-
-GBR|42,11|ARTILLERY|2|-
+GBR|42,11|RECON|2|-
GBR|43,11|RECON|2|-
-GBR|40,9|RECON|2|-
-GBR|46,7|DESTROYER|2|-
+GBR|9,4|DESTROYER|2|-
ITA|25,7|INFANTRY|2|-
ITA|50,32|INFANTRY|2|-
ITA|26,7|INFANTRY|2|-
@@ -89,4 +89,4 @@ SAU|50,19|INFANTRY|1|-
DEU
[objectives]
-CAPTURE_PROVINCES|8-9|0
+CAPTURE_PROVINCES|9-10|0
diff --git a/app/src/main/assets/scenarios/campaign_ww2_04_south_seas.scn b/app/src/main/assets/scenarios/campaign_ww2_04_south_seas.scn
index a4c52b5..020c214 100644
--- a/app/src/main/assets/scenarios/campaign_ww2_04_south_seas.scn
+++ b/app/src/main/assets/scenarios/campaign_ww2_04_south_seas.scn
@@ -20,7 +20,7 @@ USA|nation_usa|#4C7BA8|20|BALANCED|1100|1,1,1,0,0,1|🇺🇸|ALLIES|1
GBR|nation_gbr|#8C4C4C|14|TURTLE|1100|1,1,1,0,0,1|🇬🇧|ALLIES|1
NLD|nation_nld|#C4813C|15|TURTLE|600|1,1,1,0,0,1|🇳🇱|ALLIES|1
THA|nation_tha|#5C86A8|7|TURTLE|500|1,1,1,0,0,1|🇹🇭||1
-ROC|nation_roc|#B4454C|0|TURTLE|1100|1,1,1,0,0,1|🇹🇼||1
+ROC|nation_chn|#B4454C|0|TURTLE|1100|1,1,1,0,0,1|🇹🇼||1
FRA|nation_fra|#4C5C9E|10|TURTLE|950|1,1,1,0,0,1|🇫🇷||1
AUS|nation_aus|#C4A05C|22|TURTLE|820|1,1,1,0,0,1|🇦🇺||1
@@ -56,9 +56,9 @@ JPN|24,3|INFANTRY|2|-
JPN|24,2|INFANTRY|2|-
USA|24,11|INFANTRY|2|-
USA|27,16|INFANTRY|2|-
-USA|25,11|INFANTRY|2|-
-USA|25,10|ANTI_AIR|2|-
+USA|25,10|INFANTRY|2|-
USA|24,10|ANTI_AIR|2|-
+USA|25,12|ANTI_AIR|2|-
USA|24,7|SUBMARINE|2|-
USA|23,7|SUBMARINE|2|-
USA|23,8|DESTROYER|2|-
@@ -66,9 +66,9 @@ GBR|8,25|INFANTRY|2|-
GBR|7,24|INFANTRY|2|-
GBR|1,9|INFANTRY|2|-
GBR|1,4|INFANTRY|2|-
-GBR|21,1|BATTLESHIP|2|-
-GBR|23,0|DESTROYER|2|-
-GBR|22,1|DESTROYER|2|-
+GBR|2,2|BATTLESHIP|2|-
+GBR|1,2|DESTROYER|2|-
+GBR|0,3|DESTROYER|2|-
GBR|18,3|ANTI_AIR|1|-
GBR|20,20|ANTI_AIR|1|-
NLD|11,33|INFANTRY|1|-
diff --git a/app/src/main/assets/scenarios/campaign_ww2_04_south_seas_allies.scn b/app/src/main/assets/scenarios/campaign_ww2_04_south_seas_allies.scn
index 9831758..2dff9e1 100644
--- a/app/src/main/assets/scenarios/campaign_ww2_04_south_seas_allies.scn
+++ b/app/src/main/assets/scenarios/campaign_ww2_04_south_seas_allies.scn
@@ -20,7 +20,7 @@ USA|nation_usa|#4C7BA8|20|BALANCED|1100|1,1,1,0,0,1|🇺🇸|ALLIES|1
GBR|nation_gbr|#8C4C4C|14|TURTLE|1100|1,1,1,0,0,1|🇬🇧|ALLIES|1
NLD|nation_nld|#C4813C|15|TURTLE|600|1,1,1,0,0,1|🇳🇱|ALLIES|1
THA|nation_tha|#5C86A8|7|TURTLE|500|1,1,1,0,0,1|🇹🇭||1
-ROC|nation_roc|#B4454C|0|TURTLE|1100|1,1,1,0,0,1|🇹🇼||1
+ROC|nation_chn|#B4454C|0|TURTLE|1100|1,1,1,0,0,1|🇹🇼||1
FRA|nation_fra|#4C5C9E|10|TURTLE|950|1,1,1,0,0,1|🇫🇷||1
AUS|nation_aus|#C4A05C|22|TURTLE|820|1,1,1,0,0,1|🇦🇺||1
@@ -56,9 +56,9 @@ JPN|24,3|INFANTRY|2|-
JPN|24,2|INFANTRY|2|-
USA|24,11|INFANTRY|2|-
USA|27,16|INFANTRY|2|-
-USA|25,11|INFANTRY|2|-
-USA|25,10|ANTI_AIR|2|-
+USA|25,10|INFANTRY|2|-
USA|24,10|ANTI_AIR|2|-
+USA|25,12|ANTI_AIR|2|-
USA|24,7|SUBMARINE|2|-
USA|23,7|SUBMARINE|2|-
USA|23,8|DESTROYER|2|-
@@ -66,9 +66,9 @@ GBR|8,25|INFANTRY|2|-
GBR|7,24|INFANTRY|2|-
GBR|1,9|INFANTRY|2|-
GBR|1,4|INFANTRY|2|-
-GBR|21,1|BATTLESHIP|2|-
-GBR|23,0|DESTROYER|2|-
-GBR|22,1|DESTROYER|2|-
+GBR|2,2|BATTLESHIP|2|-
+GBR|1,2|DESTROYER|2|-
+GBR|0,3|DESTROYER|2|-
GBR|18,3|ANTI_AIR|1|-
GBR|20,20|ANTI_AIR|1|-
NLD|11,33|INFANTRY|1|-
diff --git a/app/src/main/assets/scenarios/campaign_ww2_06_philippines.scn b/app/src/main/assets/scenarios/campaign_ww2_06_philippines.scn
index be3fa48..db8f1a1 100644
--- a/app/src/main/assets/scenarios/campaign_ww2_06_philippines.scn
+++ b/app/src/main/assets/scenarios/campaign_ww2_06_philippines.scn
@@ -18,7 +18,7 @@ starTurns 24,32
USA|nation_usa|#4C7BA8|22|BALANCED|2000|3,3,3,3,0,3|🇺🇸|ALLIES|1
JPN|nation_jpn|#C45C5C|20|BALANCED|1400|2,2,2,3,0,2|🇯🇵|AXIS|1
THA|nation_tha|#5C86A8|7|TURTLE|400|1,1,1,0,0,1|🇹🇭|AXIS|1
-ROC|nation_roc|#B4454C|1|TURTLE|1100|1,1,1,0,0,1|🇹🇼||1
+ROC|nation_chn|#B4454C|1|TURTLE|1100|1,1,1,0,0,1|🇹🇼||1
[relations]
JPN USA WAR
diff --git a/app/src/main/assets/scenarios/campaign_ww2_06_philippines_axis.scn b/app/src/main/assets/scenarios/campaign_ww2_06_philippines_axis.scn
index 4421a9f..1982ca4 100644
--- a/app/src/main/assets/scenarios/campaign_ww2_06_philippines_axis.scn
+++ b/app/src/main/assets/scenarios/campaign_ww2_06_philippines_axis.scn
@@ -18,7 +18,7 @@ starTurns 26,29
USA|nation_usa|#4C7BA8|22|AGGRESSIVE|2000|3,3,3,3,0,3|🇺🇸|ALLIES|1
JPN|nation_jpn|#C45C5C|20|BALANCED|1400|2,2,2,3,0,2|🇯🇵|AXIS|1
THA|nation_tha|#5C86A8|7|TURTLE|400|1,1,1,0,0,1|🇹🇭|AXIS|1
-ROC|nation_roc|#B4454C|1|TURTLE|1100|1,1,1,0,0,1|🇹🇼||1
+ROC|nation_chn|#B4454C|1|TURTLE|1100|1,1,1,0,0,1|🇹🇼||1
[relations]
JPN USA WAR
diff --git a/app/src/main/assets/scenarios/conquest_1939.scn b/app/src/main/assets/scenarios/conquest_1939.scn
index 7d56358..eed337a 100644
--- a/app/src/main/assets/scenarios/conquest_1939.scn
+++ b/app/src/main/assets/scenarios/conquest_1939.scn
@@ -13,50 +13,53 @@ startYear 1939
startMonth 9
[nations]
-RUS|nation_sun|#8C6E4C|46|AGGRESSIVE|3900|2,2,2,2,2,1|🇷🇺|ALLIES|8
-GBR|nation_gbr|#8C4C4C|0|BALANCED|3465|2,2,2,2,2,1|🇬🇧|ALLIES|1
-USA|nation_usa|#4C7BA8|178|BALANCED|3440|2,2,2,2,2,1|🇺🇸|ALLIES|10
-JPN|nation_jpn|#C45C5C|155|BALANCED|1980|2,2,2,2,2,1|🇯🇵|AXIS|1
-ROC|nation_roc|#B4454C|134|BALANCED|1760|2,2,2,2,2,1|🇹🇼|ALLIES|1
-FRA|nation_fra|#4C5C9E|4|BALANCED|1757|2,2,2,2,2,1|🇫🇷|ALLIES|1
-DEU|nation_deu|#6E7A86|17|AGGRESSIVE|1495|2,2,2,2,2,1|🇩🇪|AXIS|1
-BRA|nation_bra|#4F9A50|229|TURTLE|1260|1,1,1,1,1,1|🇧🇷||1
-AUS|nation_aus|#C4A05C|237|BALANCED|1189|1,1,1,1,1,1|🇦🇺|ALLIES|1
-CAN|nation_can|#6E93B5|196|TURTLE|979|1,1,1,1,1,1|🇨🇦|ALLIES|1
-ITA|nation_ita|#5C9E6E|13|OPPORTUNIST|910|1,1,1,1,1,1|🇮🇹|AXIS|1
-SAU|nation_sau|#4C8C5C|83|TURTLE|902|1,1,1,1,1,1|🇸🇦||1
-TUR|nation_tur|#A84C4C|73|TURTLE|850|1,1,0,0,0,1|🇹🇷||1
-IRN|nation_irn|#4C8C6E|76|TURTLE|804|1,1,0,0,0,1|🇮🇷||1
-MEX|nation_mex|#3F8F6B|205|TURTLE|720|1,1,0,0,0,1|🇲🇽||1
-ARG|nation_arg|#6FA8C4|224|TURTLE|690|1,1,0,0,0,1|🇦🇷||1
-ESP|nation_esp|#B08A3C|9|TURTLE|644|1,1,0,0,0,1|🇪🇸||1
-POL|nation_pol|#B4535C|23|BALANCED|572|1,1,0,0,0,1|🇵🇱|ALLIES|1
-THA|nation_tha|#5C86A8|162|BALANCED|528|1,1,0,0,0,1|🇹🇭||1
-SWE|nation_swe|#4C6E9E|30|TURTLE|504|1,1,0,0,0,1|🇸🇪||1
-NLD|nation_nld|#C4813C|170|TURTLE|494|0,0,0,0,0,0|🇳🇱||1
-CHL|nation_chl|#A8544C|221|TURTLE|482|0,0,0,0,0,0|🇨🇱||1
-COL|nation_col|#C29A3C|213|TURTLE|462|0,0,0,0,0,0|🇨🇴||1
-NOR|nation_nor|#5C7EA8|34|TURTLE|418|0,0,0,0,0,0|🇳🇴||1
-NZL|nation_nzl|#5C9E93|245|TURTLE|418|0,0,0,0,0,0|🇳🇿|ALLIES|1
-PER|nation_per|#B06A4C|218|TURTLE|418|0,0,0,0,0,0|🇵🇪||1
-VEN|nation_ven|#B4703C|215|TURTLE|399|0,0,0,0,0,0|🇻🇪||1
-DNK|nation_dnk|#A85C6E|35|TURTLE|384|0,0,0,0,0,0|🇩🇰||1
-CHE|nation_che|#B45C5C|16|TURTLE|378|0,0,0,0,0,0|🇨🇭||1
-BEL|nation_bel|#9E8C4C|110|TURTLE|368|0,0,0,0,0,0|🇧🇪||1
-FIN|nation_fin|#7A9EB4|37|TURTLE|352|0,0,0,0,0,0|🇫🇮||1
-PRT|nation_prt|#4C8C7A|12|TURTLE|345|0,0,0,0,0,0|🇵🇹||1
-ROU|nation_rou|#8C7A3C|26|TURTLE|336|0,0,0,0,0,0|🇷🇴||1
-GRC|nation_grc|#4C7AA8|29|TURTLE|315|0,0,0,0,0,0|🇬🇷||1
-HUN|nation_hun|#9E7A4C|25|OPPORTUNIST|315|0,0,0,0,0,0|🇭🇺||1
+RUS|nation_sun|#8C6E4C|50|AGGRESSIVE|3900|2,2,2,2,2,1|🇷🇺|ALLIES|8
+GBR|nation_gbr|#8C4C4C|0|BALANCED|3575|2,2,2,2,2,1|🇬🇧|ALLIES|1
+USA|nation_usa|#4C7BA8|182|BALANCED|3200|2,2,2,2,2,1|🇺🇸|ALLIES|10
+JPN|nation_jpn|#C45C5C|159|BALANCED|1980|2,2,2,2,2,1|🇯🇵|AXIS|1
+ROC|nation_chn|#B4454C|138|BALANCED|1760|2,2,2,2,2,1|🇹🇼|ALLIES|1
+FRA|nation_fra|#4C5C9E|5|BALANCED|1757|2,2,2,2,2,1|🇫🇷|ALLIES|1
+DEU|nation_deu|#6E7A86|19|AGGRESSIVE|1495|2,2,2,2,2,1|🇩🇪|AXIS|1
+BRA|nation_bra|#4F9A50|236|TURTLE|1260|1,1,1,1,1,1|🇧🇷||1
+AUS|nation_aus|#C4A05C|244|BALANCED|1189|1,1,1,1,1,1|🇦🇺|ALLIES|1
+CAN|nation_can|#6E93B5|200|TURTLE|979|1,1,1,1,1,1|🇨🇦|ALLIES|1
+ITA|nation_ita|#5C9E6E|15|OPPORTUNIST|910|1,1,1,1,1,1|🇮🇹|AXIS|1
+SAU|nation_sau|#4C8C5C|87|TURTLE|902|1,1,1,1,1,1|🇸🇦||1
+TUR|nation_tur|#A84C4C|77|TURTLE|850|1,1,0,0,0,1|🇹🇷||1
+IRN|nation_irn|#4C8C6E|80|TURTLE|804|1,1,0,0,0,1|🇮🇷||1
+ARG|nation_arg|#6FA8C4|230|TURTLE|720|1,1,0,0,0,1|🇦🇷||1
+MEX|nation_mex|#3F8F6B|209|TURTLE|720|1,1,0,0,0,1|🇲🇽||1
+ESP|nation_esp|#B08A3C|10|TURTLE|644|1,1,0,0,0,1|🇪🇸||1
+POL|nation_pol|#B4535C|25|BALANCED|572|1,1,0,0,0,1|🇵🇱|ALLIES|1
+THA|nation_tha|#5C86A8|166|BALANCED|528|1,1,0,0,0,1|🇹🇭||1
+CHL|nation_chl|#A8544C|225|TURTLE|525|1,1,0,0,0,1|🇨🇱||1
+SWE|nation_swe|#4C6E9E|32|TURTLE|504|1,1,0,0,0,1|🇸🇪||1
+NLD|nation_nld|#C4813C|174|TURTLE|494|0,0,0,0,0,0|🇳🇱||1
+COL|nation_col|#C29A3C|217|TURTLE|462|0,0,0,0,0,0|🇨🇴||1
+NOR|nation_nor|#5C7EA8|36|TURTLE|456|0,0,0,0,0,0|🇳🇴||1
+NZL|nation_nzl|#5C9E93|252|TURTLE|418|0,0,0,0,0,0|🇳🇿|ALLIES|1
+PER|nation_per|#B06A4C|222|TURTLE|418|0,0,0,0,0,0|🇵🇪||1
+VEN|nation_ven|#B4703C|219|TURTLE|399|0,0,0,0,0,0|🇻🇪||1
+DNK|nation_dnk|#A85C6E|39|TURTLE|384|0,0,0,0,0,0|🇩🇰||1
+CHE|nation_che|#B45C5C|18|TURTLE|378|0,0,0,0,0,0|🇨🇭||1
+BEL|nation_bel|#9E8C4C|114|TURTLE|368|0,0,0,0,0,0|🇧🇪||1
+FIN|nation_fin|#7A9EB4|41|TURTLE|352|0,0,0,0,0,0|🇫🇮||1
+PRT|nation_prt|#4C8C7A|14|TURTLE|345|0,0,0,0,0,0|🇵🇹||1
+ROU|nation_rou|#8C7A3C|28|TURTLE|336|0,0,0,0,0,0|🇷🇴||1
+GRC|nation_grc|#4C7AA8|31|TURTLE|315|0,0,0,0,0,0|🇬🇷||1
+HUN|nation_hun|#9E7A4C|27|OPPORTUNIST|315|0,0,0,0,0,0|🇭🇺||1
+CUB|nation_cub|#A85C4C|215|TURTLE|273|0,0,0,0,0,0|🇨🇺||1
IRL|nation_irl|#4C8C5C|3|TURTLE|273|0,0,0,0,0,0|🇮🇪||1
-SRB|nation_srb|#8C5C4C|27|OPPORTUNIST|273|0,0,0,0,0,0|🇷🇸||1
-ECU|nation_ecu|#C7A24E|216|TURTLE|264|0,0,0,0,0,0|🇪🇨||1
-BGR|nation_bgr|#6E8C5C|28|TURTLE|252|0,0,0,0,0,0|🇧🇬||1
-BOL|nation_bol|#8C9A4C|220|TURTLE|252|0,0,0,0,0,0|🇧🇴||1
-AFG|nation_afg|#8C7A5C|88|TURTLE|231|0,0,0,0,0,0|🇦🇫||1
-GTM|nation_gtm|#57A07E|209|TURTLE|231|0,0,0,0,0,0|🇬🇹||1
-URY|nation_ury|#6E9BB0|227|TURTLE|231|0,0,0,0,0,0|🇺🇾||1
-PRY|nation_pry|#7F8F5C|228|TURTLE|210|0,0,0,0,0,0|🇵🇾||1
+SRB|nation_srb|#8C5C4C|29|OPPORTUNIST|273|0,0,0,0,0,0|🇷🇸||1
+ECU|nation_ecu|#C7A24E|220|TURTLE|264|0,0,0,0,0,0|🇪🇨||1
+BGR|nation_bgr|#6E8C5C|30|TURTLE|252|0,0,0,0,0,0|🇧🇬||1
+BOL|nation_bol|#8C9A4C|224|TURTLE|252|0,0,0,0,0,0|🇧🇴||1
+AFG|nation_afg|#8C7A5C|92|TURTLE|231|0,0,0,0,0,0|🇦🇫||1
+GTM|nation_gtm|#57A07E|213|TURTLE|231|0,0,0,0,0,0|🇬🇹||1
+PAN|nation_pan|#4E9E86|214|TURTLE|231|0,0,0,0,0,0|🇵🇦||1
+URY|nation_ury|#6E9BB0|234|TURTLE|231|0,0,0,0,0,0|🇺🇾||1
+DOM|nation_dom|#9E6B58|216|TURTLE|210|0,0,0,0,0,0|🇩🇴||1
+PRY|nation_pry|#7F8F5C|235|TURTLE|210|0,0,0,0,0,0|🇵🇾||1
[relations]
DEU GBR WAR
@@ -82,50 +85,53 @@ JPN AUS WAR
JPN NZL WAR
[owners]
-RUS: 39,42-72
-GBR: 0-2,79-80,82,85-87,89-91,101-103,105,108-109,113-118,121-133,148,160-161,167-169
-USA: 175-176,178-195,210-212
-JPN: 141-142,149-159
-ROC: 134-140,143-147
-FRA: 4-6,81,93-100,104,120,164-166
-DEU: 17-22
-BRA: 229-236
-AUS: 177,237-244
-CAN: 196-203
-ITA: 13-15,92,106-107
-SAU: 83-84
-TUR: 73-75
-IRN: 76-78
-MEX: 205-208
-ARG: 224-226
-ESP: 9-11
-POL: 23-24
-THA: 162-163
-SWE: 30-33
-NLD: 8,170-174
-CHL: 221-223
-COL: 213-214
-NOR: 34,41
-NZL: 245-246
-PER: 218-219
-VEN: 215
-DNK: 35-36,40,204
-CHE: 16
-BEL: 7,110-111
-FIN: 37-38
-PRT: 12,112,119
-ROU: 26
-GRC: 29
-HUN: 25
+RUS: 43,46-76
+GBR: 0-2,4,13,83-84,86,89-91,93-95,105-107,109,112-113,117-122,125-137,152,164-165,171-173
+USA: 179-180,182-199
+JPN: 145-146,153-163
+ROC: 138-144,147-151
+FRA: 5-7,85,97-104,108,124,168-170
+DEU: 19-24
+BRA: 236-243
+AUS: 181,244-251
+CAN: 200-207
+ITA: 15-17,96,110-111
+SAU: 87-88
+TUR: 77-79
+IRN: 80-82
+ARG: 230-233
+MEX: 209-212
+ESP: 10-12
+POL: 25-26
+THA: 166-167
+CHL: 225-229
+SWE: 32-35
+NLD: 9,174-178
+COL: 217-218
+NOR: 36-38,45
+NZL: 252-253
+PER: 222-223
+VEN: 219
+DNK: 39-40,44,208
+CHE: 18
+BEL: 8,114-115
+FIN: 41-42
+PRT: 14,116,123
+ROU: 28
+GRC: 31
+HUN: 27
+CUB: 215
IRL: 3
-SRB: 27
-ECU: 216-217
-BGR: 28
-BOL: 220
-AFG: 88
-GTM: 209
-URY: 227
-PRY: 228
+SRB: 29
+ECU: 220-221
+BGR: 30
+BOL: 224
+AFG: 92
+GTM: 213
+PAN: 214
+URY: 234
+DOM: 216
+PRY: 235
[units]
GBR|47,17|INFANTRY|1|-
@@ -230,6 +236,9 @@ MEX|16,43|INFANTRY|1|-
MEX|17,43|ARTILLERY|1|-
MEX|17,42|ARMOUR|1|-
GTM|19,45|INFANTRY|1|-
+PAN|23,48|INFANTRY|1|-
+CUB|22,41|INFANTRY|1|-
+DOM|26,43|INFANTRY|1|-
COL|25,51|INFANTRY|1|-
COL|26,51|ARTILLERY|1|-
VEN|28,48|INFANTRY|1|-
@@ -241,6 +250,7 @@ CHL|27,68|INFANTRY|1|-
CHL|28,68|ARTILLERY|1|-
ARG|30,69|INFANTRY|1|-
ARG|30,68|ARTILLERY|1|-
+ARG|29,69|ARMOUR|1|-
URY|31,68|INFANTRY|1|-
PRY|30,65|INFANTRY|1|-
BRA|33,63|INFANTRY|1|-
diff --git a/app/src/main/assets/scenarios/conquest_1943.scn b/app/src/main/assets/scenarios/conquest_1943.scn
index a037ec1..9835a90 100644
--- a/app/src/main/assets/scenarios/conquest_1943.scn
+++ b/app/src/main/assets/scenarios/conquest_1943.scn
@@ -13,45 +13,48 @@ startYear 1943
startMonth 3
[nations]
-RUS|nation_sun|#8C6E4C|46|AGGRESSIVE|3600|2,2,2,2,2,1|🇷🇺|ALLIES|1
-GBR|nation_gbr|#8C4C4C|0|BALANCED|3355|2,2,2,2,2,1|🇬🇧|ALLIES|1
-USA|nation_usa|#4C7BA8|178|BALANCED|3279|2,2,2,2,2,1|🇺🇸|ALLIES|1
-JPN|nation_jpn|#C45C5C|134|BALANCED|3240|2,2,2,2,2,1|🇯🇵|AXIS|1
-DEU|nation_deu|#6E7A86|4|AGGRESSIVE|2530|2,2,2,2,2,1|🇩🇪|AXIS|1
-ROC|nation_roc|#B4454C|138|BALANCED|1485|2,2,2,2,2,1|🇹🇼|ALLIES|1
-FRA|nation_fra|#4C5C9E|81|BALANCED|1425|2,2,2,2,2,1|🇫🇷|ALLIES|1
-BRA|nation_bra|#4F9A50|229|TURTLE|1260|1,1,1,1,1,1|🇧🇷||1
-AUS|nation_aus|#C4A05C|237|BALANCED|1189|1,1,1,1,1,1|🇦🇺|ALLIES|1
-CAN|nation_can|#6E93B5|196|TURTLE|979|1,1,1,1,1,1|🇨🇦|ALLIES|1
-SAU|nation_sau|#4C8C5C|83|TURTLE|902|1,1,1,1,1,1|🇸🇦||1
-TUR|nation_tur|#A84C4C|73|TURTLE|850|1,1,0,0,0,1|🇹🇷||1
-ITA|nation_ita|#5C9E6E|13|OPPORTUNIST|804|1,1,0,0,0,1|🇮🇹|AXIS|1
-MEX|nation_mex|#3F8F6B|205|TURTLE|720|1,1,0,0,0,1|🇲🇽||1
-ARG|nation_arg|#6FA8C4|224|TURTLE|690|1,1,0,0,0,1|🇦🇷||1
-ESP|nation_esp|#B08A3C|9|TURTLE|644|1,1,0,0,0,1|🇪🇸||1
-THA|nation_tha|#5C86A8|162|BALANCED|528|1,1,0,0,0,1|🇹🇭|AXIS|1
-SWE|nation_swe|#4C6E9E|30|TURTLE|504|1,1,0,0,0,1|🇸🇪||1
-CHL|nation_chl|#A8544C|221|TURTLE|482|0,0,0,0,0,0|🇨🇱||1
-COL|nation_col|#C29A3C|213|TURTLE|462|0,0,0,0,0,0|🇨🇴||1
-NZL|nation_nzl|#5C9E93|245|TURTLE|418|0,0,0,0,0,0|🇳🇿|ALLIES|1
-PER|nation_per|#B06A4C|218|TURTLE|418|0,0,0,0,0,0|🇵🇪||1
-VEN|nation_ven|#B4703C|215|TURTLE|399|0,0,0,0,0,0|🇻🇪||1
-CHE|nation_che|#B45C5C|16|TURTLE|378|0,0,0,0,0,0|🇨🇭||1
-ETH|nation_eth|#6E9E4C|106|BALANCED|357|0,0,0,0,0,0|🇪🇹|ALLIES|1
-BEL|nation_bel|#9E8C4C|110|TURTLE|352|0,0,0,0,0,0|🇧🇪||1
-DNK|nation_dnk|#A85C6E|40|TURTLE|352|0,0,0,0,0,0|🇩🇰||1
-FIN|nation_fin|#7A9EB4|37|TURTLE|352|0,0,0,0,0,0|🇫🇮|AXIS|1
-ROU|nation_rou|#8C7A3C|26|TURTLE|352|0,0,0,0,0,0|🇷🇴|AXIS|1
-PRT|nation_prt|#4C8C7A|12|TURTLE|345|0,0,0,0,0,0|🇵🇹||1
-HUN|nation_hun|#9E7A4C|25|OPPORTUNIST|315|0,0,0,0,0,0|🇭🇺|AXIS|1
+RUS|nation_sun|#8C6E4C|50|AGGRESSIVE|3600|2,2,2,2,2,1|🇷🇺|ALLIES|1
+GBR|nation_gbr|#8C4C4C|0|BALANCED|3465|2,2,2,2,2,1|🇬🇧|ALLIES|1
+JPN|nation_jpn|#C45C5C|138|BALANCED|3240|2,2,2,2,2,1|🇯🇵|AXIS|1
+USA|nation_usa|#4C7BA8|182|BALANCED|3040|2,2,2,2,2,1|🇺🇸|ALLIES|1
+DEU|nation_deu|#6E7A86|5|AGGRESSIVE|2645|2,2,2,2,2,1|🇩🇪|AXIS|1
+ROC|nation_chn|#B4454C|142|BALANCED|1485|2,2,2,2,2,1|🇹🇼|ALLIES|1
+FRA|nation_fra|#4C5C9E|85|BALANCED|1425|2,2,2,2,2,1|🇫🇷|ALLIES|1
+BRA|nation_bra|#4F9A50|236|TURTLE|1260|1,1,1,1,1,1|🇧🇷||1
+AUS|nation_aus|#C4A05C|244|BALANCED|1189|1,1,1,1,1,1|🇦🇺|ALLIES|1
+CAN|nation_can|#6E93B5|200|TURTLE|979|1,1,1,1,1,1|🇨🇦|ALLIES|1
+SAU|nation_sau|#4C8C5C|87|TURTLE|902|1,1,1,1,1,1|🇸🇦||1
+TUR|nation_tur|#A84C4C|77|TURTLE|850|1,1,0,0,0,1|🇹🇷||1
+ITA|nation_ita|#5C9E6E|15|OPPORTUNIST|804|1,1,0,0,0,1|🇮🇹|AXIS|1
+ARG|nation_arg|#6FA8C4|230|TURTLE|720|1,1,0,0,0,1|🇦🇷||1
+MEX|nation_mex|#3F8F6B|209|TURTLE|720|1,1,0,0,0,1|🇲🇽||1
+ESP|nation_esp|#B08A3C|10|TURTLE|644|1,1,0,0,0,1|🇪🇸||1
+THA|nation_tha|#5C86A8|166|BALANCED|528|1,1,0,0,0,1|🇹🇭|AXIS|1
+CHL|nation_chl|#A8544C|225|TURTLE|525|1,1,0,0,0,1|🇨🇱||1
+SWE|nation_swe|#4C6E9E|32|TURTLE|504|1,1,0,0,0,1|🇸🇪||1
+COL|nation_col|#C29A3C|217|TURTLE|462|0,0,0,0,0,0|🇨🇴||1
+NZL|nation_nzl|#5C9E93|252|TURTLE|418|0,0,0,0,0,0|🇳🇿|ALLIES|1
+PER|nation_per|#B06A4C|222|TURTLE|418|0,0,0,0,0,0|🇵🇪||1
+VEN|nation_ven|#B4703C|219|TURTLE|399|0,0,0,0,0,0|🇻🇪||1
+CHE|nation_che|#B45C5C|18|TURTLE|378|0,0,0,0,0,0|🇨🇭||1
+ETH|nation_eth|#6E9E4C|110|TURTLE|357|0,0,0,0,0,0|🇪🇹||1
+BEL|nation_bel|#9E8C4C|114|TURTLE|352|0,0,0,0,0,0|🇧🇪||1
+DNK|nation_dnk|#A85C6E|44|TURTLE|352|0,0,0,0,0,0|🇩🇰||1
+FIN|nation_fin|#7A9EB4|41|TURTLE|352|0,0,0,0,0,0|🇫🇮|AXIS|1
+ROU|nation_rou|#8C7A3C|28|TURTLE|352|0,0,0,0,0,0|🇷🇴|AXIS|1
+PRT|nation_prt|#4C8C7A|14|TURTLE|345|0,0,0,0,0,0|🇵🇹||1
+HUN|nation_hun|#9E7A4C|27|OPPORTUNIST|315|0,0,0,0,0,0|🇭🇺|AXIS|1
+CUB|nation_cub|#A85C4C|215|TURTLE|273|0,0,0,0,0,0|🇨🇺||1
IRL|nation_irl|#4C8C5C|3|TURTLE|273|0,0,0,0,0,0|🇮🇪||1
-ECU|nation_ecu|#C7A24E|216|TURTLE|264|0,0,0,0,0,0|🇪🇨||1
-BGR|nation_bgr|#6E8C5C|28|TURTLE|252|0,0,0,0,0,0|🇧🇬|AXIS|1
-BOL|nation_bol|#8C9A4C|220|TURTLE|252|0,0,0,0,0,0|🇧🇴||1
-AFG|nation_afg|#8C7A5C|88|TURTLE|231|0,0,0,0,0,0|🇦🇫||1
-GTM|nation_gtm|#57A07E|209|TURTLE|231|0,0,0,0,0,0|🇬🇹||1
-URY|nation_ury|#6E9BB0|227|TURTLE|231|0,0,0,0,0,0|🇺🇾||1
-PRY|nation_pry|#7F8F5C|228|TURTLE|210|0,0,0,0,0,0|🇵🇾||1
+ECU|nation_ecu|#C7A24E|220|TURTLE|264|0,0,0,0,0,0|🇪🇨||1
+BGR|nation_bgr|#6E8C5C|30|TURTLE|252|0,0,0,0,0,0|🇧🇬|AXIS|1
+BOL|nation_bol|#8C9A4C|224|TURTLE|252|0,0,0,0,0,0|🇧🇴||1
+AFG|nation_afg|#8C7A5C|92|TURTLE|231|0,0,0,0,0,0|🇦🇫||1
+GTM|nation_gtm|#57A07E|213|TURTLE|231|0,0,0,0,0,0|🇬🇹||1
+PAN|nation_pan|#4E9E86|214|TURTLE|231|0,0,0,0,0,0|🇵🇦||1
+URY|nation_ury|#6E9BB0|234|TURTLE|231|0,0,0,0,0,0|🇺🇾||1
+DOM|nation_dom|#9E6B58|216|TURTLE|210|0,0,0,0,0,0|🇩🇴||1
+PRY|nation_pry|#7F8F5C|235|TURTLE|210|0,0,0,0,0,0|🇵🇾||1
[relations]
DEU GBR WAR
@@ -62,7 +65,6 @@ DEU FRA WAR
DEU CAN WAR
DEU AUS WAR
DEU NZL WAR
-DEU ETH WAR
ITA GBR WAR
ITA USA WAR
ITA RUS WAR
@@ -71,7 +73,6 @@ ITA FRA WAR
ITA CAN WAR
ITA AUS WAR
ITA NZL WAR
-ITA ETH WAR
JPN GBR WAR
JPN USA WAR
JPN RUS WAR
@@ -80,7 +81,6 @@ JPN FRA WAR
JPN CAN WAR
JPN AUS WAR
JPN NZL WAR
-JPN ETH WAR
FIN GBR WAR
FIN USA WAR
FIN RUS WAR
@@ -89,7 +89,6 @@ FIN FRA WAR
FIN CAN WAR
FIN AUS WAR
FIN NZL WAR
-FIN ETH WAR
ROU GBR WAR
ROU USA WAR
ROU RUS WAR
@@ -98,7 +97,6 @@ ROU FRA WAR
ROU CAN WAR
ROU AUS WAR
ROU NZL WAR
-ROU ETH WAR
HUN GBR WAR
HUN USA WAR
HUN RUS WAR
@@ -107,7 +105,6 @@ HUN FRA WAR
HUN CAN WAR
HUN AUS WAR
HUN NZL WAR
-HUN ETH WAR
BGR GBR WAR
BGR USA WAR
BGR RUS WAR
@@ -116,7 +113,6 @@ BGR FRA WAR
BGR CAN WAR
BGR AUS WAR
BGR NZL WAR
-BGR ETH WAR
THA GBR WAR
THA USA WAR
THA RUS WAR
@@ -125,48 +121,50 @@ THA FRA WAR
THA CAN WAR
THA AUS WAR
THA NZL WAR
-THA ETH WAR
[owners]
-RUS: 46-72,78
-GBR: 0-2,76-77,79-80,82,85-87,89-92,101-103,105,107-109,113-118,121-133
-USA: 178-195,210-212
-JPN: 134-137,141-142,147-161,164-176
-DEU: 4-8,17-24,27,29,34-36,39,41-42,44-45,93
-ROC: 138-140,143-146
-FRA: 81,94-100,104,120
-BRA: 229-236
-AUS: 177,237-244
-CAN: 196-203
-SAU: 83-84
-TUR: 73-75
-ITA: 13-15
-MEX: 205-208
-ARG: 224-226
-ESP: 9-11
-THA: 162-163
-SWE: 30-33
-CHL: 221-223
-COL: 213-214
-NZL: 245-246
-PER: 218-219
-VEN: 215
-CHE: 16
-ETH: 106
-BEL: 110-111
-DNK: 40,204
-FIN: 37-38
-ROU: 26,43
-PRT: 12,112,119
-HUN: 25
+RUS: 50-76,82
+GBR: 0-2,4,13,80-81,83-84,86,89-91,93-96,105-107,109,111-113,117-122,125-137
+JPN: 138-141,145-146,151-165,168-180
+USA: 182-199
+DEU: 5-9,19-26,29,31,36-40,43,45-46,48-49,97
+ROC: 142-144,147-150
+FRA: 85,98-104,108,124
+BRA: 236-243
+AUS: 181,244-251
+CAN: 200-207
+SAU: 87-88
+TUR: 77-79
+ITA: 15-17
+ARG: 230-233
+MEX: 209-212
+ESP: 10-12
+THA: 166-167
+CHL: 225-229
+SWE: 32-35
+COL: 217-218
+NZL: 252-253
+PER: 222-223
+VEN: 219
+CHE: 18
+ETH: 110
+BEL: 114-115
+DNK: 44,208
+FIN: 41-42
+ROU: 28,47
+PRT: 14,116,123
+HUN: 27
+CUB: 215
IRL: 3
-ECU: 216-217
-BGR: 28
-BOL: 220
-AFG: 88
-GTM: 209
-URY: 227
-PRY: 228
+ECU: 220-221
+BGR: 30
+BOL: 224
+AFG: 92
+GTM: 213
+PAN: 214
+URY: 234
+DOM: 216
+PRY: 235
[units]
GBR|47,17|INFANTRY|1|-
@@ -264,6 +262,9 @@ MEX|16,43|INFANTRY|1|-
MEX|17,43|ARTILLERY|1|-
MEX|17,42|ARMOUR|1|-
GTM|19,45|INFANTRY|1|-
+PAN|23,48|INFANTRY|1|-
+CUB|22,41|INFANTRY|1|-
+DOM|26,43|INFANTRY|1|-
COL|25,51|INFANTRY|1|-
COL|26,51|ARTILLERY|1|-
VEN|28,48|INFANTRY|1|-
@@ -275,6 +276,7 @@ CHL|27,68|INFANTRY|1|-
CHL|28,68|ARTILLERY|1|-
ARG|30,69|INFANTRY|1|-
ARG|30,68|ARTILLERY|1|-
+ARG|29,69|ARMOUR|1|-
URY|31,68|INFANTRY|1|-
PRY|30,65|INFANTRY|1|-
BRA|33,63|INFANTRY|1|-
@@ -285,7 +287,7 @@ BRA|34,64|DESTROYER|1|-
NZL|119,70|INFANTRY|1|-
[playable]
-RUS,GBR,USA,JPN,DEU,ROC,FRA,AUS,CAN,ITA,THA,NZL,ETH,FIN,ROU,HUN,BGR
+RUS,GBR,JPN,USA,DEU,ROC,FRA,AUS,CAN,ITA,THA,NZL,FIN,ROU,HUN,BGR
[objectives]
# 沒有列出目標 = 征服模式的預設條件(拿下地圖上八成的省份)
diff --git a/app/src/main/assets/scenarios/conquest_1950.scn b/app/src/main/assets/scenarios/conquest_1950.scn
index 1bfcc94..531ded5 100644
--- a/app/src/main/assets/scenarios/conquest_1950.scn
+++ b/app/src/main/assets/scenarios/conquest_1950.scn
@@ -13,74 +13,74 @@ startYear 1950
startMonth 1
[nations]
-RUS|nation_sun|#8C6E4C|46|AGGRESSIVE|3824|2,2,2,2,2,1|🇷🇺|EAST|1
-USA|nation_usa|#4C7BA8|178|BALANCED|3040|2,2,2,2,2,1|🇺🇸|WEST|1
-CHN|nation_chn|#B4454C|134|BALANCED|2890|2,2,2,2,2,1|🇨🇳|EAST|1
-GBR|nation_gbr|#8C4C4C|0|BALANCED|2200|2,2,2,2,2,1|🇬🇧|WEST|1
-FRA|nation_fra|#4C5C9E|4|BALANCED|1710|2,2,2,2,2,1|🇫🇷|WEST|1
-IND|nation_ind|#C4864C|121|TURTLE|1610|2,2,2,2,2,1|🇮🇳||1
-JPN|nation_jpn|#C45C5C|155|BALANCED|1500|2,2,2,2,2,1|🇯🇵|WEST|1
-DEU|nation_frg|#6E7A86|19|AGGRESSIVE|1322|1,1,1,1,1,1|🇩🇪|WEST|1
-BRA|nation_bra|#4F9A50|229|TURTLE|1260|1,1,1,1,1,1|🇧🇷||1
-AUS|nation_aus|#C4A05C|237|BALANCED|1189|1,1,1,1,1,1|🇦🇺|WEST|1
-CAN|nation_can|#6E93B5|196|TURTLE|979|1,1,1,1,1,1|🇨🇦|WEST|1
-SAU|nation_sau|#4C8C5C|83|TURTLE|902|1,1,1,1,1,1|🇸🇦||1
-IDN|nation_idn|#A85C4C|170|TURTLE|875|1,1,0,0,0,1|🇮🇩||1
-TUR|nation_tur|#A84C4C|73|AGGRESSIVE|850|1,1,0,0,0,1|🇹🇷|WEST|1
-ITA|nation_ita|#5C9E6E|13|OPPORTUNIST|840|1,1,0,0,0,1|🇮🇹|WEST|1
-IRN|nation_irn|#4C8C6E|76|TURTLE|804|1,1,0,0,0,1|🇮🇷||1
-EGY|nation_egy|#C4A84C|89|TURTLE|736|1,1,0,0,0,1|🇪🇬||1
-ZAF|nation_zaf|#4C7A5C|117|TURTLE|736|1,1,0,0,0,1|🇿🇦||1
-DDR|nation_ddr|#8C5A5A|17|BALANCED|735|1,1,0,0,0,1||EAST|1
-MEX|nation_mex|#3F8F6B|205|TURTLE|720|1,1,0,0,0,1|🇲🇽||1
-ARG|nation_arg|#6FA8C4|224|TURTLE|690|1,1,0,0,0,1|🇦🇷||1
-KOR|nation_kor|#5C9EB4|151|TURTLE|682|1,1,0,0,0,1|🇰🇷|WEST|1
-ESP|nation_esp|#B08A3C|9|TURTLE|644|1,1,0,0,0,1|🇪🇸||1
-PAK|nation_pak|#4C8C5C|129|TURTLE|644|1,1,0,0,0,1|🇵🇰||1
-POL|nation_pol|#B4535C|23|BALANCED|572|1,1,0,0,0,1|🇵🇱|EAST|1
-TWN|nation_roc|#4C86B4|149|TURTLE|572|1,1,0,0,0,1|🇹🇼|WEST|1
-THA|nation_tha|#5C86A8|162|TURTLE|528|1,1,0,0,0,1|🇹🇭||1
-SWE|nation_swe|#4C6E9E|30|TURTLE|504|1,1,0,0,0,1|🇸🇪||1
-CHL|nation_chl|#A8544C|221|TURTLE|482|0,0,0,0,0,0|🇨🇱||1
-COL|nation_col|#C29A3C|213|TURTLE|462|0,0,0,0,0,0|🇨🇴||1
-IRQ|nation_irq|#8C8C4C|79|TURTLE|462|0,0,0,0,0,0|🇮🇶||1
-PHL|nation_phl|#4C86A8|175|TURTLE|462|0,0,0,0,0,0|🇵🇭|WEST|1
-ISR|nation_isr|#5C86B4|82|TURTLE|441|0,0,0,0,0,0|🇮🇱||1
-NOR|nation_nor|#5C7EA8|34|TURTLE|418|0,0,0,0,0,0|🇳🇴|WEST|1
-NZL|nation_nzl|#5C9E93|245|TURTLE|418|0,0,0,0,0,0|🇳🇿|WEST|1
-PER|nation_per|#B06A4C|218|TURTLE|418|0,0,0,0,0,0|🇵🇪||1
-NLD|nation_nld|#C4813C|8|TURTLE|399|0,0,0,0,0,0|🇳🇱|WEST|1
-VEN|nation_ven|#B4703C|215|TURTLE|399|0,0,0,0,0,0|🇻🇪||1
-PRK|nation_prk|#8C5C6E|153|AGGRESSIVE|396|0,0,0,0,0,0|🇰🇵|EAST|1
-CHE|nation_che|#B45C5C|16|TURTLE|378|0,0,0,0,0,0|🇨🇭||1
-BEL|nation_bel|#9E8C4C|110|TURTLE|368|0,0,0,0,0,0|🇧🇪|WEST|1
-DNK|nation_dnk|#A85C6E|35|TURTLE|368|0,0,0,0,0,0|🇩🇰|WEST|1
-AUT|nation_aut|#A0A6AC|21|TURTLE|357|0,0,0,0,0,0|🇦🇹||1
-ETH|nation_eth|#6E9E4C|106|TURTLE|357|0,0,0,0,0,0|🇪🇹||1
-FIN|nation_fin|#7A9EB4|37|TURTLE|352|0,0,0,0,0,0|🇫🇮||1
-PRT|nation_prt|#4C8C7A|12|TURTLE|345|0,0,0,0,0,0|🇵🇹|WEST|1
-ROU|nation_rou|#8C7A3C|26|TURTLE|336|0,0,0,0,0,0|🇷🇴|EAST|1
-MMR|nation_mmr|#8C9E4C|160|TURTLE|330|0,0,0,0,0,0|🇲🇲||1
-CZE|nation_cze|#8A96A0|22|TURTLE|315|0,0,0,0,0,0|🇨🇿|EAST|1
-GRC|nation_grc|#4C7AA8|29|TURTLE|315|0,0,0,0,0,0|🇬🇷|WEST|1
-HUN|nation_hun|#9E7A4C|25|OPPORTUNIST|315|0,0,0,0,0,0|🇭🇺|EAST|1
-CUB|nation_cub|#A85C4C|211|TURTLE|273|0,0,0,0,0,0|🇨🇺||1
+RUS|nation_sun|#8C6E4C|50|AGGRESSIVE|3824|2,2,2,2,2,1|🇷🇺|EAST|1
+USA|nation_usa|#4C7BA8|182|BALANCED|3040|2,2,2,2,2,1|🇺🇸|WEST|1
+CHN|nation_prc|#B4454C|138|BALANCED|2890|2,2,2,2,2,1|🇨🇳|EAST|1
+GBR|nation_gbr|#8C4C4C|0|BALANCED|2310|2,2,2,2,2,1|🇬🇧|WEST|1
+FRA|nation_fra|#4C5C9E|5|BALANCED|1710|2,2,2,2,2,1|🇫🇷|WEST|1
+IND|nation_ind|#C4864C|125|TURTLE|1610|2,2,2,2,2,1|🇮🇳||1
+JPN|nation_jpn|#C45C5C|159|BALANCED|1500|2,2,2,2,2,1|🇯🇵|WEST|1
+DEU|nation_frg|#6E7A86|21|AGGRESSIVE|1322|1,1,1,1,1,1|🇩🇪|WEST|1
+BRA|nation_bra|#4F9A50|236|TURTLE|1260|1,1,1,1,1,1|🇧🇷||1
+AUS|nation_aus|#C4A05C|244|BALANCED|1189|1,1,1,1,1,1|🇦🇺|WEST|1
+CAN|nation_can|#6E93B5|200|TURTLE|979|1,1,1,1,1,1|🇨🇦|WEST|1
+SAU|nation_sau|#4C8C5C|87|TURTLE|902|1,1,1,1,1,1|🇸🇦||1
+IDN|nation_idn|#A85C4C|174|TURTLE|875|1,1,0,0,0,1|🇮🇩||1
+TUR|nation_tur|#A84C4C|77|AGGRESSIVE|850|1,1,0,0,0,1|🇹🇷|WEST|1
+ITA|nation_ita|#5C9E6E|15|OPPORTUNIST|840|1,1,0,0,0,1|🇮🇹|WEST|1
+IRN|nation_irn|#4C8C6E|80|TURTLE|804|1,1,0,0,0,1|🇮🇷||1
+EGY|nation_egy|#C4A84C|93|TURTLE|736|1,1,0,0,0,1|🇪🇬||1
+ZAF|nation_zaf|#4C7A5C|121|TURTLE|736|1,1,0,0,0,1|🇿🇦||1
+DDR|nation_ddr|#8C5A5A|19|BALANCED|735|1,1,0,0,0,1||EAST|1
+ARG|nation_arg|#6FA8C4|230|TURTLE|720|1,1,0,0,0,1|🇦🇷||1
+MEX|nation_mex|#3F8F6B|209|TURTLE|720|1,1,0,0,0,1|🇲🇽||1
+KOR|nation_kor|#5C9EB4|155|TURTLE|682|1,1,0,0,0,1|🇰🇷|WEST|1
+ESP|nation_esp|#B08A3C|10|TURTLE|644|1,1,0,0,0,1|🇪🇸||1
+PAK|nation_pak|#4C8C5C|133|TURTLE|644|1,1,0,0,0,1|🇵🇰||1
+POL|nation_pol|#B4535C|25|BALANCED|572|1,1,0,0,0,1|🇵🇱|EAST|1
+TWN|nation_roc|#4C86B4|153|TURTLE|572|1,1,0,0,0,1|🇹🇼|WEST|1
+THA|nation_tha|#5C86A8|166|TURTLE|528|1,1,0,0,0,1|🇹🇭||1
+CHL|nation_chl|#A8544C|225|TURTLE|525|1,1,0,0,0,1|🇨🇱||1
+SWE|nation_swe|#4C6E9E|32|TURTLE|504|1,1,0,0,0,1|🇸🇪||1
+COL|nation_col|#C29A3C|217|TURTLE|462|0,0,0,0,0,0|🇨🇴||1
+IRQ|nation_irq|#8C8C4C|83|TURTLE|462|0,0,0,0,0,0|🇮🇶||1
+PHL|nation_phl|#4C86A8|179|TURTLE|462|0,0,0,0,0,0|🇵🇭|WEST|1
+NOR|nation_nor|#5C7EA8|36|TURTLE|456|0,0,0,0,0,0|🇳🇴|WEST|1
+ISR|nation_isr|#5C86B4|86|TURTLE|441|0,0,0,0,0,0|🇮🇱||1
+NZL|nation_nzl|#5C9E93|252|TURTLE|418|0,0,0,0,0,0|🇳🇿|WEST|1
+PER|nation_per|#B06A4C|222|TURTLE|418|0,0,0,0,0,0|🇵🇪||1
+NLD|nation_nld|#C4813C|9|TURTLE|399|0,0,0,0,0,0|🇳🇱|WEST|1
+VEN|nation_ven|#B4703C|219|TURTLE|399|0,0,0,0,0,0|🇻🇪||1
+PRK|nation_prk|#8C5C6E|157|AGGRESSIVE|396|0,0,0,0,0,0|🇰🇵|EAST|1
+CHE|nation_che|#B45C5C|18|TURTLE|378|0,0,0,0,0,0|🇨🇭||1
+BEL|nation_bel|#9E8C4C|114|TURTLE|368|0,0,0,0,0,0|🇧🇪|WEST|1
+DNK|nation_dnk|#A85C6E|39|TURTLE|368|0,0,0,0,0,0|🇩🇰|WEST|1
+AUT|nation_aut|#A0A6AC|23|TURTLE|357|0,0,0,0,0,0|🇦🇹||1
+ETH|nation_eth|#6E9E4C|110|TURTLE|357|0,0,0,0,0,0|🇪🇹||1
+FIN|nation_fin|#7A9EB4|41|TURTLE|352|0,0,0,0,0,0|🇫🇮||1
+PRT|nation_prt|#4C8C7A|14|TURTLE|345|0,0,0,0,0,0|🇵🇹|WEST|1
+ROU|nation_rou|#8C7A3C|28|TURTLE|336|0,0,0,0,0,0|🇷🇴|EAST|1
+MMR|nation_mmr|#8C9E4C|164|TURTLE|330|0,0,0,0,0,0|🇲🇲||1
+CZE|nation_cze|#8A96A0|24|TURTLE|315|0,0,0,0,0,0|🇨🇿|EAST|1
+GRC|nation_grc|#4C7AA8|31|TURTLE|315|0,0,0,0,0,0|🇬🇷|WEST|1
+HUN|nation_hun|#9E7A4C|27|OPPORTUNIST|315|0,0,0,0,0,0|🇭🇺|EAST|1
+CUB|nation_cub|#A85C4C|215|TURTLE|273|0,0,0,0,0,0|🇨🇺||1
IRL|nation_irl|#4C8C5C|3|TURTLE|273|0,0,0,0,0,0|🇮🇪||1
-SRB|nation_srb|#8C5C4C|27|TURTLE|273|0,0,0,0,0,0|🇷🇸||1
-SYR|nation_syr|#7A8C5C|81|TURTLE|273|0,0,0,0,0,0|🇸🇾||1
-ECU|nation_ecu|#C7A24E|216|TURTLE|264|0,0,0,0,0,0|🇪🇨||1
-BGR|nation_bgr|#6E8C5C|28|TURTLE|252|0,0,0,0,0,0|🇧🇬|EAST|1
-BOL|nation_bol|#8C9A4C|220|TURTLE|252|0,0,0,0,0,0|🇧🇴||1
-MNG|nation_mng|#B4A05C|72|TURTLE|252|0,0,0,0,0,0|🇲🇳|EAST|1
-AFG|nation_afg|#8C7A5C|88|TURTLE|231|0,0,0,0,0,0|🇦🇫||1
-GTM|nation_gtm|#57A07E|209|TURTLE|231|0,0,0,0,0,0|🇬🇹||1
-LKA|nation_lka|#B4844C|132|TURTLE|231|0,0,0,0,0,0|🇱🇰||1
-PAN|nation_pan|#4E9E86|210|TURTLE|231|0,0,0,0,0,0|🇵🇦||1
-URY|nation_ury|#6E9BB0|227|TURTLE|231|0,0,0,0,0,0|🇺🇾||1
-DOM|nation_dom|#9E6B58|212|TURTLE|210|0,0,0,0,0,0|🇩🇴||1
-PRY|nation_pry|#7F8F5C|228|TURTLE|210|0,0,0,0,0,0|🇵🇾||1
-NPL|nation_npl|#A85C5C|133|TURTLE|189|0,0,0,0,0,0|🇳🇵||1
-ISL|nation_isl|#93A8B4|40|TURTLE|157|0,0,0,0,0,0|🇮🇸|WEST|1
+SRB|nation_srb|#8C5C4C|29|TURTLE|273|0,0,0,0,0,0|🇷🇸||1
+SYR|nation_syr|#7A8C5C|85|TURTLE|273|0,0,0,0,0,0|🇸🇾||1
+ECU|nation_ecu|#C7A24E|220|TURTLE|264|0,0,0,0,0,0|🇪🇨||1
+BGR|nation_bgr|#6E8C5C|30|TURTLE|252|0,0,0,0,0,0|🇧🇬|EAST|1
+BOL|nation_bol|#8C9A4C|224|TURTLE|252|0,0,0,0,0,0|🇧🇴||1
+MNG|nation_mng|#B4A05C|76|TURTLE|252|0,0,0,0,0,0|🇲🇳|EAST|1
+AFG|nation_afg|#8C7A5C|92|TURTLE|231|0,0,0,0,0,0|🇦🇫||1
+GTM|nation_gtm|#57A07E|213|TURTLE|231|0,0,0,0,0,0|🇬🇹||1
+LKA|nation_lka|#B4844C|136|TURTLE|231|0,0,0,0,0,0|🇱🇰||1
+PAN|nation_pan|#4E9E86|214|TURTLE|231|0,0,0,0,0,0|🇵🇦||1
+URY|nation_ury|#6E9BB0|234|TURTLE|231|0,0,0,0,0,0|🇺🇾||1
+DOM|nation_dom|#9E6B58|216|TURTLE|210|0,0,0,0,0,0|🇩🇴||1
+PRY|nation_pry|#7F8F5C|235|TURTLE|210|0,0,0,0,0,0|🇵🇾||1
+NPL|nation_npl|#A85C5C|137|TURTLE|189|0,0,0,0,0,0|🇳🇵||1
+ISL|nation_isl|#93A8B4|44|TURTLE|157|0,0,0,0,0,0|🇮🇸|WEST|1
[relations]
USA RUS WAR
@@ -285,74 +285,74 @@ PHL PRK WAR
PHL MNG WAR
[owners]
-RUS: 39,42-71
-USA: 178-195
-CHN: 134-147
-GBR: 0-2,85-87,92,101-103,105,108-109,113-115,148,167-169
-FRA: 4-6,93-100,104,120,164-166
-IND: 121-128
-JPN: 155-159
-DEU: 18-20
-BRA: 229-236
-AUS: 177,237-244
-CAN: 196-203
-SAU: 83-84
-IDN: 170-174
-TUR: 73-75
-ITA: 13-15,107
-IRN: 76-78
-EGY: 89-91
-ZAF: 116-118
-DDR: 17
-MEX: 205-208
-ARG: 224-226
-KOR: 151-152
-ESP: 9-11
-PAK: 129-131
-POL: 23-24
-TWN: 149-150
-THA: 162-163
-SWE: 30-33
-CHL: 221-223
-COL: 213-214
-IRQ: 79-80
-PHL: 175-176
-ISR: 82
-NOR: 34,41
-NZL: 245-246
-PER: 218-219
-NLD: 8
-VEN: 215
-PRK: 153-154
-CHE: 16
-BEL: 7,110-111
-DNK: 35-36,204
-AUT: 21
-ETH: 106
-FIN: 37-38
-PRT: 12,112,119
-ROU: 26
-MMR: 160-161
-CZE: 22
-GRC: 29
-HUN: 25
-CUB: 211
+RUS: 43,46-75
+USA: 182-199
+CHN: 138-151
+GBR: 0-2,4,13,89-91,96,105-107,109,112-113,117-119,152,171-173
+FRA: 5-7,97-104,108,124,168-170
+IND: 125-132
+JPN: 159-163
+DEU: 20-22
+BRA: 236-243
+AUS: 181,244-251
+CAN: 200-207
+SAU: 87-88
+IDN: 174-178
+TUR: 77-79
+ITA: 15-17,111
+IRN: 80-82
+EGY: 93-95
+ZAF: 120-122
+DDR: 19
+ARG: 230-233
+MEX: 209-212
+KOR: 155-156
+ESP: 10-12
+PAK: 133-135
+POL: 25-26
+TWN: 153-154
+THA: 166-167
+CHL: 225-229
+SWE: 32-35
+COL: 217-218
+IRQ: 83-84
+PHL: 179-180
+NOR: 36-38,45
+ISR: 86
+NZL: 252-253
+PER: 222-223
+NLD: 9
+VEN: 219
+PRK: 157-158
+CHE: 18
+BEL: 8,114-115
+DNK: 39-40,208
+AUT: 23
+ETH: 110
+FIN: 41-42
+PRT: 14,116,123
+ROU: 28
+MMR: 164-165
+CZE: 24
+GRC: 31
+HUN: 27
+CUB: 215
IRL: 3
-SRB: 27
-SYR: 81
-ECU: 216-217
-BGR: 28
-BOL: 220
-MNG: 72
-AFG: 88
-GTM: 209
-LKA: 132
-PAN: 210
-URY: 227
-DOM: 212
-PRY: 228
-NPL: 133
-ISL: 40
+SRB: 29
+SYR: 85
+ECU: 220-221
+BGR: 30
+BOL: 224
+MNG: 76
+AFG: 92
+GTM: 213
+LKA: 136
+PAN: 214
+URY: 234
+DOM: 216
+PRY: 235
+NPL: 137
+ISL: 44
[units]
GBR|47,17|INFANTRY|1|-
@@ -458,7 +458,7 @@ THA|93,46|ARTILLERY|1|-
IDN|95,56|INFANTRY|1|-
IDN|96,56|ARTILLERY|1|-
PHL|102,45|INFANTRY|1|-
-PHL|103,45|ARTILLERY|1|-
+PHL|103,44|ARTILLERY|1|-
AUS|116,68|INFANTRY|1|-
AUS|115,67|ARTILLERY|1|-
AUS|115,68|ARMOUR|1|-
@@ -494,6 +494,7 @@ CHL|27,68|INFANTRY|1|-
CHL|28,68|ARTILLERY|1|-
ARG|30,69|INFANTRY|1|-
ARG|30,68|ARTILLERY|1|-
+ARG|29,69|ARMOUR|1|-
URY|31,68|INFANTRY|1|-
PRY|30,65|INFANTRY|1|-
BRA|33,63|INFANTRY|1|-
@@ -502,6 +503,12 @@ BRA|33,62|ARMOUR|1|-
BRA|34,63|INFANTRY|1|-
BRA|34,64|DESTROYER|1|-
NZL|119,70|INFANTRY|1|-
+TWN|91,42|INFANTRY|2|-
+TWN|91,40|INFANTRY|1|-
+TWN|94,40|INFANTRY|1|-
+TWN|103,37|DESTROYER|1|-
+TWN|102,39|DESTROYER|1|-
+TWN|102,40|CRUISER|1|-
[playable]
RUS,USA,CHN,GBR,FRA,JPN,DEU,AUS,CAN,TUR,ITA,DDR,KOR,POL,TWN,PHL,NOR,NZL,NLD,PRK,BEL,DNK,PRT,ROU,CZE,GRC,HUN,BGR,MNG,ISL
diff --git a/app/src/main/assets/scenarios/conquest_1980.scn b/app/src/main/assets/scenarios/conquest_1980.scn
index fd1fed3..f3b8483 100644
--- a/app/src/main/assets/scenarios/conquest_1980.scn
+++ b/app/src/main/assets/scenarios/conquest_1980.scn
@@ -13,104 +13,104 @@ startYear 1980
startMonth 1
[nations]
-RUS|nation_sun|#8C6E4C|46|AGGRESSIVE|3824|2,2,2,2,2,1|🇷🇺|PACT|1
-USA|nation_usa|#4C7BA8|178|BALANCED|3040|2,2,2,2,2,1|🇺🇸|NATO|1
-CHN|nation_chn|#B4454C|134|TURTLE|2890|2,2,2,2,2,1|🇨🇳||1
-IND|nation_ind|#C4864C|121|TURTLE|1610|2,2,2,2,2,1|🇮🇳||1
-JPN|nation_jpn|#C45C5C|155|TURTLE|1500|2,2,2,2,2,1|🇯🇵||1
-DEU|nation_frg|#6E7A86|19|AGGRESSIVE|1322|1,1,1,1,1,1|🇩🇪|NATO|1
-GBR|nation_gbr|#8C4C4C|0|BALANCED|1320|1,1,1,1,1,1|🇬🇧|NATO|1
-BRA|nation_bra|#4F9A50|229|TURTLE|1260|1,1,1,1,1,1|🇧🇷||1
-AUS|nation_aus|#C4A05C|237|TURTLE|1148|1,1,1,1,1,1|🇦🇺||1
-FRA|nation_fra|#4C5C9E|4|BALANCED|1092|1,1,1,1,1,1|🇫🇷|NATO|1
-CAN|nation_can|#6E93B5|196|TURTLE|979|1,1,1,1,1,1|🇨🇦|NATO|1
-SAU|nation_sau|#4C8C5C|83|TURTLE|902|1,1,1,1,1,1|🇸🇦||1
-IDN|nation_idn|#A85C4C|170|TURTLE|875|1,1,0,0,0,1|🇮🇩||1
-TUR|nation_tur|#A84C4C|73|AGGRESSIVE|850|1,1,0,0,0,1|🇹🇷|NATO|1
-IRN|nation_irn|#4C8C6E|76|TURTLE|804|1,1,0,0,0,1|🇮🇷||1
-ITA|nation_ita|#5C9E6E|13|OPPORTUNIST|804|1,1,0,0,0,1|🇮🇹|NATO|1
-EGY|nation_egy|#C4A84C|89|TURTLE|736|1,1,0,0,0,1|🇪🇬||1
-ZAF|nation_zaf|#4C7A5C|117|TURTLE|736|1,1,0,0,0,1|🇿🇦||1
-DDR|nation_ddr|#8C5A5A|17|BALANCED|735|1,1,0,0,0,1||PACT|1
-MEX|nation_mex|#3F8F6B|205|TURTLE|720|1,1,0,0,0,1|🇲🇽||1
-ARG|nation_arg|#6FA8C4|224|TURTLE|690|1,1,0,0,0,1|🇦🇷||1
-KOR|nation_kor|#5C9EB4|151|TURTLE|682|1,1,0,0,0,1|🇰🇷||1
-ESP|nation_esp|#B08A3C|9|TURTLE|644|1,1,0,0,0,1|🇪🇸||1
-NGA|nation_nga|#4C9E5C|102|TURTLE|616|1,1,0,0,0,1|🇳🇬||1
-PAK|nation_pak|#4C8C5C|129|TURTLE|616|1,1,0,0,0,1|🇵🇰||1
-POL|nation_pol|#B4535C|23|BALANCED|572|1,1,0,0,0,1|🇵🇱|PACT|1
-TWN|nation_roc|#4C86B4|149|TURTLE|572|1,1,0,0,0,1|🇹🇼||1
-SGP|nation_sgp|#B45C5C|169|TURTLE|546|1,1,0,0,0,1|🇸🇬||1
-THA|nation_tha|#5C86A8|162|TURTLE|528|1,1,0,0,0,1|🇹🇭||1
-DZA|nation_dza|#5C9E5C|94|TURTLE|506|1,1,0,0,0,1|🇩🇿||1
-VNM|nation_vnm|#B4954C|165|TURTLE|506|1,1,0,0,0,1|🇻🇳||1
-SWE|nation_swe|#4C6E9E|30|TURTLE|504|1,1,0,0,0,1|🇸🇪||1
-ARE|nation_are|#6E9E7A|85|TURTLE|483|0,0,0,0,0,0|🇦🇪||1
-CHL|nation_chl|#A8544C|221|TURTLE|482|0,0,0,0,0,0|🇨🇱||1
-COL|nation_col|#C29A3C|213|TURTLE|462|0,0,0,0,0,0|🇨🇴||1
-IRQ|nation_irq|#8C8C4C|79|TURTLE|462|0,0,0,0,0,0|🇮🇶||1
-MYS|nation_mys|#4C9E6E|167|TURTLE|462|0,0,0,0,0,0|🇲🇾||1
-PHL|nation_phl|#4C86A8|175|TURTLE|462|0,0,0,0,0,0|🇵🇭||1
-ISR|nation_isr|#5C86B4|82|TURTLE|441|0,0,0,0,0,0|🇮🇱||1
-COD|nation_cod|#5C8C4C|110|TURTLE|418|0,0,0,0,0,0|🇨🇩||1
-NOR|nation_nor|#5C7EA8|34|TURTLE|418|0,0,0,0,0,0|🇳🇴|NATO|1
-NZL|nation_nzl|#5C9E93|245|TURTLE|418|0,0,0,0,0,0|🇳🇿||1
-PER|nation_per|#B06A4C|218|TURTLE|418|0,0,0,0,0,0|🇵🇪||1
-MAR|nation_mar|#A85C4C|96|TURTLE|399|0,0,0,0,0,0|🇲🇦||1
-NLD|nation_nld|#C4813C|8|TURTLE|399|0,0,0,0,0,0|🇳🇱|NATO|1
-VEN|nation_ven|#B4703C|215|TURTLE|399|0,0,0,0,0,0|🇻🇪||1
-PRK|nation_prk|#8C5C6E|153|TURTLE|396|0,0,0,0,0,0|🇰🇵||1
-CHE|nation_che|#B45C5C|16|TURTLE|378|0,0,0,0,0,0|🇨🇭||1
-DNK|nation_dnk|#A85C6E|35|TURTLE|368|0,0,0,0,0,0|🇩🇰|NATO|1
-AUT|nation_aut|#A0A6AC|21|TURTLE|357|0,0,0,0,0,0|🇦🇹||1
-ETH|nation_eth|#6E9E4C|106|TURTLE|357|0,0,0,0,0,0|🇪🇹||1
-FIN|nation_fin|#7A9EB4|37|TURTLE|352|0,0,0,0,0,0|🇫🇮||1
-AGO|nation_ago|#A8804C|112|TURTLE|336|0,0,0,0,0,0|🇦🇴||1
-BEL|nation_bel|#9E8C4C|7|TURTLE|336|0,0,0,0,0,0|🇧🇪|NATO|1
-BGD|nation_bgd|#5C9E7A|131|TURTLE|336|0,0,0,0,0,0|🇧🇩||1
-KEN|nation_ken|#4C8C6E|108|TURTLE|336|0,0,0,0,0,0|🇰🇪||1
-LBY|nation_lby|#A89A5C|92|TURTLE|336|0,0,0,0,0,0|🇱🇾||1
-ROU|nation_rou|#8C7A3C|26|TURTLE|336|0,0,0,0,0,0|🇷🇴|PACT|1
-MMR|nation_mmr|#8C9E4C|160|TURTLE|330|0,0,0,0,0,0|🇲🇲||1
-CZE|nation_cze|#8A96A0|22|TURTLE|315|0,0,0,0,0,0|🇨🇿|PACT|1
-GRC|nation_grc|#4C7AA8|29|TURTLE|315|0,0,0,0,0,0|🇬🇷|NATO|1
-HUN|nation_hun|#9E7A4C|25|OPPORTUNIST|315|0,0,0,0,0,0|🇭🇺|PACT|1
-PRT|nation_prt|#4C8C7A|12|TURTLE|315|0,0,0,0,0,0|🇵🇹|NATO|1
-SDN|nation_sdn|#9E8C4C|105|TURTLE|294|0,0,0,0,0,0|🇸🇩||1
-TZA|nation_tza|#4C9E86|113|TURTLE|294|0,0,0,0,0,0|🇹🇿||1
-CUB|nation_cub|#A85C4C|211|TURTLE|273|0,0,0,0,0,0|🇨🇺||1
-GHA|nation_gha|#B4844C|101|TURTLE|273|0,0,0,0,0,0|🇬🇭||1
+RUS|nation_sun|#8C6E4C|50|AGGRESSIVE|3824|2,2,2,2,2,1|🇷🇺|PACT|1
+USA|nation_usa|#4C7BA8|182|BALANCED|3040|2,2,2,2,2,1|🇺🇸|NATO|1
+CHN|nation_prc|#B4454C|138|TURTLE|2890|2,2,2,2,2,1|🇨🇳||1
+IND|nation_ind|#C4864C|125|TURTLE|1610|2,2,2,2,2,1|🇮🇳||1
+JPN|nation_jpn|#C45C5C|159|TURTLE|1500|2,2,2,2,2,1|🇯🇵||1
+GBR|nation_gbr|#8C4C4C|0|BALANCED|1430|2,2,2,2,2,1|🇬🇧|NATO|1
+DEU|nation_frg|#6E7A86|21|AGGRESSIVE|1322|1,1,1,1,1,1|🇩🇪|NATO|1
+BRA|nation_bra|#4F9A50|236|TURTLE|1260|1,1,1,1,1,1|🇧🇷||1
+AUS|nation_aus|#C4A05C|244|TURTLE|1148|1,1,1,1,1,1|🇦🇺||1
+FRA|nation_fra|#4C5C9E|5|BALANCED|1092|1,1,1,1,1,1|🇫🇷|NATO|1
+CAN|nation_can|#6E93B5|200|TURTLE|979|1,1,1,1,1,1|🇨🇦|NATO|1
+SAU|nation_sau|#4C8C5C|87|TURTLE|902|1,1,1,1,1,1|🇸🇦||1
+IDN|nation_idn|#A85C4C|174|TURTLE|875|1,1,0,0,0,1|🇮🇩||1
+TUR|nation_tur|#A84C4C|77|AGGRESSIVE|850|1,1,0,0,0,1|🇹🇷|NATO|1
+IRN|nation_irn|#4C8C6E|80|TURTLE|804|1,1,0,0,0,1|🇮🇷||1
+ITA|nation_ita|#5C9E6E|15|OPPORTUNIST|804|1,1,0,0,0,1|🇮🇹|NATO|1
+EGY|nation_egy|#C4A84C|93|TURTLE|736|1,1,0,0,0,1|🇪🇬||1
+ZAF|nation_zaf|#4C7A5C|121|TURTLE|736|1,1,0,0,0,1|🇿🇦||1
+DDR|nation_ddr|#8C5A5A|19|BALANCED|735|1,1,0,0,0,1||PACT|1
+ARG|nation_arg|#6FA8C4|230|TURTLE|720|1,1,0,0,0,1|🇦🇷||1
+MEX|nation_mex|#3F8F6B|209|TURTLE|720|1,1,0,0,0,1|🇲🇽||1
+KOR|nation_kor|#5C9EB4|155|TURTLE|682|1,1,0,0,0,1|🇰🇷||1
+ESP|nation_esp|#B08A3C|10|TURTLE|644|1,1,0,0,0,1|🇪🇸||1
+NGA|nation_nga|#4C9E5C|106|TURTLE|616|1,1,0,0,0,1|🇳🇬||1
+PAK|nation_pak|#4C8C5C|133|TURTLE|616|1,1,0,0,0,1|🇵🇰||1
+POL|nation_pol|#B4535C|25|BALANCED|572|1,1,0,0,0,1|🇵🇱|PACT|1
+TWN|nation_roc|#4C86B4|153|TURTLE|572|1,1,0,0,0,1|🇹🇼||1
+SGP|nation_sgp|#B45C5C|173|TURTLE|546|1,1,0,0,0,1|🇸🇬||1
+THA|nation_tha|#5C86A8|166|TURTLE|528|1,1,0,0,0,1|🇹🇭||1
+CHL|nation_chl|#A8544C|225|TURTLE|525|1,1,0,0,0,1|🇨🇱||1
+DZA|nation_dza|#5C9E5C|98|TURTLE|506|1,1,0,0,0,1|🇩🇿||1
+VNM|nation_vnm|#B4954C|169|TURTLE|506|1,1,0,0,0,1|🇻🇳||1
+SWE|nation_swe|#4C6E9E|32|TURTLE|504|1,1,0,0,0,1|🇸🇪||1
+ARE|nation_are|#6E9E7A|89|TURTLE|483|0,0,0,0,0,0|🇦🇪||1
+COL|nation_col|#C29A3C|217|TURTLE|462|0,0,0,0,0,0|🇨🇴||1
+IRQ|nation_irq|#8C8C4C|83|TURTLE|462|0,0,0,0,0,0|🇮🇶||1
+MYS|nation_mys|#4C9E6E|171|TURTLE|462|0,0,0,0,0,0|🇲🇾||1
+PHL|nation_phl|#4C86A8|179|TURTLE|462|0,0,0,0,0,0|🇵🇭||1
+NOR|nation_nor|#5C7EA8|36|TURTLE|456|0,0,0,0,0,0|🇳🇴|NATO|1
+ISR|nation_isr|#5C86B4|86|TURTLE|441|0,0,0,0,0,0|🇮🇱||1
+COD|nation_cod|#5C8C4C|114|TURTLE|418|0,0,0,0,0,0|🇨🇩||1
+NZL|nation_nzl|#5C9E93|252|TURTLE|418|0,0,0,0,0,0|🇳🇿||1
+PER|nation_per|#B06A4C|222|TURTLE|418|0,0,0,0,0,0|🇵🇪||1
+MAR|nation_mar|#A85C4C|100|TURTLE|399|0,0,0,0,0,0|🇲🇦||1
+NLD|nation_nld|#C4813C|9|TURTLE|399|0,0,0,0,0,0|🇳🇱|NATO|1
+VEN|nation_ven|#B4703C|219|TURTLE|399|0,0,0,0,0,0|🇻🇪||1
+PRK|nation_prk|#8C5C6E|157|TURTLE|396|0,0,0,0,0,0|🇰🇵||1
+CHE|nation_che|#B45C5C|18|TURTLE|378|0,0,0,0,0,0|🇨🇭||1
+DNK|nation_dnk|#A85C6E|39|TURTLE|368|0,0,0,0,0,0|🇩🇰|NATO|1
+AUT|nation_aut|#A0A6AC|23|TURTLE|357|0,0,0,0,0,0|🇦🇹||1
+ETH|nation_eth|#6E9E4C|110|TURTLE|357|0,0,0,0,0,0|🇪🇹||1
+FIN|nation_fin|#7A9EB4|41|TURTLE|352|0,0,0,0,0,0|🇫🇮||1
+AGO|nation_ago|#A8804C|116|TURTLE|336|0,0,0,0,0,0|🇦🇴||1
+BEL|nation_bel|#9E8C4C|8|TURTLE|336|0,0,0,0,0,0|🇧🇪|NATO|1
+BGD|nation_bgd|#5C9E7A|135|TURTLE|336|0,0,0,0,0,0|🇧🇩||1
+KEN|nation_ken|#4C8C6E|112|TURTLE|336|0,0,0,0,0,0|🇰🇪||1
+LBY|nation_lby|#A89A5C|96|TURTLE|336|0,0,0,0,0,0|🇱🇾||1
+ROU|nation_rou|#8C7A3C|28|TURTLE|336|0,0,0,0,0,0|🇷🇴|PACT|1
+MMR|nation_mmr|#8C9E4C|164|TURTLE|330|0,0,0,0,0,0|🇲🇲||1
+CZE|nation_cze|#8A96A0|24|TURTLE|315|0,0,0,0,0,0|🇨🇿|PACT|1
+GRC|nation_grc|#4C7AA8|31|TURTLE|315|0,0,0,0,0,0|🇬🇷|NATO|1
+HUN|nation_hun|#9E7A4C|27|OPPORTUNIST|315|0,0,0,0,0,0|🇭🇺|PACT|1
+PRT|nation_prt|#4C8C7A|14|TURTLE|315|0,0,0,0,0,0|🇵🇹|NATO|1
+SDN|nation_sdn|#9E8C4C|109|TURTLE|294|0,0,0,0,0,0|🇸🇩||1
+TZA|nation_tza|#4C9E86|117|TURTLE|294|0,0,0,0,0,0|🇹🇿||1
+CUB|nation_cub|#A85C4C|215|TURTLE|273|0,0,0,0,0,0|🇨🇺||1
+GHA|nation_gha|#B4844C|105|TURTLE|273|0,0,0,0,0,0|🇬🇭||1
IRL|nation_irl|#4C8C5C|3|TURTLE|273|0,0,0,0,0,0|🇮🇪||1
-OMN|nation_omn|#8C9E7A|87|TURTLE|273|0,0,0,0,0,0|🇴🇲||1
-SRB|nation_srb|#8C5C4C|27|TURTLE|273|0,0,0,0,0,0|🇷🇸||1
-SYR|nation_syr|#7A8C5C|81|TURTLE|273|0,0,0,0,0,0|🇸🇾||1
-ECU|nation_ecu|#C7A24E|216|TURTLE|264|0,0,0,0,0,0|🇪🇨||1
-BGR|nation_bgr|#6E8C5C|28|TURTLE|252|0,0,0,0,0,0|🇧🇬|PACT|1
-BOL|nation_bol|#8C9A4C|220|TURTLE|252|0,0,0,0,0,0|🇧🇴||1
-CIV|nation_civ|#C4954C|100|TURTLE|252|0,0,0,0,0,0|🇨🇮||1
-MNG|nation_mng|#B4A05C|72|TURTLE|252|0,0,0,0,0,0|🇲🇳||1
-TUN|nation_tun|#9E5C5C|93|TURTLE|252|0,0,0,0,0,0|🇹🇳||1
-AFG|nation_afg|#8C7A5C|88|TURTLE|231|0,0,0,0,0,0|🇦🇫||1
-GTM|nation_gtm|#57A07E|209|TURTLE|231|0,0,0,0,0,0|🇬🇹||1
-LKA|nation_lka|#B4844C|132|TURTLE|231|0,0,0,0,0,0|🇱🇰||1
-MOZ|nation_moz|#7A9E6E|119|TURTLE|231|0,0,0,0,0,0|🇲🇿||1
-PAN|nation_pan|#4E9E86|210|TURTLE|231|0,0,0,0,0,0|🇵🇦||1
-SEN|nation_sen|#5C9E7A|97|TURTLE|231|0,0,0,0,0,0|🇸🇳||1
-UGA|nation_uga|#7A9E5C|109|TURTLE|231|0,0,0,0,0,0|🇺🇬||1
-URY|nation_ury|#6E9BB0|227|TURTLE|231|0,0,0,0,0,0|🇺🇾||1
-ZMB|nation_zmb|#8C9E5C|114|TURTLE|231|0,0,0,0,0,0|🇿🇲||1
-MLI|nation_mli|#B49A5C|98|TURTLE|220|0,0,0,0,0,0|🇲🇱||1
-DOM|nation_dom|#9E6B58|212|TURTLE|210|0,0,0,0,0,0|🇩🇴||1
-KHM|nation_khm|#7A8C6E|166|TURTLE|210|0,0,0,0,0,0|🇰🇭||1
-MDG|nation_mdg|#8C6E9E|120|TURTLE|210|0,0,0,0,0,0|🇲🇬||1
-PRY|nation_pry|#7F8F5C|228|TURTLE|210|0,0,0,0,0,0|🇵🇾||1
-YEM|nation_yem|#A87A5C|86|TURTLE|210|0,0,0,0,0,0|🇾🇪||1
-ZWE|nation_zwe|#9E8C5C|115|TURTLE|210|0,0,0,0,0,0|🇿🇼||1
-NPL|nation_npl|#A85C5C|133|TURTLE|189|0,0,0,0,0,0|🇳🇵||1
-PNG|nation_png|#7A9E86|177|TURTLE|189|0,0,0,0,0,0|🇵🇬||1
-SOM|nation_som|#7AA8B4|107|TURTLE|189|0,0,0,0,0,0|🇸🇴||1
-TCD|nation_tcd|#A8945C|104|TURTLE|189|0,0,0,0,0,0|🇹🇩||1
-ISL|nation_isl|#93A8B4|40|TURTLE|157|0,0,0,0,0,0|🇮🇸|NATO|1
+OMN|nation_omn|#8C9E7A|91|TURTLE|273|0,0,0,0,0,0|🇴🇲||1
+SRB|nation_srb|#8C5C4C|29|TURTLE|273|0,0,0,0,0,0|🇷🇸||1
+SYR|nation_syr|#7A8C5C|85|TURTLE|273|0,0,0,0,0,0|🇸🇾||1
+ECU|nation_ecu|#C7A24E|220|TURTLE|264|0,0,0,0,0,0|🇪🇨||1
+BGR|nation_bgr|#6E8C5C|30|TURTLE|252|0,0,0,0,0,0|🇧🇬|PACT|1
+BOL|nation_bol|#8C9A4C|224|TURTLE|252|0,0,0,0,0,0|🇧🇴||1
+CIV|nation_civ|#C4954C|104|TURTLE|252|0,0,0,0,0,0|🇨🇮||1
+MNG|nation_mng|#B4A05C|76|TURTLE|252|0,0,0,0,0,0|🇲🇳||1
+TUN|nation_tun|#9E5C5C|97|TURTLE|252|0,0,0,0,0,0|🇹🇳||1
+AFG|nation_afg|#8C7A5C|92|TURTLE|231|0,0,0,0,0,0|🇦🇫||1
+GTM|nation_gtm|#57A07E|213|TURTLE|231|0,0,0,0,0,0|🇬🇹||1
+LKA|nation_lka|#B4844C|136|TURTLE|231|0,0,0,0,0,0|🇱🇰||1
+MOZ|nation_moz|#7A9E6E|123|TURTLE|231|0,0,0,0,0,0|🇲🇿||1
+PAN|nation_pan|#4E9E86|214|TURTLE|231|0,0,0,0,0,0|🇵🇦||1
+SEN|nation_sen|#5C9E7A|101|TURTLE|231|0,0,0,0,0,0|🇸🇳||1
+UGA|nation_uga|#7A9E5C|113|TURTLE|231|0,0,0,0,0,0|🇺🇬||1
+URY|nation_ury|#6E9BB0|234|TURTLE|231|0,0,0,0,0,0|🇺🇾||1
+ZMB|nation_zmb|#8C9E5C|118|TURTLE|231|0,0,0,0,0,0|🇿🇲||1
+MLI|nation_mli|#B49A5C|102|TURTLE|220|0,0,0,0,0,0|🇲🇱||1
+DOM|nation_dom|#9E6B58|216|TURTLE|210|0,0,0,0,0,0|🇩🇴||1
+KHM|nation_khm|#7A8C6E|170|TURTLE|210|0,0,0,0,0,0|🇰🇭||1
+MDG|nation_mdg|#8C6E9E|124|TURTLE|210|0,0,0,0,0,0|🇲🇬||1
+PRY|nation_pry|#7F8F5C|235|TURTLE|210|0,0,0,0,0,0|🇵🇾||1
+YEM|nation_yem|#A87A5C|90|TURTLE|210|0,0,0,0,0,0|🇾🇪||1
+ZWE|nation_zwe|#9E8C5C|119|TURTLE|210|0,0,0,0,0,0|🇿🇼||1
+NPL|nation_npl|#A85C5C|137|TURTLE|189|0,0,0,0,0,0|🇳🇵||1
+PNG|nation_png|#7A9E86|181|TURTLE|189|0,0,0,0,0,0|🇵🇬||1
+SOM|nation_som|#7AA8B4|111|TURTLE|189|0,0,0,0,0,0|🇸🇴||1
+TCD|nation_tcd|#A8945C|108|TURTLE|189|0,0,0,0,0,0|🇹🇩||1
+ISL|nation_isl|#93A8B4|44|TURTLE|157|0,0,0,0,0,0|🇮🇸|NATO|1
[relations]
USA RUS WAR
@@ -213,104 +213,104 @@ TUR BGR WAR
TUR DDR WAR
[owners]
-RUS: 39,42-71
-USA: 178-195
-CHN: 134-147
-IND: 121-128
-JPN: 155-159
-DEU: 18-20
-GBR: 0-2,148
-BRA: 229-236
-AUS: 237-244
-FRA: 4-6
-CAN: 196-203
-SAU: 83-84
-IDN: 170-174
-TUR: 73-75
-IRN: 76-78
-ITA: 13-15
-EGY: 89-91
-ZAF: 116-118
-DDR: 17
-MEX: 205-208
-ARG: 224-226
-KOR: 151-152
-ESP: 9-11
-NGA: 102-103
-PAK: 129-130
-POL: 23-24
-TWN: 149-150
-SGP: 169
-THA: 162-163
-DZA: 94-95
-VNM: 164-165
-SWE: 30-33
-ARE: 85
-CHL: 221-223
-COL: 213-214
-IRQ: 79-80
-MYS: 167-168
-PHL: 175-176
-ISR: 82
-COD: 110-111
-NOR: 34,41
-NZL: 245-246
-PER: 218-219
-MAR: 96
-NLD: 8
-VEN: 215
-PRK: 153-154
-CHE: 16
-DNK: 35-36,204
-AUT: 21
-ETH: 106
-FIN: 37-38
-AGO: 112
-BEL: 7
-BGD: 131
-KEN: 108
-LBY: 92
-ROU: 26
-MMR: 160-161
-CZE: 22
-GRC: 29
-HUN: 25
-PRT: 12
-SDN: 105
-TZA: 113
-CUB: 211
-GHA: 101
+RUS: 43,46-75
+USA: 182-199
+CHN: 138-151
+IND: 125-132
+JPN: 159-163
+GBR: 0-2,4,13,152
+DEU: 20-22
+BRA: 236-243
+AUS: 244-251
+FRA: 5-7
+CAN: 200-207
+SAU: 87-88
+IDN: 174-178
+TUR: 77-79
+IRN: 80-82
+ITA: 15-17
+EGY: 93-95
+ZAF: 120-122
+DDR: 19
+ARG: 230-233
+MEX: 209-212
+KOR: 155-156
+ESP: 10-12
+NGA: 106-107
+PAK: 133-134
+POL: 25-26
+TWN: 153-154
+SGP: 173
+THA: 166-167
+CHL: 225-229
+DZA: 98-99
+VNM: 168-169
+SWE: 32-35
+ARE: 89
+COL: 217-218
+IRQ: 83-84
+MYS: 171-172
+PHL: 179-180
+NOR: 36-38,45
+ISR: 86
+COD: 114-115
+NZL: 252-253
+PER: 222-223
+MAR: 100
+NLD: 9
+VEN: 219
+PRK: 157-158
+CHE: 18
+DNK: 39-40,208
+AUT: 23
+ETH: 110
+FIN: 41-42
+AGO: 116
+BEL: 8
+BGD: 135
+KEN: 112
+LBY: 96
+ROU: 28
+MMR: 164-165
+CZE: 24
+GRC: 31
+HUN: 27
+PRT: 14
+SDN: 109
+TZA: 117
+CUB: 215
+GHA: 105
IRL: 3
-OMN: 87
-SRB: 27
-SYR: 81
-ECU: 216-217
-BGR: 28
-BOL: 220
-CIV: 100
-MNG: 72
-TUN: 93
-AFG: 88
-GTM: 209
-LKA: 132
-MOZ: 119
-PAN: 210
-SEN: 97
-UGA: 109
-URY: 227
-ZMB: 114
-MLI: 98-99
-DOM: 212
-KHM: 166
-MDG: 120
-PRY: 228
-YEM: 86
-ZWE: 115
-NPL: 133
-PNG: 177
-SOM: 107
-TCD: 104
-ISL: 40
+OMN: 91
+SRB: 29
+SYR: 85
+ECU: 220-221
+BGR: 30
+BOL: 224
+CIV: 104
+MNG: 76
+TUN: 97
+AFG: 92
+GTM: 213
+LKA: 136
+MOZ: 123
+PAN: 214
+SEN: 101
+UGA: 113
+URY: 234
+ZMB: 118
+MLI: 102-103
+DOM: 216
+KHM: 170
+MDG: 124
+PRY: 235
+YEM: 90
+ZWE: 119
+NPL: 137
+PNG: 181
+SOM: 111
+TCD: 108
+ISL: 44
[units]
GBR|47,17|INFANTRY|1|-
@@ -448,7 +448,7 @@ SGP|94,52|INFANTRY|1|-
IDN|95,56|INFANTRY|1|-
IDN|96,56|ARTILLERY|1|-
PHL|102,45|INFANTRY|1|-
-PHL|103,45|ARTILLERY|1|-
+PHL|103,44|ARTILLERY|1|-
PNG|115,57|INFANTRY|1|-
USA|25,27|INFANTRY|1|-
USA|26,26|ARTILLERY|1|-
@@ -480,6 +480,7 @@ CHL|27,68|INFANTRY|1|-
CHL|28,68|ARTILLERY|1|-
ARG|30,69|INFANTRY|1|-
ARG|30,68|ARTILLERY|1|-
+ARG|29,69|ARMOUR|1|-
URY|31,68|INFANTRY|1|-
PRY|30,65|INFANTRY|1|-
BRA|33,63|INFANTRY|1|-
@@ -495,7 +496,7 @@ AUS|117,68|DESTROYER|1|-
NZL|119,70|INFANTRY|1|-
[playable]
-RUS,USA,DEU,GBR,FRA,CAN,TUR,ITA,DDR,POL,NOR,NLD,DNK,BEL,ROU,CZE,GRC,HUN,PRT,BGR,ISL
+RUS,USA,GBR,DEU,FRA,CAN,TUR,ITA,DDR,POL,NOR,NLD,DNK,BEL,ROU,CZE,GRC,HUN,PRT,BGR,ISL
[objectives]
# 沒有列出目標 = 征服模式的預設條件(拿下地圖上八成的省份)
diff --git a/app/src/main/res/values-b+zh+Hans/strings.xml b/app/src/main/res/values-b+zh+Hans/strings.xml
index 4e781fc..ee7dfef 100644
--- a/app/src/main/res/values-b+zh+Hans/strings.xml
+++ b/app/src/main/res/values-b+zh+Hans/strings.xml
@@ -136,6 +136,7 @@
元帅
苏联
西德
+ 中华人民共和国
二战 · 欧洲
二战 · 太平洋
冷战
@@ -442,6 +443,7 @@
曼彻斯特
爱丁堡
都柏林
+ 贝尔法斯特
巴黎
里昂
波尔多
@@ -450,6 +452,7 @@
马德里
巴塞罗那
塞维利亚
+ 直布罗陀
里斯本
罗马
米兰
@@ -471,8 +474,10 @@
斯德哥尔摩
哥德堡
松兹瓦尔
- 基律纳
+ 吕勒奥
奥斯陆
+ 特隆赫姆
+ 哈默菲斯特
哥本哈根
奥胡斯
赫尔辛基
@@ -661,10 +666,13 @@
拉巴斯
圣地亚哥
安托法加斯塔
+ 特木科
+ 科伊艾克
蓬塔阿雷纳斯
布宜诺斯艾利斯
科尔多瓦
- 巴里洛切
+ 内乌肯
+ 里瓦达维亚海军准将城
蒙得维的亚
亚松森
圣保罗
diff --git a/app/src/main/res/values-b+zh+Hant/strings.xml b/app/src/main/res/values-b+zh+Hant/strings.xml
index 47523cc..46d83eb 100644
--- a/app/src/main/res/values-b+zh+Hant/strings.xml
+++ b/app/src/main/res/values-b+zh+Hant/strings.xml
@@ -136,6 +136,7 @@
元帥
蘇聯
西德
+ 中華人民共和國
二戰 · 歐洲
二戰 · 太平洋
冷戰
@@ -442,6 +443,7 @@
曼徹斯特
愛丁堡
都柏林
+ 貝爾法斯特
巴黎
里昂
波爾多
@@ -450,6 +452,7 @@
馬德里
巴塞隆納
塞維利亞
+ 直布羅陀
里斯本
羅馬
米蘭
@@ -471,8 +474,10 @@
斯德哥爾摩
哥德堡
松茲瓦爾
- 基律納
+ 呂勒奧
奧斯陸
+ 特隆赫姆
+ 哈默菲斯特
哥本哈根
奧胡斯
赫爾辛基
@@ -661,10 +666,13 @@
拉巴斯
聖地牙哥
安托法加斯塔
+ 特木科
+ 科伊艾克
蓬塔阿雷納斯
布宜諾斯艾利斯
科爾多瓦
- 巴里洛切
+ 內烏肯
+ 里瓦達維亞海軍准將城
蒙特維多
亞松森
聖保羅
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index ce892f3..3237502 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -136,6 +136,7 @@
Marshal
Soviet Union
West Germany
+ People\'s Republic of China
WWII · Europe
WWII · Pacific
Cold War
@@ -442,6 +443,7 @@
Manchester
Edinburgh
Dublin
+ Belfast
Paris
Lyon
Bordeaux
@@ -450,6 +452,7 @@
Madrid
Barcelona
Seville
+ Gibraltar
Lisbon
Rome
Milan
@@ -471,8 +474,10 @@
Stockholm
Gothenburg
Sundsvall
- Kiruna
+ Lulea
Oslo
+ Trondheim
+ Hammerfest
Copenhagen
Aarhus
Helsinki
@@ -661,10 +666,13 @@
La Paz
Santiago
Antofagasta
+ Temuco
+ Coyhaique
Punta Arenas
Buenos Aires
Cordoba
- Bariloche
+ Neuquen
+ Comodoro Rivadavia
Montevideo
Asuncion
Sao Paulo
diff --git a/app/src/test/java/io/github/acidefluorhydrique/mapconquer/world/MapAssetTest.kt b/app/src/test/java/io/github/acidefluorhydrique/mapconquer/world/MapAssetTest.kt
index cec40b1..1e0ac29 100644
--- a/app/src/test/java/io/github/acidefluorhydrique/mapconquer/world/MapAssetTest.kt
+++ b/app/src/test/java/io/github/acidefluorhydrique/mapconquer/world/MapAssetTest.kt
@@ -173,7 +173,9 @@ class MapAssetTest {
"prov_miami" to "prov_havana",
"prov_london" to "prov_paris",
"prov_helsinki" to "prov_riga",
- "prov_taipei" to "prov_shanghai"
+ "prov_taipei" to "prov_shanghai",
+ "prov_copenhagen" to "prov_gothenburg",
+ "prov_gibraltar" to "prov_casablanca"
)) {
if (a in byKey && b in byKey) assertFalse("$a 與 $b 之間應該是海", landTouches(a, b))
}
diff --git a/tools/genstrings.py b/tools/genstrings.py
index f8a4278..8c34d45 100644
--- a/tools/genstrings.py
+++ b/tools/genstrings.py
@@ -202,6 +202,7 @@
# AI 性格
"nation_sun": ("Soviet Union", "蘇聯", "苏联"),
"nation_frg": ("West Germany", "西德", "西德"),
+ "nation_prc": ("People's Republic of China", "中華人民共和國", "中华人民共和国"),
"chapter_ww2_europe": ("WWII · Europe", "二戰 · 歐洲", "二战 · 欧洲"),
"chapter_ww2_pacific": ("WWII · Pacific", "二戰 · 太平洋", "二战 · 太平洋"),
diff --git a/tools/genworld.py b/tools/genworld.py
index 9fb4495..dc9940f 100644
--- a/tools/genworld.py
+++ b/tools/genworld.py
@@ -111,13 +111,15 @@ def nearest_land_tile(grid, is_land, lon, lat, allowed=None):
return best, (best_d if best_d is not None else 1e9)
-def assign_provinces(grid, is_land, seeds):
+def assign_provinces(grid, is_land, seeds, no_expand=frozenset()):
"""
多源 BFS:每個陸地格歸給「沿陸地走最近」的那顆種子。
走陸地連通而不是直線距離,是為了讓省界看起來合理 ——
直線 Voronoi 會讓海峽對面的島被劃進大陸的省裡。
孤立的小島(沒有種子可以走到)最後再用直線距離補上。
+
+ [no_expand] 裡的省份只佔種子那一格(見 places.SINGLE_TILE)。
"""
count = grid.cols * grid.rows
owner = [-1] * count
@@ -132,6 +134,8 @@ def assign_provinces(grid, is_land, seeds):
while head < len(frontier):
tile = frontier[head]
head += 1
+ if owner[tile] in no_expand:
+ continue
col, row = tile % grid.cols, tile // grid.cols
for c, r in grid.neighbours(col, row):
j = grid.index(c, r)
@@ -249,7 +253,8 @@ def build_map(map_id, cols, rows, lon_min, lon_max, lat_max, lat_min,
seeds.append(tile)
provinces.append((key, tier, nation, tile))
- province_of = assign_provinces(grid, is_land, seeds)
+ single = frozenset(pid for pid, p in enumerate(provinces) if p[0] in places.SINGLE_TILE)
+ province_of = assign_provinces(grid, is_land, seeds, single)
built = BuiltMap(map_id, grid, terrain, is_land, provinces)
built.province_of = province_of
built.dropped = dropped
@@ -411,9 +416,45 @@ def garrison_lines(built, owners, nation_funds):
return lines
+SEA_KINDS = {"DESTROYER", "CRUISER", "BATTLESHIP", "CARRIER", "SUBMARINE", "TRANSPORT_SHIP"}
+
+
+def placed_units(built, units, taken_lines):
+ """
+ 把指定經緯度的部隊放到最近的空格:軍艦找海,陸軍找陸地。
+
+ 用來擺開局不在自己領土上的部隊(1950 年滇緬邊境的國軍、外海的艦隊)。
+ 已經被守軍佔用的格子從 [taken_lines] 讀出來。
+ """
+ grid = built.grid
+ taken = set()
+ for line in taken_lines:
+ col, row = map(int, line.split("|")[1].split(","))
+ taken.add(grid.index(col, row))
+ out = []
+ for code, lon, lat, kind, level in units:
+ want_water = kind in SEA_KINDS
+ best, best_d = None, None
+ for tile in range(grid.cols * grid.rows):
+ if tile in taken or (built.terrain[tile] in "~-") != want_water:
+ continue
+ if not want_water and tile in (p[3] for p in built.provinces):
+ continue # 不站在別人的城市格上
+ glon, glat = grid.lonlat(tile % grid.cols, tile // grid.cols)
+ d = (glon - lon) ** 2 + (glat - lat) ** 2
+ if best_d is None or d < best_d:
+ best, best_d = tile, d
+ if best is None:
+ raise ValueError("放不下 %s 的 %s" % (code, kind))
+ taken.add(best)
+ out.append("%s|%d,%d|%s|%d|-" % (code, best % grid.cols, best // grid.cols, kind, level))
+ return out
+
+
def write_conquest(built, scenario_id, name_key, desc_key, order, merge,
start_year, turtle=None, blocs=None, overrides=None,
- renames=None, war_turns=None, start_month=None, turn_limit=0):
+ renames=None, war_turns=None, start_month=None, turn_limit=0,
+ extra_units=()):
"""把 places 的國家分佈展開成一份征服劇本。"""
owners = {}
for pid, (key, _tier, nation, _tile) in enumerate(built.provinces):
@@ -482,7 +523,9 @@ def nation_row(code):
lines.append("%s: %s" % (code, compress_ids(owners[code])))
lines.append("")
lines.append("[units]")
- lines.extend(garrison_lines(built, owners, nation_funds))
+ garrison = garrison_lines(built, owners, nation_funds)
+ lines.extend(garrison)
+ lines.extend(placed_units(built, extra_units, garrison))
lines.append("")
lines.append("[playable]")
# 可選國家:有陣營的才能選。中立國不參戰、也沒有敵對陣營可打垮,
@@ -844,7 +887,8 @@ def main():
turtle=unaligned(places.COLD_WAR_1950_BLOCS),
blocs=places.COLD_WAR_1950_BLOCS,
overrides=places.COLD_WAR_1950_PROVINCE_OWNERS,
- renames=places.COLD_WAR_RENAMES, start_month=1))
+ renames=places.COLD_WAR_RENAMES, start_month=1,
+ extra_units=places.COLD_WAR_1950_EXTRA_UNITS))
print(write_conquest(world, "conquest_1980", "scn_conquest_1980",
"scn_conquest_1980_desc", 40, places.COLD_WAR_1980_MERGE, 1980,
turtle=unaligned(places.COLD_WAR_1980_BLOCS),
diff --git a/tools/geodata.py b/tools/geodata.py
index 5858bdd..79cf226 100644
--- a/tools/geodata.py
+++ b/tools/geodata.py
@@ -45,8 +45,8 @@
],
"scandinavia": [
(5.0, 58.5), (11.0, 59.0), (12.5, 56.2), (16.0, 56.0), (19.0, 60.0),
- (21.5, 63.5), (24.0, 65.8), (27.0, 68.5), (31.0, 69.8), (24.0, 71.2), (18.0, 70.0),
- (14.0, 68.0), (11.0, 64.0), (5.0, 62.0), (4.5, 59.5),
+ (21.5, 63.5), (24.0, 65.8), (27.0, 68.5), (31.0, 69.8), (29.0, 71.3), (24.0, 71.4),
+ (19.0, 71.3), (16.0, 69.8), (14.0, 68.0), (11.0, 64.0), (5.0, 62.0), (4.5, 59.5),
],
# 日德蘭半島原本也沒有多邊形:europe 的北岸停在北緯 54.5,丹麥只剩
# 城市錨點那一格,跟德國之間隔著一排海。
@@ -55,6 +55,12 @@
(10.9, 56.4), (10.3, 56.9), (10.6, 57.7), (10.0, 57.6), (8.6, 57.1),
(8.1, 56.6), (8.1, 55.5), (8.6, 54.9),
],
+ # 西蘭島(哥本哈根)。跟日德蘭相連(大貝爾特海峽在這個尺度下等於沒有),
+ # 但跟瑞典之間的厄勒海峽要留著,見 SEAS。
+ "zealand": [
+ (10.9, 55.7), (11.0, 55.2), (12.6, 55.0), (12.8, 55.7), (12.6, 56.1),
+ (11.8, 56.0),
+ ],
# 芬蘭原本沒有自己的多邊形:斯堪地那維亞的東緣沿著波的尼亞灣往北走,
# europe 的西緣從聖彼得堡往北走,兩者之間北緯 60–67、東經 21–29 整片是
# 空白 —— 芬蘭本土柵格化出來是海,赫爾辛基只剩錨點那一格,其餘的地被
@@ -70,7 +76,8 @@
(86.0, 74.5), (100.0, 76.0), (110.0, 76.5), (113.0, 73.5), (129.0, 73.5),
(140.0, 72.5), (150.0, 70.0), (160.0, 70.0), (170.0, 68.5), (179.0, 65.5),
(179.0, 62.0), (170.0, 60.5), (162.0, 60.0), (158.0, 57.0), (155.0, 52.0),
- (142.0, 49.0), (135.0, 48.0), (130.0, 44.0), (127.0, 45.5), (120.0, 50.0),
+ (141.0, 52.0), (140.5, 48.5), (138.5, 46.5), (135.5, 43.8), (132.5, 42.8),
+ (130.7, 42.4), (127.0, 45.5), (120.0, 50.0),
(115.0, 50.0), (107.0, 50.0), (98.0, 51.0), (90.0, 50.0), (85.0, 49.5),
(80.0, 50.5), (72.0, 54.0), (65.0, 55.0), (60.0, 58.0), (58.0, 62.0),
],
@@ -247,9 +254,19 @@
(121.0, 25.2), (121.9, 25.0), (121.9, 24.4), (121.3, 23.0),
(120.9, 21.9), (120.2, 22.6), (120.1, 23.6), (120.7, 24.5),
],
- "philippines": [
- (120.0, 18.5), (124.0, 18.0), (126.0, 14.0), (126.5, 7.0), (122.0, 5.5),
- (120.0, 9.0), (120.0, 13.5),
+ # 菲律賓原本是一整塊從東經 120 到 126.5 的多邊形,把錫布延海也算成陸地,
+ # 在東亞加寬過的經度上柵格化出四格寬的方塊。拆成三大島群。
+ "luzon": [
+ (120.0, 18.5), (122.3, 18.5), (122.2, 16.5), (121.6, 15.8), (122.0, 14.2),
+ (124.0, 13.0), (123.5, 12.6), (121.8, 13.8), (120.6, 13.9), (120.0, 15.5),
+ ],
+ "visayas": [
+ (121.9, 11.8), (124.0, 12.5), (125.7, 11.5), (125.3, 10.0), (123.8, 9.6),
+ (122.4, 9.3), (122.0, 10.6),
+ ],
+ "mindanao": [
+ (122.0, 7.5), (123.5, 8.6), (125.0, 9.8), (126.3, 9.0), (126.6, 7.0),
+ (125.5, 5.6), (124.0, 6.5), (122.2, 6.8),
],
"sumatra": [(95.5, 5.5), (99.0, 4.0), (104.0, -2.0), (106.0, -6.0), (103.0, -5.5), (100.0, -2.0)],
"java": [(105.1, -5.9), (110.4, -6.4), (114.4, -7.7), (114.6, -8.8),
@@ -286,7 +303,7 @@
"japan": ["japan_honshu", "japan_kyushu", "japan_shikoku"],
"sakhalin": ["sakhalin"],
"taiwan": ["taiwan"],
- "philippines": ["philippines"],
+ "philippines": ["luzon", "visayas", "mindanao"],
"sumatra": ["sumatra"],
"java": ["java"],
"borneo": ["borneo"],
@@ -310,6 +327,12 @@
# 跟南亞之間隔著阿拉伯海。這些海在網格上往往只有零到一格寬,城市格
# 一貼過去就成了陸橋 —— 葉門的省長到索馬利亞、阿曼的省長到巴基斯坦。
SEAS = [
+ # 厄勒海峽與卡特加特:丹麥跟瑞典之間是海,哥本哈根的城市格不能是陸橋。
+ ("jutland", "scandinavia"),
+ ("zealand", "scandinavia"),
+ # 直布羅陀:伊比利亞跟摩洛哥之間,直布羅陀城本身就站在海峽口上。
+ ("europe", "africa"),
+ ("sicily", "africa"),
("arabia", "africa"),
("arabia", "sinai"),
("arabia", "iran"),
@@ -329,7 +352,8 @@
STRAITS = {
"english_channel": [(-6.0, 50.0), (-3.0, 50.2), (0.0, 50.4), (2.4, 50.8)],
"irish_sea": [(-6.6, 52.0), (-5.7, 53.8), (-5.3, 55.4)],
- "gibraltar": [(-7.6, 35.9), (-5.6, 35.9), (-3.0, 36.0)],
+ # 畫在海峽的南半邊:直布羅陀城要站在伊比利亞這一側的那一排格子上。
+ "gibraltar": [(-7.6, 35.6), (-5.6, 35.6), (-3.0, 35.7)],
"danish_straits": [(7.0, 57.6), (10.0, 57.4), (12.6, 55.8), (14.6, 55.2)],
"turkish_straits": [(25.8, 39.9), (27.2, 40.4), (28.6, 40.6), (29.4, 41.2)],
# 芬蘭灣:赫爾辛基與塔林只差不到一度緯度,多邊形在這個尺度下留不住海。
diff --git a/tools/places.py b/tools/places.py
index 63f6fb9..b1346d7 100644
--- a/tools/places.py
+++ b/tools/places.py
@@ -13,12 +13,17 @@
城市等級:0 = 無城、1 = 城鎮、2 = 城市、3 = 大城、4 = 核心城市。
"""
+# 只佔一格的省份:據點,不是一片領土。香港、直布羅陀、北愛爾蘭的面積在這張
+# 地圖上連一格都不到,照一般省份從城市往外長,會吃掉鄰國一大塊地。
+SINGLE_TILE = {"prov_hong_kong", "prov_gibraltar", "prov_belfast"}
+
PROVINCES = [
# ---- 西歐 ----
("prov_london", -0.1, 51.5, 4, "GBR", "London", "倫敦", "伦敦"),
("prov_manchester", -2.2, 53.5, 2, "GBR", "Manchester", "曼徹斯特", "曼彻斯特"),
("prov_edinburgh", -3.2, 55.9, 2, "GBR", "Edinburgh", "愛丁堡", "爱丁堡"),
("prov_dublin", -6.3, 53.3, 2, "IRL", "Dublin", "都柏林", "都柏林"),
+ ("prov_belfast", -5.9, 54.6, 1, "GBR", "Belfast", "貝爾法斯特", "贝尔法斯特"),
("prov_paris", 2.35, 48.9, 4, "FRA", "Paris", "巴黎", "巴黎"),
("prov_lyon", 4.8, 45.8, 2, "FRA", "Lyon", "里昂", "里昂"),
("prov_bordeaux", -0.6, 44.8, 2, "FRA", "Bordeaux", "波爾多", "波尔多"),
@@ -27,6 +32,7 @@
("prov_madrid", -3.7, 40.4, 3, "ESP", "Madrid", "馬德里", "马德里"),
("prov_barcelona", 2.2, 41.4, 2, "ESP", "Barcelona", "巴塞隆納", "巴塞罗那"),
("prov_seville", -6.0, 37.4, 2, "ESP", "Seville", "塞維利亞", "塞维利亚"),
+ ("prov_gibraltar", -5.35, 36.1, 1, "GBR", "Gibraltar", "直布羅陀", "直布罗陀"),
("prov_lisbon", -9.1, 38.7, 2, "PRT", "Lisbon", "里斯本", "里斯本"),
("prov_rome", 12.5, 41.9, 3, "ITA", "Rome", "羅馬", "罗马"),
("prov_milan", 9.2, 45.5, 3, "ITA", "Milan", "米蘭", "米兰"),
@@ -50,8 +56,10 @@
("prov_stockholm", 18.1, 59.3, 2, "SWE", "Stockholm", "斯德哥爾摩", "斯德哥尔摩"),
("prov_gothenburg", 12.0, 57.7, 1, "SWE", "Gothenburg", "哥德堡", "哥德堡"),
("prov_sundsvall", 17.3, 62.4, 1, "SWE", "Sundsvall", "松茲瓦爾", "松兹瓦尔"),
- ("prov_kiruna", 20.2, 67.9, 1, "SWE", "Kiruna", "基律納", "基律纳"),
+ ("prov_lulea", 22.15, 65.6, 1, "SWE", "Lulea", "呂勒奧", "吕勒奥"),
("prov_oslo", 10.7, 59.9, 2, "NOR", "Oslo", "奧斯陸", "奥斯陆"),
+ ("prov_trondheim", 10.4, 63.4, 1, "NOR", "Trondheim", "特隆赫姆", "特隆赫姆"),
+ ("prov_hammerfest", 23.7, 70.7, 1, "NOR", "Hammerfest", "哈默菲斯特", "哈默菲斯特"),
("prov_copenhagen", 12.6, 55.7, 2, "DNK", "Copenhagen", "哥本哈根", "哥本哈根"),
("prov_aarhus", 10.2, 56.2, 1, "DNK", "Aarhus", "奧胡斯", "奥胡斯"),
("prov_helsinki", 25.0, 60.2, 2, "FIN", "Helsinki", "赫爾辛基", "赫尔辛基"),
@@ -258,10 +266,13 @@
("prov_la_paz", -68.1, -16.5, 1, "BOL", "La Paz", "拉巴斯", "拉巴斯"),
("prov_santiago", -70.7, -33.4, 3, "CHL", "Santiago", "聖地牙哥", "圣地亚哥"),
("prov_antofagasta", -70.4, -23.6, 1, "CHL", "Antofagasta", "安托法加斯塔", "安托法加斯塔"),
+ ("prov_temuco", -72.6, -38.7, 1, "CHL", "Temuco", "特木科", "特木科"),
+ ("prov_coyhaique", -72.1, -45.6, 1, "CHL", "Coyhaique", "科伊艾克", "科伊艾克"),
("prov_punta_arenas", -70.9, -53.2, 1, "CHL", "Punta Arenas", "蓬塔阿雷納斯", "蓬塔阿雷纳斯"),
("prov_buenos_aires", -58.4, -34.6, 4, "ARG", "Buenos Aires", "布宜諾斯艾利斯", "布宜诺斯艾利斯"),
("prov_cordoba_ar", -64.2, -31.4, 2, "ARG", "Cordoba", "科爾多瓦", "科尔多瓦"),
- ("prov_bariloche", -71.3, -41.1, 1, "ARG", "Bariloche", "巴里洛切", "巴里洛切"),
+ ("prov_neuquen", -68.1, -39.0, 1, "ARG", "Neuquen", "內烏肯", "内乌肯"),
+ ("prov_comodoro", -67.5, -45.9, 1, "ARG", "Comodoro Rivadavia", "里瓦達維亞海軍准將城", "里瓦达维亚海军准将城"),
("prov_montevideo", -56.2, -34.9, 1, "URY", "Montevideo", "蒙特維多", "蒙得维的亚"),
("prov_asuncion", -57.6, -25.3, 1, "PRY", "Asuncion", "亞松森", "亚松森"),
("prov_sao_paulo", -46.6, -23.5, 4, "BRA", "Sao Paulo", "聖保羅", "圣保罗"),
@@ -435,8 +446,9 @@
"GRL": "DNK", "ISL": "DNK",
"PNG": "AUS", # 1939 年是澳洲代管地,不是 1914 年以前的德屬新幾內亞。
- # 美國:菲律賓與加勒比。
- "PHL": "USA", "CUB": "USA", "DOM": "USA", "PAN": "USA",
+ # 美國:菲律賓(自治邦)。古巴、多明尼加、巴拿馬是獨立國家,
+ # 開戰時中立,不併進美國(見 WW2_NEUTRALS)。
+ "PHL": "USA",
# 日本:朝鮮與臺灣是併入的領土。
"KOR": "JPN", "PRK": "JPN", "TWN": "JPN",
@@ -488,6 +500,9 @@
# 顯示用的翻譯鍵。蘇聯沒有對應的 emoji 國旗,暫時沿用 🇷🇺。
WW2_RENAMES = {
"RUS": "nation_sun",
+ # 二戰時的中國就是中華民國,國旗 🇹🇼,名字直接叫「中國」。
+ # 冷戰年代才分成中華人民共和國與中華民國(見 COLD_WAR_RENAMES)。
+ "ROC": "nation_chn",
}
# 1939 年不參戰的國家。它們有城市、有守軍、也擋在路上,但 AI 走 TURTLE:
@@ -496,7 +511,9 @@
WW2_NEUTRALS = {
"CHE", "SWE", "PRT", "ESP", "IRL", "TUR", "IRN", "AFG", "SAU",
"BRA", "ARG", "CHL", "COL", "PER", "VEN", "ECU", "BOL", "PRY", "URY",
- "GTM", "MEX",
+ "GTM", "MEX", "CUB", "DOM", "PAN",
+ # 1943 年的衣索比亞是獨立國家(1941 年光復),不列入同盟陣營。
+ "ETH",
}
@@ -510,7 +527,7 @@
# 德國:法國全境(1942 年 11 月之後)、低地國、北歐、波蘭、巴爾幹、蘇聯西部
"prov_paris": "DEU", "prov_lyon": "DEU", "prov_bordeaux": "DEU",
"prov_amsterdam": "DEU", "prov_brussels": "DEU", "prov_copenhagen": "DEU", "prov_aarhus": "DEU",
- "prov_oslo": "DEU", "prov_narvik": "DEU",
+ "prov_oslo": "DEU", "prov_narvik": "DEU", "prov_trondheim": "DEU", "prov_hammerfest": "DEU",
"prov_warsaw": "DEU", "prov_krakow": "DEU",
"prov_belgrade": "DEU", "prov_athens": "DEU",
"prov_riga": "DEU", "prov_minsk": "DEU", "prov_kyiv": "DEU", "prov_kharkiv": "DEU",
@@ -532,12 +549,12 @@
})
# 芬蘭(繼續戰爭)、羅馬尼亞、匈牙利、保加利亞、泰國都是實際跟軸心並肩作戰的。
-# 西班牙與土耳其不是 —— 別的遊戲把西班牙排進軸心,那不對。衣索比亞在 1942 年
-# 底對軸心宣戰。巴西與墨西哥雖然也宣戰了,但在棋盤上跟中立沒有差別,
-# 放進同盟只會讓軸心玩家必須去滅掉它們才算贏。
+# 西班牙與土耳其不是 —— 別的遊戲把西班牙排進軸心,那不對。衣索比亞、巴西、
+# 墨西哥雖然也在 1942 年宣戰了,但在棋盤上跟中立沒有差別,放進同盟只會讓
+# 軸心玩家必須去滅掉它們才算贏。
WW2_1943_BLOCS = {
"AXIS": ["DEU", "ITA", "JPN", "FIN", "ROU", "HUN", "BGR", "THA"],
- "ALLIES": ["GBR", "USA", "RUS", "ROC", "FRA", "CAN", "AUS", "NZL", "ETH"],
+ "ALLIES": ["GBR", "USA", "RUS", "ROC", "FRA", "CAN", "AUS", "NZL"],
}
# ----------------------------------------------------------------------
@@ -605,13 +622,26 @@
"PACT": ["RUS", "POL", "CZE", "HUN", "ROU", "BGR", "DDR"],
}
-# 冷戰年代的名字:蘇聯、西德、在臺灣的中華民國。
+# 冷戰年代的名字:蘇聯、西德、中華人民共和國、在臺灣的中華民國。
COLD_WAR_RENAMES = {
"RUS": "nation_sun",
"DEU": "nation_frg",
+ "CHN": "nation_prc",
"TWN": "nation_roc",
}
+# 1950 年開局時中華民國在大陸以外的殘部:滇緬邊境的孤軍、昆明附近的部隊、
+# 上海與福建外海的艦隊。(國家, 經度, 緯度, 兵種, 等級),產生器會找最近的
+# 空格(陸軍找陸地、軍艦找海)。
+COLD_WAR_1950_EXTRA_UNITS = [
+ ("TWN", 99.0, 21.5, "INFANTRY", 2), # 緬甸撣邦,滇緬邊境
+ ("TWN", 98.0, 22.8, "INFANTRY", 1),
+ ("TWN", 103.5, 24.2, "INFANTRY", 1), # 昆明東南
+ ("TWN", 122.8, 30.8, "DESTROYER", 1), # 上海外海(舟山)
+ ("TWN", 120.5, 25.8, "DESTROYER", 1), # 福建外海
+ ("TWN", 119.8, 24.8, "CRUISER", 1),
+]
+
# 合併後才出現的新勢力,需要自己的名字。
EXTRA_NATIONS = {
diff --git a/tools/scenarios.py b/tools/scenarios.py
index 9365c58..40833e8 100644
--- a/tools/scenarios.py
+++ b/tools/scenarios.py
@@ -88,7 +88,8 @@
"forces": {
"DEU": ["prov_berlin", "prov_hamburg", "prov_munich", "prov_cologne"],
"FRA": ["prov_paris", "prov_lyon", "prov_bordeaux"],
- "GBR": ["prov_london", "prov_manchester", "prov_edinburgh"],
+ "GBR": ["prov_london", "prov_manchester", "prov_edinburgh", "prov_belfast",
+ "prov_gibraltar"],
"BEL": ["prov_brussels"],
"NLD": ["prov_amsterdam"],
"CHE": ["prov_zurich"],
@@ -125,7 +126,8 @@
"turn_limit": 35,
"stars": (20, 28),
"forces": {
- "GBR": ["prov_cairo", "prov_alexandria", "prov_aswan", "prov_khartoum"],
+ "GBR": ["prov_cairo", "prov_alexandria", "prov_aswan", "prov_khartoum",
+ "prov_gibraltar"],
"ITA": ["prov_tripoli"],
"DEU": ["prov_tunis"],
"TUR": ["prov_ankara", "prov_izmir"],
@@ -303,7 +305,8 @@
# 柏林在東德。原本整省算西德的,那是在沒有東德可用的時候將就的。
"DEU": ["prov_hamburg", "prov_munich", "prov_cologne"],
"FRA": ["prov_paris", "prov_lyon", "prov_bordeaux"],
- "GBR": ["prov_london", "prov_manchester", "prov_edinburgh"],
+ "GBR": ["prov_london", "prov_manchester", "prov_edinburgh", "prov_belfast",
+ "prov_gibraltar"],
"NLD": ["prov_amsterdam"],
"BEL": ["prov_brussels"],
"DNK": ["prov_copenhagen", "prov_aarhus"],
diff --git a/tools/topology.py b/tools/topology.py
index 48b8254..f7fb8a2 100644
--- a/tools/topology.py
+++ b/tools/topology.py
@@ -24,6 +24,10 @@
LAND_BORDERS = [
# 北歐:芬蘭夾在瑞典與俄羅斯之間,不是一塊浮在波羅的海上的地。
("FIN", "SWE"), ("FIN", "RUS"), ("NOR", "SWE"),
+ # 北愛爾蘭:愛爾蘭島上唯一的陸上國界。
+ ("GBR", "IRL"),
+ # 直布羅陀
+ ("GBR", "ESP"),
# 西歐與中歐
("ESP", "FRA"), ("ESP", "PRT"), ("FRA", "BEL"), ("FRA", "DEU"),
("FRA", "CHE"), ("FRA", "ITA"), ("DEU", "POL"), ("DEU", "NLD"),
@@ -45,16 +49,16 @@
SEA_BETWEEN = [
# 島國對大陸
- ("GBR", "FRA"), ("GBR", "IRL"), ("GBR", "BEL"), ("GBR", "NLD"),
+ ("GBR", "FRA"), ("GBR", "BEL"), ("GBR", "NLD"),
("JPN", "KOR"), ("JPN", "PRK"), ("JPN", "CHN"), ("JPN", "RUS"),
("TWN", "CHN"), ("LKA", "IND"), ("CUB", "USA"), ("MDG", "MOZ"),
("AUS", "IDN"), ("AUS", "PNG"), ("NZL", "AUS"), ("PHL", "CHN"),
("PHL", "MYS"), ("ISL", "GBR"), ("ISL", "NOR"),
# 波羅的海與北海:芬蘭灣、波的尼亞灣、斯卡格拉克。
("FIN", "LVA"), ("FIN", "BLR"), ("SWE", "LVA"), ("SWE", "POL"),
- ("SWE", "DEU"), ("NOR", "DNK"),
+ ("SWE", "DEU"), ("NOR", "DNK"), ("DNK", "SWE"),
# 地中海
- ("ITA", "TUN"), ("ITA", "LBY"), ("ESP", "MAR"), ("GRC", "EGY"),
+ ("ITA", "TUN"), ("ITA", "LBY"), ("ESP", "MAR"), ("GBR", "MAR"), ("GRC", "EGY"),
("GRC", "LBY"), ("TUR", "EGY"), ("SYR", "EGY"),
# 紅海、曼德海峽、荷莫茲、阿拉伯海
("SAU", "SDN"), ("SAU", "EGY"), ("YEM", "ETH"), ("YEM", "SOM"),
@@ -62,6 +66,10 @@
("SAU", "IRN"),
]
+# 本土必須連成一片的國家(不含離島)。挪威曾經被瑞典的省從中間切斷:
+# 松茲瓦爾一路長到大西洋岸,奧斯陸與納爾維克之間沒有陸路。
+CONTIGUOUS = ["NOR", "SWE", "FIN", "DNK", "CHL", "VNM", "KOR", "PRK", "ESP", "FRA", "DEU", "POL"]
+
def _neighbours(grid, tile, wrap):
col, row = tile % grid.cols, tile // grid.cols
@@ -111,4 +119,26 @@ def touching(a, b):
for a, b in SEA_BETWEEN:
if a in present and b in present and touching(a, b):
errors.append("%s 與 %s 之間應該隔著海,地圖上卻陸地相鄰" % (a, b))
+ for code in CONTIGUOUS:
+ pieces = _land_pieces(built, code, wrap)
+ if pieces > 1:
+ errors.append("%s 的國土被切成 %d 塊" % (code, pieces))
return errors
+
+
+def _land_pieces(built, code, wrap):
+ """[code] 的陸地格分成幾個連通塊。"""
+ nation = [p[2] for p in built.provinces]
+ tiles = {t for t, land in enumerate(built.is_land)
+ if land and nation[built.province_of[t]] == code}
+ pieces = 0
+ while tiles:
+ pieces += 1
+ stack = [tiles.pop()]
+ while stack:
+ t = stack.pop()
+ for n in _neighbours(built.grid, t, wrap):
+ if n in tiles:
+ tiles.remove(n)
+ stack.append(n)
+ return pieces
From 0ded018d634b1a12b4ee11316f6594fe16ff8f2d Mon Sep 17 00:00:00 2001
From: AcideFluorhydrique
<139669368+AcideFluorhydrique@users.noreply.github.com>
Date: Tue, 22 Sep 2026 18:03:53 +0800
Subject: [PATCH 06/11] Let the player move first in every round
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
A new game made the player watch every nation ahead of them in the
scenario file move first — in conquest that is dozens of AI turns before
the first click, because the file lists nations by strength. The reference
game starts on the player's turn and the AI moves after it.
Session now puts the player at the front of the nation list and keeps the
scenario's order for everyone else, so every round starts with the player.
Nation ids shift with that, so the save format goes to version 2 and older
saves are refused as outdated. docs/original-behavior.md records the turn
order.
---
.../mapconquer/game/SaveGame.kt | 9 +++++-
.../mapconquer/game/Session.kt | 6 +++-
.../mapconquer/game/SessionTest.kt | 12 ++++++++
docs/original-behavior.md | 30 ++++++++++++++++++-
4 files changed, 54 insertions(+), 3 deletions(-)
diff --git a/app/src/main/java/io/github/acidefluorhydrique/mapconquer/game/SaveGame.kt b/app/src/main/java/io/github/acidefluorhydrique/mapconquer/game/SaveGame.kt
index 45da402..9af08f5 100644
--- a/app/src/main/java/io/github/acidefluorhydrique/mapconquer/game/SaveGame.kt
+++ b/app/src/main/java/io/github/acidefluorhydrique/mapconquer/game/SaveGame.kt
@@ -25,7 +25,11 @@ import java.io.File
object SaveGame {
private const val FILE_NAME = "session.save"
- private const val VERSION = 1
+ /**
+ * 存檔格式版本。規則改變了索引的意義時要加一,舊版存檔會被當成過時拒絕:
+ * 2 = 國家順序改成玩家第一(國家 id 全部位移)。
+ */
+ private const val VERSION = 2
/** 讀檔的結果。存檔舊了跟存檔壞了是兩回事,玩家該看到不同的說明。 */
sealed class Restore {
@@ -158,6 +162,7 @@ object SaveGame {
val lines = file(context).readLines()
if (lines.isEmpty()) return Restore.Broken
+ var version = 0
var scenarioId = ""
var mapPrint = ""
var playerCode = ""
@@ -179,6 +184,7 @@ object SaveGame {
val key = line.substring(0, sep)
val value = line.substring(sep + 1).trim()
when (key) {
+ "v" -> version = value.toIntOrNull() ?: 0
"scenario" -> scenarioId = value
"map" -> mapPrint = value
"player" -> playerCode = value
@@ -197,6 +203,7 @@ object SaveGame {
}
}
if (scenarioId.isEmpty()) return Restore.Broken
+ if (version != VERSION) return Restore.Outdated
val scenario = ScenarioLoader.load(context, scenarioId)
val map = MapLoader.load(context, scenario.mapId)
diff --git a/app/src/main/java/io/github/acidefluorhydrique/mapconquer/game/Session.kt b/app/src/main/java/io/github/acidefluorhydrique/mapconquer/game/Session.kt
index 760405e..6f7feef 100644
--- a/app/src/main/java/io/github/acidefluorhydrique/mapconquer/game/Session.kt
+++ b/app/src/main/java/io/github/acidefluorhydrique/mapconquer/game/Session.kt
@@ -99,7 +99,11 @@ class Session(
init {
val built = ArrayList(scenario.nations.size)
- scenario.nations.forEachIndexed { index, sn ->
+ // 玩家永遠排第一:每一輪由玩家先動,AI 在玩家結束回合之後才依序行動。
+ // 劇本檔的順序(依國力排)只決定 AI 之間的先後。開新局時不該先看著
+ // 一百多個 AI 跑完一輪才輪到自己。
+ val order = scenario.nations.sortedBy { if (it.code == playerCode) 0 else 1 }
+ order.forEachIndexed { index, sn ->
val nation = Nation(
index, sn.code, sn.nameKey, sn.colour,
sn.aiProfile, sn.capitalProvince, sn.flag, sn.bloc, sn.warTurn
diff --git a/app/src/test/java/io/github/acidefluorhydrique/mapconquer/game/SessionTest.kt b/app/src/test/java/io/github/acidefluorhydrique/mapconquer/game/SessionTest.kt
index 4a628e9..af2e7b9 100644
--- a/app/src/test/java/io/github/acidefluorhydrique/mapconquer/game/SessionTest.kt
+++ b/app/src/test/java/io/github/acidefluorhydrique/mapconquer/game/SessionTest.kt
@@ -874,6 +874,18 @@ class SessionTest {
assertEquals(SessionStatus.PLAYING, s.status)
}
+ @Test
+ fun `a new game starts on the player's turn, before any AI moves`() {
+ val scenario = TestAssets.scenario("conquest_1939")
+ val map = TestAssets.cachedMap(scenario.mapId)
+ // 挑劇本檔裡排得最後面的可選國家:原本它要等前面所有 AI 跑完才輪到。
+ val code = scenario.playable.last()
+ val s = Session(map, scenario, Difficulty.OFFICER, code, 1L)
+ assertEquals(code, s.playerNation.code)
+ assertEquals(1, s.turn)
+ assertTrue("開局第一個行動的就是玩家", s.isPlayerTurn)
+ }
+
@Test
fun `losing everything ends the game`() {
val s = session(
diff --git a/docs/original-behavior.md b/docs/original-behavior.md
index a5dd4ac..8fc62f6 100644
--- a/docs/original-behavior.md
+++ b/docs/original-behavior.md
@@ -152,7 +152,35 @@ enemies(P) = 與玩家 P 分屬敵對陣營的國家 ∪ 目前與 P 交戰中
---
-## 4. 待研究
+## 4. 回合順序
+
+### 觀察到的行為
+
+| 行為 | 來源 | 狀態 |
+|---|---|---|
+| 開新局時由玩家先行動,AI 在玩家結束回合之後才行動 | 觀察 | ✅ |
+
+### 規格
+
+```text
+每一輪:玩家 → 其他國家依序 → 回合數 +1 → 玩家 → …
+第 1 回合開局時,任何 AI 都還沒有行動過。
+```
+
+### 本專案
+
+- `Session` 建立時把玩家排在國家清單的第一位,其餘國家維持劇本檔的順序
+ (依國力排),所以一輪總是從玩家開始。
+- 國家 id 因此跟著玩家改變,存檔格式版本升到 2,舊版存檔視為過時。
+- 測試:`SessionTest` 的 ``a new game starts on the player's turn, before any AI moves``。
+
+### UNKNOWN BEHAVIOR
+
+1. **AI 國家之間的先後順序。** 本專案依國力由強到弱。原版未觀察。
+
+---
+
+## 5. 待研究
以下行為會影響後續的實作,但目前沒有足夠證據,先列出來:
From 9eef5057162b795f31879282983f2a7fd0bb2ed5 Mon Sep 17 00:00:00 2001
From: AcideFluorhydrique
<139669368+AcideFluorhydrique@users.noreply.github.com>
Date: Tue, 22 Sep 2026 18:03:54 +0800
Subject: [PATCH 07/11] Sign CI debug builds with one shared key
Every fresh runner generated its own debug keystore, so each CI debug APK
had a different signature and could not be installed over the previous
one. The workflow now restores a fixed keystore from the DEBUG_KEYSTORE
secret (base64) to the path the Android build tools read by default, so
the Gradle files stay unchanged and no key is committed. Without the
secret, as on pull requests from forks, it warns and falls back to a
random key. Release builds are untouched; F-Droid signs those itself.
---
.github/workflows/build.yml | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index d559df3..58b0d4d 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -65,6 +65,23 @@ jobs:
app/build/reports/lint-results-debug.xml
if-no-files-found: warn
+ # 沒有這一步,每台全新的 runner 都會自己產生一把 debug keystore,
+ # 每次產出的 debug APK 簽名都不一樣,裝在手機上的版本永遠無法覆蓋更新。
+ # 固定的那一把以 base64 存在 repo secret DEBUG_KEYSTORE,還原到 Android
+ # 建置工具預設讀取的位置,Gradle 設定不必動。這把只簽 debug 版;
+ # F-Droid 的 release 由 F-Droid 自己簽。來自 fork 的 PR 拿不到 secret,
+ # 會退回隨機金鑰並留一則警告,不讓建置失敗。
+ - name: Restore the shared debug keystore
+ env:
+ DEBUG_KEYSTORE: ${{ secrets.DEBUG_KEYSTORE }}
+ run: |
+ if [ -n "$DEBUG_KEYSTORE" ]; then
+ mkdir -p ~/.android
+ echo "$DEBUG_KEYSTORE" | base64 -d > ~/.android/debug.keystore
+ else
+ echo "::warning::DEBUG_KEYSTORE secret 沒有設定,debug APK 會用隨機金鑰簽名,無法覆蓋更新。"
+ fi
+
- name: Build debug APK
run: ./gradlew assembleDebug --stacktrace
From 7be465ca97cf1352e334baed32aae982e8f90bc5 Mon Sep 17 00:00:00 2001
From: AcideFluorhydrique
<139669368+AcideFluorhydrique@users.noreply.github.com>
Date: Tue, 22 Sep 2026 19:42:33 +0800
Subject: [PATCH 08/11] Sign release builds in CI with the project key, and
check reproducibility
The shared debug key from the previous commit is dropped: phones get the
release build. CI still builds the release APK without any signing config,
so the unsigned artifact is what F-Droid will build from source, and then
signs it with apksigner using the RELEASE_KEYSTORE secret (base64) and its
password and alias secrets. The keystore exists only in the runner's temp
directory for that one step. The certificate fingerprint is printed for
F-Droid's AllowedAPKSigningKeys. Without the secrets, as on pull requests
from forks, the job warns and ships only the unsigned APK.
The debug APK is no longer built or uploaded; nobody installs it and its
random per-runner key made it impossible to update anyway.
A new reproducible job builds the release twice, from the checkout and
from a second worktree at another path with the build cache off, and fails
unless the two APKs are byte-identical. F-Droid only publishes the
developer-signed APK when its own build matches, so this catches
timestamps, absolute paths and unstable ordering before a release does.
---
.github/workflows/build.yml | 108 ++++++++++++++++++++++++++----------
1 file changed, 79 insertions(+), 29 deletions(-)
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 58b0d4d..d909a3e 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -65,44 +65,94 @@ jobs:
app/build/reports/lint-results-debug.xml
if-no-files-found: warn
- # 沒有這一步,每台全新的 runner 都會自己產生一把 debug keystore,
- # 每次產出的 debug APK 簽名都不一樣,裝在手機上的版本永遠無法覆蓋更新。
- # 固定的那一把以 base64 存在 repo secret DEBUG_KEYSTORE,還原到 Android
- # 建置工具預設讀取的位置,Gradle 設定不必動。這把只簽 debug 版;
- # F-Droid 的 release 由 F-Droid 自己簽。來自 fork 的 PR 拿不到 secret,
- # 會退回隨機金鑰並留一則警告,不讓建置失敗。
- - name: Restore the shared debug keystore
+ # F-Droid 建的是 release variant,這裡也走同一條路徑。Gradle 沒有簽章設定,
+ # 產出的是未簽章的 APK —— 跟 F-Droid 從原始碼建出來的應該位元相同,
+ # 這是 reproducible build 的前提(見下面的 reproducible job)。
+ - name: Build release APK
+ run: ./gradlew assembleRelease --stacktrace
+
+ - name: Upload unsigned release APK
+ uses: actions/upload-artifact@v5
+ with:
+ name: mapconquer-release-unsigned
+ path: app/build/outputs/apk/release/app-release-unsigned.apk
+ if-no-files-found: error
+
+ # 用正式金鑰簽名。簽名刻意不放進 Gradle:建置產物保持跟 F-Droid 的一致,
+ # 簽名是建置之後的一步,F-Droid 比對時把這份的簽章複製到它自己建的 APK 上
+ # 驗證即可。
+ #
+ # 金鑰以 base64 存在 repo secret RELEASE_KEYSTORE,密碼與別名另外三個
+ # secret。keystore 只在這一步寫進 runner 的暫存目錄,簽完立刻刪除。
+ # 拿不到 secret 的情況(來自 fork 的 PR)只留警告,不讓建置失敗。
+ - name: Sign release APK
+ id: sign
env:
- DEBUG_KEYSTORE: ${{ secrets.DEBUG_KEYSTORE }}
+ RELEASE_KEYSTORE: ${{ secrets.RELEASE_KEYSTORE }}
+ RELEASE_KEYSTORE_PASSWORD: ${{ secrets.RELEASE_KEYSTORE_PASSWORD }}
+ RELEASE_KEY_ALIAS: ${{ secrets.RELEASE_KEY_ALIAS }}
+ RELEASE_KEY_PASSWORD: ${{ secrets.RELEASE_KEY_PASSWORD }}
run: |
- if [ -n "$DEBUG_KEYSTORE" ]; then
- mkdir -p ~/.android
- echo "$DEBUG_KEYSTORE" | base64 -d > ~/.android/debug.keystore
- else
- echo "::warning::DEBUG_KEYSTORE secret 沒有設定,debug APK 會用隨機金鑰簽名,無法覆蓋更新。"
+ if [ -z "$RELEASE_KEYSTORE" ]; then
+ echo "::warning::RELEASE_KEYSTORE secret 沒有設定,只產出未簽章的 release APK。"
+ exit 0
fi
-
- - name: Build debug APK
- run: ./gradlew assembleDebug --stacktrace
-
- - name: Upload debug APK
+ apksigner="$(ls -d "$ANDROID_HOME"/build-tools/* | sort -V | tail -n 1)/apksigner"
+ keystore="$RUNNER_TEMP/release.keystore"
+ trap 'rm -f "$keystore"' EXIT
+ echo "$RELEASE_KEYSTORE" | base64 -d > "$keystore"
+ "$apksigner" sign \
+ --ks "$keystore" \
+ --ks-pass env:RELEASE_KEYSTORE_PASSWORD \
+ --ks-key-alias "$RELEASE_KEY_ALIAS" \
+ --key-pass env:RELEASE_KEY_PASSWORD \
+ --out app/build/outputs/apk/release/mapconquer-release.apk \
+ app/build/outputs/apk/release/app-release-unsigned.apk
+ # 憑證指紋印在 log 上:F-Droid metadata 的 AllowedAPKSigningKeys 填的就是它。
+ "$apksigner" verify --print-certs app/build/outputs/apk/release/mapconquer-release.apk
+ echo "signed=true" >> "$GITHUB_OUTPUT"
+
+ - name: Upload signed release APK
+ if: steps.sign.outputs.signed == 'true'
uses: actions/upload-artifact@v5
with:
- name: mapconquer-debug
- path: app/build/outputs/apk/debug/app-debug.apk
+ name: mapconquer-release
+ path: app/build/outputs/apk/release/mapconquer-release.apk
if-no-files-found: error
- # F-Droid 建的是 release variant,這裡也走一遍同一條路徑。
- # 專案沒有簽章設定,所以產出的是未簽章的 APK。
- - name: Build release APK
- run: ./gradlew assembleRelease --stacktrace
+ # 可重現建置的檢查:在另一個目錄、關掉 build cache 再建一次 release,
+ # 兩份未簽章 APK 必須位元相同。F-Droid 從原始碼建出來的 APK 跟我們簽的
+ # 那份(去掉簽章後)一致,才會發布我們簽的版本;不一致的話那一版不會上架。
+ # 這裡先在 CI 抓出時間戳、絕對路徑、排序不穩定這類問題。
+ reproducible:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v5
- - name: Upload release APK
- uses: actions/upload-artifact@v5
+ - name: Set up JDK 17
+ uses: actions/setup-java@v5
with:
- name: mapconquer-release-unsigned
- path: app/build/outputs/apk/release/*.apk
- if-no-files-found: error
+ java-version: '17'
+ distribution: 'temurin'
+
+ - name: Setup Gradle
+ uses: gradle/actions/setup-gradle@v4
+
+ - name: Build twice from two different directories
+ run: |
+ ./gradlew assembleRelease --no-build-cache --stacktrace
+ cp app/build/outputs/apk/release/app-release-unsigned.apk "$RUNNER_TEMP/first.apk"
+ copy="$RUNNER_TEMP/second-checkout"
+ git worktree add "$copy" HEAD
+ (cd "$copy" && ./gradlew assembleRelease --no-build-cache --stacktrace)
+ cp "$copy/app/build/outputs/apk/release/app-release-unsigned.apk" "$RUNNER_TEMP/second.apk"
+ sha256sum "$RUNNER_TEMP/first.apk" "$RUNNER_TEMP/second.apk"
+ if ! cmp -s "$RUNNER_TEMP/first.apk" "$RUNNER_TEMP/second.apk"; then
+ echo "::error::兩次建置的 release APK 不一致,這個版本不可重現。"
+ (cd "$RUNNER_TEMP" && mkdir a b && unzip -q first.apk -d a && unzip -q second.apk -d b && diff -r a b | head -50) || true
+ exit 1
+ fi
+ echo "兩次建置位元相同。"
# 地圖與翻譯都是產生出來的,重跑產生器之後不該有任何差異 ——
# 否則代表有人手動改了 assets,下一次重新產生就會被蓋掉。
From b8a82273208b93a75c48683f44805e209fa651ca Mon Sep 17 00:00:00 2001
From: AcideFluorhydrique
<139669368+AcideFluorhydrique@users.noreply.github.com>
Date: Tue, 22 Sep 2026 20:07:25 +0800
Subject: [PATCH 09/11] Bring the README and store listing up to date
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Both still described the first version: five training exercises, 20 unit
types across land, sea and air, fighters that rule the sky, a 96×60 map
and everyone at peace in conquest. They now describe the game as it is:
three campaign chapters with nine battles playable from either side,
conquest in four years with blocs and surrender, player-first turns,
17 unit types plus air missions, single-hex strongholds, and a stretched
world map whose borders and straits are checked on every generation.
The README gains a section pointing to docs/original-behavior.md, and one
on releases: CI signs with the project key, the release must be
reproducible, the certificate fingerprint, and how a v tag
publishes a GitHub Release. The test and generator lists cover
SessionTest and tools/topology.py. The versionCode 1 changelog, not yet
released, now matches what that release will contain.
---
README.md | 127 ++++++++++++++----
README.zh.md | 98 +++++++++++---
.../metadata/android/en-US/changelogs/1.txt | 7 +-
.../android/en-US/full_description.txt | 23 ++--
.../metadata/android/zh-CN/changelogs/1.txt | 7 +-
.../android/zh-CN/full_description.txt | 14 +-
.../metadata/android/zh-TW/changelogs/1.txt | 7 +-
.../android/zh-TW/full_description.txt | 14 +-
8 files changed, 216 insertions(+), 81 deletions(-)
diff --git a/README.md b/README.md
index 172c763..57fe713 100644
--- a/README.md
+++ b/README.md
@@ -11,13 +11,18 @@ external storage or your location.
Two modes:
-- **Campaign** — five training exercises, each built to teach one thing: an
- amphibious crossing, a supply line stretched across a desert, an island chain
- that has to be taken by sea and air, a defensive battle you win by not losing,
- and a mountain offensive where your vehicles cannot follow you.
-- **Conquest** — the whole world map, a hundred-odd nations, everyone at peace on
- turn one. Pick anyone and take every city your enemies hold — a nation
- that loses its last city surrenders.
+- **Campaign** — three chapters (World War II in Europe, World War II in the
+ Pacific, the Cold War), nine battles from Poland 1939 to the Central Front 1985.
+ Every battle can be played from either side, and each side has its own goal:
+ take the named cities, or hold them until the given turn. Faster wins earn more
+ stars; stars pay for commanders you keep for every later game.
+- **Conquest** — the whole world in 1939, 1943, 1950 or 1980, with the blocs of
+ that year already drawn up. Take every city of every nation at war with you;
+ allies and neutrals do not count. A nation that loses its last city surrenders:
+ its remaining units disappear and its remaining land goes to whoever took that
+ city.
+
+You always move first in a round, and the AI moves after you.
Traditional Chinese, Simplified Chinese and English, switchable inside the app.
@@ -25,33 +30,85 @@ Traditional Chinese, Simplified Chinese and English, switchable inside the app.
| System | Summary |
| --- | --- |
-| Grid | Pointy-top hexes, axial maths, odd-r storage. 96×60 for the world map. |
+| Map | Pointy-top hexes, axial maths, odd-r storage. The world map is 120×76 and wraps east–west. It is deliberately stretched — Europe and East Asia wide, the oceans narrow — but the geography stays true: which countries share a border and which are separated by sea is checked every time the map is generated. |
| Terrain | 13 types, each with a movement cost, a defence bonus and an income. Vehicles cannot enter mountains, jungle or swamp. |
-| Territory | Ownership is per **province**, not per hex. Take the province capital with a land unit and the whole province changes hands — income, supply and factories with it. |
-| Units | 20 kinds across land, sea and air. Each has four separate attack values — against infantry, armour, ships and aircraft — so the counter matters more than the raw number. |
-| Combat | Ratio-based (`55·A/(A+D)`), bounded by construction, ±8% deterministic variance. Artillery fires from range and takes no return fire; it is nearly helpless in melee. |
+| Territory | Ownership is per **province**, not per hex; each province is one city and its land. A city falls when its defence is worn down and a land unit stands in it, and the whole province changes hands with it. Hong Kong, Gibraltar and Belfast are single-hex strongholds. |
+| Units | 17 kinds: 11 land, 6 sea. Each has four attack values — against infantry, armour, ships and aircraft — so the counter matters more than the raw number. Units are built as formations of one to four. |
+| Air power | Not units on the board but missions you pay for: fighter strikes, bomber strikes (which can also hit an empty city's walls) and airdrops, flown from cities and carriers (bombers need a large city). Anti-air, cruisers and destroyers blunt strikes near them. |
+| Combat | Ratio-based (`55·A/(A+D)`), bounded by construction, ±8% deterministic variance. Artillery fires from range and takes no return fire; it is nearly helpless in melee. A unit inside a city takes half the damage, and the city's walls take a further 70% of the blow. |
| Zones of control | Moving next to an enemy ends your move. Armour ignores this once per move, which is what makes it the tool for opening a breach. |
-| Supply | Spreads from your own cities along your own territory, priced in movement cost — so mountains break a supply line faster than plains do. Out of supply means losing strength, then dying. |
+| Supply | Spreads from your own cities along your own territory, priced in movement cost — so mountains break a supply line faster than plains do. Out of supply means losing strength, then dying. Supply trucks and headquarters carry a small supply bubble with them. |
| Experience | Units level 1→5 from damage dealt and kills. |
| Commanders | 16 fictional commanders with stacking skills, unlocked with medals earned from campaign stars, usable in every later game. |
| Research | Six branches, five levels each, +8% per level. |
-| Diplomacy | War / peace / alliance, with truce cooldowns so the AI cannot flip-flop. |
-| AI | Resource-based difficulty only — the AI plays by exactly the same combat rules you do. It runs as a resumable state machine so a hundred nations can move without freezing a frame. |
+| Diplomacy | Blocs go to war on their historical turn; you can declare war on a neutral, which makes it an enemy you must also defeat. Truce cooldowns stop the AI from flip-flopping. |
+| AI | Resource-based difficulty only — the AI plays by exactly the same rules you do. It runs as a resumable state machine so a hundred nations can move without freezing a frame. |
+
+## Reference behaviour
+
+Some rules — victory, surrender, turn order — are modelled on the observable
+behaviour of the classic games in this genre. What is known, what is still
+uncertain and how it could be tested is written down in
+[docs/original-behavior.md](docs/original-behavior.md). That document describes
+behaviour only; no code, data or artwork from any other game is used in this
+project.
## Building
-There is nothing to install beyond a JDK — Gradle fetches the rest.
+There is nothing to install beyond JDK 17 — Gradle fetches the rest.
```bash
-./gradlew assembleDebug
+./gradlew assembleRelease
```
-Run the test suite (this is worth doing; see below):
+The result is an unsigned APK in `app/build/outputs/apk/release/`. Run the test
+suite (this is worth doing; see below):
```bash
./gradlew test
```
+## Releases and signing
+
+Release APKs are signed with the project's own key, and the build is meant to be
+**reproducible**: building the same commit from source must give a byte-identical
+unsigned APK, so F-Droid can verify its own build against ours and ship the APK
+we signed. Everyone then has the same signature and can move between F-Droid,
+GitHub Releases and other stores without reinstalling.
+
+CI (`.github/workflows/build.yml`) does this on every push:
+
+1. builds the release APK with no signing configuration — the same artifact
+ F-Droid builds;
+2. signs it with `apksigner`, using the keystore in the `RELEASE_KEYSTORE`
+ repository secret (base64) and the `RELEASE_KEYSTORE_PASSWORD`,
+ `RELEASE_KEY_ALIAS` and `RELEASE_KEY_PASSWORD` secrets, and prints the
+ certificate fingerprint;
+3. in a separate job, builds the release twice from two different directories
+ and fails unless the two APKs are identical.
+
+Signing certificate SHA-256:
+
+```
+CE:85:A4:91:84:50:57:7B:3B:59:42:3E:A7:62:CC:86:76:E2:25:2C:6F:28:02:6A:C0:BB:B9:13:FC:4F:06:A0
+```
+
+To publish a release:
+
+1. raise `versionCode` and `versionName` in `app/build.gradle.kts`;
+2. write the changelog for the new `versionCode` in
+ `fastlane/metadata/android/*/changelogs/.txt`;
+3. commit, then tag the commit `v` and push the tag:
+
+ ```bash
+ git tag v0.1.0
+ git push origin v0.1.0
+ ```
+
+CI checks that the tag matches `versionName` and that the changelog exists, runs
+every check above, and creates a GitHub Release with the signed
+`mapconquer-.apk` attached and the changelog as its notes.
+
## Tests
The entire simulation layer — hex maths, pathfinding, map and scenario parsing,
@@ -64,11 +121,16 @@ fixtures:
- `PathfinderTest` — Dijkstra ranges, cost-aware routing, zones of control, no
state leaking between searches.
- `MapAssetTest` — every shipped map parses; neighbour relations are symmetric;
- provinces are contiguous, land-only and hold their own capital.
+ every land hex belongs to a province that holds its own capital; straits on
+ the world map are water all the way across; a map's fingerprint changes when a
+ single hex does.
- `ScenarioAssetTest` — every scenario cross-checks against its map: no province
claimed twice, no ship spawned on land, no campaign objective you already own.
- `CombatTest` — damage bounds, the rock-paper-scissors relationships, terrain and
entrenchment, artillery's asymmetry.
+- `SessionTest` — the turn engine on small hand-written maps: capture, sieges,
+ formations, air missions, surrender, the conquest victory and turn limit, and
+ that a new game starts on the player's turn.
- `ConquestSmokeTest` — loads the real world map with 100+ nations and plays
several complete turns with the AI driving every side, asserting a set of state
invariants after every turn.
@@ -85,17 +147,21 @@ python3 tools/genstrings.py # → app/src/main/res/values*/strings.xml
- `tools/geodata.py` — coastlines, mountain ranges, deserts, jungles and rivers as
hand-drawn latitude/longitude polygons. These are original simplified outlines,
- not derived from OpenStreetMap, Natural Earth or any other dataset — at 3.75° per
- hex there is nothing a real dataset would buy, and keeping everything under one
- licence makes the F-Droid build trivially auditable. If you want real data, swap
- `LAND`/`SEA` for polygons read from a GeoJSON; the rasteriser below does not care.
-- `tools/hexraster.py` — projects those polygons onto the hex grid and paints
- terrain by latitude, elevation and biome.
+ not derived from OpenStreetMap, Natural Earth or any other dataset — at this
+ scale there is nothing a real dataset would buy, and keeping everything under
+ one licence makes the F-Droid build trivially auditable. It also lists which
+ land masses must never touch (islands, and pairs such as Arabia and Africa).
+- `tools/hexraster.py` — projects those polygons onto the hex grid, keeps every
+ island and sea gap at least one hex of water, and paints terrain by latitude,
+ elevation and biome.
- `tools/places.py` — the single source of truth for provinces and nations: one row
per city with its coordinates, city tier, owner and its name in all three
- languages. Both the map files and the translations come from this table, so they
- can never drift apart.
-- `tools/scenarios.py` — the campaign missions.
+ languages, plus how nations merge, split and ally in each year. Both the map
+ files and the translations come from this table, so they can never drift apart.
+- `tools/scenarios.py` — the campaign battles.
+- `tools/topology.py` — the geography written down as rules: borders that must
+ exist, seas that must stay seas, and countries whose mainland must be one piece.
+ `genworld.py` fails when the world map breaks any of them.
CI re-runs both generators and fails if the committed output differs, so the
assets in the repository always match the tools that produced them.
@@ -107,10 +173,13 @@ A few decisions worth knowing before reading the code:
- **Everything is drawn on a `Canvas`.** One `Activity`, one `SurfaceView`, no
Compose, no fragments, no view hierarchy. Screens are states of `GameView`.
- **No binary assets.** Unit symbols are drawn as vectors, the icon is a vector,
- and sound effects are synthesised at runtime. Nothing in the APK needs a
- provenance statement.
+ flags are emoji, and sound effects are synthesised at runtime. Nothing in the
+ APK needs a provenance statement.
- **Determinism.** The RNG is a seeded xorshift whose state is part of the save
file, so a battle plays out the same way on a reload.
+- **Saves know their map.** A save records the map's fingerprint and a format
+ version; one made on a different map, or under older rules, is refused rather
+ than loaded into the wrong hexes.
- **Tile indices, not objects.** Pathfinding and AI walk hundreds of thousands of
tiles per turn; nothing on those paths allocates.
diff --git a/README.zh.md b/README.zh.md
index 644d5a6..2d8f492 100644
--- a/README.zh.md
+++ b/README.zh.md
@@ -10,10 +10,14 @@ Android 上的六角格回合制大戰略遊戲。自由軟體,沒有廣告、
兩個模式:
-- **戰役** —— 五場演習,每一關只教一件事:渡海登陸、把補給線拉過沙漠、
- 只能靠海空拿下的島鏈、靠「不輸」取勝的防禦戰,以及輪車與履帶跟不上你的山地攻勢。
-- **征服** —— 整張世界地圖、一百多個國家,第一回合所有人都還在和平狀態。
- 挑一個國家,攻下所有敵國的城市 —— 丟掉最後一座城的國家就會投降。
+- **戰役** —— 三章(二戰歐洲、二戰太平洋、冷戰),九場戰役,從 1939 年的波蘭
+ 打到 1985 年的中歐前線。每一場兩邊都能打,各有各的目標:攻下指定城市,
+ 或堅守到指定回合。愈快獲勝星等愈高;星等換成勳章,勳章招募的指揮官之後每一局都能用。
+- **征服** —— 1939、1943、1950 或 1980 年的整個世界,當年的陣營都已經劃好。
+ 攻下所有跟你交戰的國家的全部城市;盟國與中立國不算。丟掉最後一座城的國家
+ 會投降:它剩下的部隊全部消失,剩下的領土歸攻下那座城的一方。
+
+每一輪都由你先動,AI 在你之後行動。
正體中文、简体中文、English,可以在 app 內切換。
@@ -21,33 +25,77 @@ Android 上的六角格回合制大戰略遊戲。自由軟體,沒有廣告、
| 系統 | 說明 |
| --- | --- |
-| 網格 | 尖頂六角格,軸向座標做數學、奇數列偏移做儲存。世界地圖 96×60。 |
+| 地圖 | 尖頂六角格,軸向座標做數學、奇數列偏移做儲存。世界地圖 120×76,東西環繞。地圖刻意變形 —— 歐洲與東亞放大、大洋壓扁 —— 但地理關係是真的:哪些國家接壤、哪些之間隔著海,每次產生地圖時都會檢查。 |
| 地形 | 13 種,各有移動成本、防禦加成與產值。輪車與履帶進不了山地、叢林與沼澤。 |
-| 領土 | 歸屬算在**省**上而不是格上。用陸軍拿下省會,整省連同收入、補給與工業一起易主。 |
-| 兵種 | 陸海空共 20 種。每種都有四個獨立的攻擊值 —— 對步兵、對裝甲、對艦艇、對空 —— 所以「派誰去」比「數字多大」更重要。 |
-| 戰鬥 | 攻防比公式(`55·A/(A+D)`),天然有界,加上 ±8% 的決定性亂數。火炮遠射不被反擊,但被貼身幾乎無法自衛。 |
+| 領土 | 歸屬算在**省**上而不是格上,一省就是一座城與它的土地。城防被打光、陸軍站進城裡,這座城就陷落,整省跟著易主。香港、直布羅陀、貝爾法斯特是只佔一格的據點。 |
+| 兵種 | 17 種:陸軍 11、海軍 6。每種都有四個獨立的攻擊值 —— 對步兵、對裝甲、對艦艇、對空 —— 所以「派誰去」比「數字多大」更重要。部隊建造時就決定編制,一到四個。 |
+| 空軍 | 不是棋盤上的棋子,而是花錢買的任務:戰鬥機打擊、轟炸機打擊(也能轟炸無人城市的城防)與空降,從城市與航艦起飛(轟炸機要大城市)。附近的防空、巡洋艦、驅逐艦會削弱打擊。 |
+| 戰鬥 | 攻防比公式(`55·A/(A+D)`),天然有界,加上 ±8% 的決定性亂數。火炮遠射不被反擊,但被貼身幾乎無法自衛。城裡的部隊只受一半傷害,城防另外承受這一擊的 70%。 |
| 控制區 | 走到敵人旁邊就必須停下。裝甲部隊每次移動可以無視一次,這正是它作為突破口的價值。 |
-| 補給 | 從自己的城市沿自己的領土擴散,用移動成本計價 —— 所以越過山脈的攻勢會比沿平原推進更快斷補。斷補給會先掉戰力,最後餓死。 |
+| 補給 | 從自己的城市沿自己的領土擴散,用移動成本計價 —— 所以越過山脈的攻勢會比沿平原推進更快斷補。斷補給會先掉戰力,最後餓死。補給車與司令部自帶一個小型補給圈。 |
| 經驗 | 部隊靠打出的傷害與擊殺從 1 級升到 5 級。 |
| 指揮官 | 16 位虛構指揮官,技能可疊加。用戰役星等換來的勳章解鎖,之後每一局都能用。 |
| 研發 | 六個分支,各五級,每級 +8%。 |
-| 外交 | 戰爭/和平/同盟,附停戰冷卻,避免 AI 每回合開關戰爭。 |
-| AI | 難度只調資源,戰鬥規則跟玩家完全一樣。AI 寫成可分段執行的狀態機,所以一百多個國家輪流行動也不會卡住畫面。 |
+| 外交 | 各陣營在史實的回合參戰;你可以對中立國宣戰,它就成了你也必須打垮的敵國。停戰冷卻避免 AI 反覆開關戰爭。 |
+| AI | 難度只調資源,規則跟玩家完全一樣。AI 寫成可分段執行的狀態機,所以一百多個國家輪流行動也不會卡住畫面。 |
+
+## 參考行為
+
+勝利條件、投降、回合順序等規則,參照的是同類經典遊戲的可觀察行為。
+已經確認的、還不確定的、以及可以怎麼驗證,都寫在
+[docs/original-behavior.md](docs/original-behavior.md)。那份文件只描述行為;
+本專案沒有使用任何其他遊戲的程式碼、資料或美術。
## 建置
-除了 JDK 之外不需要另外裝東西,其餘由 Gradle 抓。
+除了 JDK 17 之外不需要另外裝東西,其餘由 Gradle 抓。
```bash
-./gradlew assembleDebug
+./gradlew assembleRelease
```
-跑測試(很值得跑,理由見下):
+產出的是 `app/build/outputs/apk/release/` 底下未簽章的 APK。跑測試(很值得跑,理由見下):
```bash
./gradlew test
```
+## 發行與簽章
+
+Release APK 用本專案自己的金鑰簽章,而且建置必須**可重現**:同一個 commit 從原始碼
+建出來的未簽章 APK 必須位元相同,F-Droid 才能拿它自己建的版本跟我們的比對,
+然後發布我們簽的那一份。這樣所有人拿到的都是同一個簽章,在 F-Droid、GitHub Releases
+與其他商店之間切換都不必重裝。
+
+CI(`.github/workflows/build.yml`)每次 push 都會:
+
+1. 在沒有任何簽章設定的情況下建出 release APK —— 就是 F-Droid 會建出來的那一份;
+2. 用 `apksigner` 簽章,金鑰來自 repo secret `RELEASE_KEYSTORE`(base64),
+ 密碼與別名來自 `RELEASE_KEYSTORE_PASSWORD`、`RELEASE_KEY_ALIAS`、
+ `RELEASE_KEY_PASSWORD`,並印出憑證指紋;
+3. 另一個 job 從兩個不同的目錄各建一次 release,兩份不一致就讓建置失敗。
+
+簽章憑證 SHA-256:
+
+```
+CE:85:A4:91:84:50:57:7B:3B:59:42:3E:A7:62:CC:86:76:E2:25:2C:6F:28:02:6A:C0:BB:B9:13:FC:4F:06:A0
+```
+
+發行新版本:
+
+1. 在 `app/build.gradle.kts` 調高 `versionCode` 與 `versionName`;
+2. 在 `fastlane/metadata/android/*/changelogs/.txt` 寫好這一版的更新說明;
+3. commit,然後把那個 commit 標上 `v` 並推上去:
+
+ ```bash
+ git tag v0.1.0
+ git push origin v0.1.0
+ ```
+
+CI 會檢查 tag 跟 `versionName` 一致、更新說明存在,跑完上面所有檢查,
+然後建立一個 GitHub Release,附上簽好章的 `mapconquer-.apk`,
+說明文字就是那份更新說明。
+
## 測試
整個模擬層 —— 六角數學、尋路、地圖與劇本解析、戰鬥、回合引擎與 AI ——
@@ -56,10 +104,13 @@ Android 上的六角格回合制大戰略遊戲。自由軟體,沒有廣告、
- `HexMathTest` —— 座標往返、環與圓盤的大小、直線的連續性。
- `PathfinderTest` —— Dijkstra 範圍、考慮成本的繞路、控制區、以及搜尋之間不殘留狀態。
-- `MapAssetTest` —— 每一張地圖都解析得動;鄰接關係對稱;省份連通、全是陸地、而且含有自己的省會。
+- `MapAssetTest` —— 每一張地圖都解析得動;鄰接關係對稱;每一格陸地都屬於某個含有自己
+ 省會的省;世界地圖上的海峽從頭到尾都是水;改動任何一格,地圖指紋就會跟著變。
- `ScenarioAssetTest` —— 每份劇本都對照它的地圖驗過:沒有省份被兩國同時宣稱、
沒有軍艦生在陸地上、沒有「開局就已經持有」的戰役目標。
- `CombatTest` —— 傷害邊界、兵種相剋、地形與築壕、火炮的不對稱性。
+- `SessionTest` —— 在手寫的小地圖上驗回合引擎:佔領、圍城、編制、空中任務、投降、
+ 征服的勝利條件與回合上限,以及新局一開始就輪到玩家。
- `ConquestSmokeTest` —— 載入真實的世界地圖與一百多個國家,讓 AI 操控每一方
完整跑好幾個回合,每回合結束後檢查一整組狀態不變量。
@@ -74,13 +125,16 @@ python3 tools/genstrings.py # → app/src/main/res/values*/strings.xml
- `tools/geodata.py` —— 海岸線、山脈、沙漠、雨林與河流,全部是手繪的經緯度多邊形。
這些是原創的簡化輪廓,**不是**從 OpenStreetMap、Natural Earth 或任何資料庫轉出來的:
- 一格 3.75 經度的尺度下,真實資料換不到任何畫面上的差別,而整包只有一種授權,
- F-Droid 的稽核也就變得單純。真的要用實測資料時,把 `LAND` / `SEA` 換成從 GeoJSON
- 讀進來的多邊形即可,底下的柵格化完全不必動。
-- `tools/hexraster.py` —— 把那些多邊形投影到六角格上,再依緯度、高程與生態帶塗上地形。
+ 在這個尺度下真實資料換不到任何差別,而整包只有一種授權,F-Droid 的稽核也就變得單純。
+ 這裡也列出哪些陸塊之間絕對不能相連(各個島嶼,以及阿拉伯半島對非洲這類配對)。
+- `tools/hexraster.py` —— 把那些多邊形投影到六角格上,確保每座島、每道海峽至少隔一格海,
+ 再依緯度、高程與生態帶塗上地形。
- `tools/places.py` —— 省份與國家的唯一資料來源:一列一座城市,帶座標、城市等級、
- 歸屬國,以及三種語言的名字。地圖檔與翻譯都由這張表產生,所以兩邊永遠不會走鐘。
+ 歸屬國,以及三種語言的名字;還有各年份國家怎麼合併、分裂、結盟。地圖檔與翻譯都由
+ 這張表產生,所以兩邊永遠不會走鐘。
- `tools/scenarios.py` —— 戰役關卡的定義。
+- `tools/topology.py` —— 把地理寫成規則:必須存在的國界、必須是海的海峽、本土必須連成
+ 一片的國家。世界地圖違反任何一條,`genworld.py` 就會失敗。
CI 會重跑兩支產生器,只要輸出跟 commit 的版本有差就讓建置失敗 ——
repo 裡的資產永遠對得上產生它的工具。
@@ -91,10 +145,12 @@ repo 裡的資產永遠對得上產生它的工具。
- **畫面全部畫在 `Canvas` 上。** 一個 Activity、一個 SurfaceView,
沒有 Compose、沒有 Fragment、沒有 View 樹。每個頁面都是 `GameView` 的一個狀態。
-- **沒有任何二進位素材。** 兵種記號是向量畫的、圖示是向量、音效是即時合成的。
+- **沒有任何二進位素材。** 兵種記號是向量畫的、圖示是向量、國旗是 emoji、音效是即時合成的。
APK 裡沒有一樣東西需要交代來源。
- **決定性。** 亂數是帶種子的 xorshift,狀態本身就是存檔的一部分,
所以讀檔之後同一場仗會打出同樣的結果。
+- **存檔認得自己的地圖。** 存檔記下地圖指紋與格式版本;在另一張地圖、或舊版規則下
+ 建立的存檔會被拒絕,而不是讀進錯的格子裡。
- **用格子索引而不是物件。** 尋路與 AI 每回合要走過數十萬個格子,
那條路徑上不做任何配置。
diff --git a/fastlane/metadata/android/en-US/changelogs/1.txt b/fastlane/metadata/android/en-US/changelogs/1.txt
index c5bfcf1..a14db58 100644
--- a/fastlane/metadata/android/en-US/changelogs/1.txt
+++ b/fastlane/metadata/android/en-US/changelogs/1.txt
@@ -1,6 +1,7 @@
First release.
-- Campaign: five training exercises
-- Conquest: the world map with 100+ nations
-- 20 unit types, six research branches, 16 commanders
+- Campaign: three chapters, nine battles, each playable from either side
+- Conquest: the world in 1939, 1943, 1950 and 1980
+- A nation that loses its last city surrenders
+- 17 unit types, air missions, six research branches, 16 commanders
- Traditional Chinese, Simplified Chinese and English
diff --git a/fastlane/metadata/android/en-US/full_description.txt b/fastlane/metadata/android/en-US/full_description.txt
index cee114e..dd90e4a 100644
--- a/fastlane/metadata/android/en-US/full_description.txt
+++ b/fastlane/metadata/android/en-US/full_description.txt
@@ -2,21 +2,23 @@ A turn-based grand-strategy game on a hex grid. Move armies, hold supply lines,
cities, and decide who the next war is with.
CAMPAIGN
-Five training exercises, each built around one idea: an amphibious crossing, a supply
-line stretched across a desert, an island chain that can only be taken by sea and air,
-a defensive battle won by not losing, and a mountain offensive your vehicles cannot
-follow you into. Finish faster for more stars; stars pay out medals you spend on
+Three chapters — World War II in Europe, World War II in the Pacific, the Cold War —
+and nine battles from Poland 1939 to the Central Front 1985. Every battle can be fought
+from either side, and each side has its own goal: take the named cities, or hold them
+until the given turn. Finish faster for more stars; stars pay out medals you spend on
commanders who then serve you in every later game.
CONQUEST
-The whole world map, a hundred-odd nations, everyone at peace on turn one. Pick anyone
-— a superpower or a country with a single city — and take every city your enemies hold.
-A nation that loses its last city surrenders.
+The whole world in 1939, 1943, 1950 or 1980, with that year's blocs already drawn up.
+Take every city of every nation at war with you; allies and neutrals do not count.
+A nation that loses its last city surrenders, its army disappears and its land is yours.
+You always move first in a round.
WHAT MAKES A BATTLE
Every unit has four separate attack values: against infantry, armour, ships and
-aircraft. Anti-tank guns shred armour and bounce off infantry. Fighters own the sky and
-do nothing on the ground. Artillery strikes from range and takes no return fire, but is
+aircraft. Anti-tank guns shred armour and bounce off infantry. Air power is a mission you
+pay for: a fighter strike tears into infantry, a bomber strike smashes tanks, ships
+and city walls, and anti-aircraft fire blunts both. Artillery strikes from range and takes no return fire, but is
nearly helpless once something reaches it. Terrain, city walls and entrenchment all
protect the defender, so where you fight matters as much as what you bring.
@@ -26,7 +28,8 @@ more to reach across than plains do. An army that outruns its logistics loses st
every turn and eventually starves. Supply trucks and headquarters carry a small bubble
with them — that is how an offensive keeps moving.
-20 unit types across land, sea and air. Six research branches. 16 commanders with
+17 unit types on land and sea, plus fighter, bomber and airdrop missions. Six
+research branches. 16 commanders with
stacking skills. Diplomacy with war, peace and alliances.
FREE SOFTWARE
diff --git a/fastlane/metadata/android/zh-CN/changelogs/1.txt b/fastlane/metadata/android/zh-CN/changelogs/1.txt
index e45a23a..fd3bbae 100644
--- a/fastlane/metadata/android/zh-CN/changelogs/1.txt
+++ b/fastlane/metadata/android/zh-CN/changelogs/1.txt
@@ -1,6 +1,7 @@
首次发行。
-- 战役:五场演习关卡
-- 征服:一百多个国家的世界地图
-- 20 种兵种、六个研发分支、16 位指挥官
+- 战役:三章、九场战役,每一场两边都能打
+- 征服:1939、1943、1950、1980 年的世界
+- 丢掉最后一座城的国家会投降
+- 17 种兵种、空中任务、六个研发分支、16 位指挥官
- 正體中文、简体中文、English
diff --git a/fastlane/metadata/android/zh-CN/full_description.txt b/fastlane/metadata/android/zh-CN/full_description.txt
index 61fca84..de30295 100644
--- a/fastlane/metadata/android/zh-CN/full_description.txt
+++ b/fastlane/metadata/android/zh-CN/full_description.txt
@@ -2,17 +2,19 @@
并且决定下一场战争要跟谁打。
战役
-五场演习,每一关只围绕一个概念:渡海登陆、把补给线拉过沙漠、只能靠海空拿下的岛链、
-靠「不输」取胜的防御战,以及轮车与履带跟不上你的山地攻势。越快通关星等越高;
+三章 —— 二战欧洲、二战太平洋、冷战 —— 九场战役,从 1939 年的波兰打到 1985 年的中欧前线。
+每一场两边都能打,各有各的目标:攻下指定城市,或坚守到指定回合。越快通关星等越高;
星等换成勋章,勋章用来招募指挥官,而指挥官在之后的每一局都能用。
征服
-整张世界地图、一百多个国家,第一回合所有人都还在和平状态。
-挑任何一国 —— 超级强权,或是只有一座城市的小国 —— 攻下所有敌国的城市。丢掉最后一座城的国家就会投降。
+1939、1943、1950 或 1980 年的整个世界,当年的阵营都已经划好。
+攻下所有跟你交战的国家的全部城市;盟国与中立国不算。
+丢掉最后一座城的国家会投降,它的军队消失,领土归你。每一轮都由你先动。
一场仗是怎么打起来的
每支部队都有四个独立的攻击值:对步兵、对装甲、对舰艇、对空。
-反坦克炮打战车势如破竹,打步兵却软弱无力;战斗机制空无敌,对地面却几乎没有作用。
+反坦克炮打战车势如破竹,打步兵却软弱无力。空军是花钱买的任务:战斗机打击专克步兵,
+轰炸机打击专打战车、舰艇与城防,而防空火力两者都能削弱。
火炮从远处开火且不会被反击,可是一旦被贴身就几乎没有自卫能力。
地形、城墙与筑壕都保护守方,所以「在哪里打」跟「带了什么去打」一样重要。
@@ -21,7 +23,7 @@
跑赢自己后勤的军队会逐回合掉战力,最后饿死。
补给车与司令部自带一个小型补给圈 —— 攻势能不能持续下去就靠它们。
-陆海空共 20 种兵种。六个研发分支。16 位技能可叠加的指挥官。
+陆海共 17 种兵种,另有战斗机、轰炸机与空降三种空中任务。六个研发分支。16 位技能可叠加的指挥官。
包含战争、和平与同盟的外交系统。
自由软件
diff --git a/fastlane/metadata/android/zh-TW/changelogs/1.txt b/fastlane/metadata/android/zh-TW/changelogs/1.txt
index 97d2ffa..af69ac0 100644
--- a/fastlane/metadata/android/zh-TW/changelogs/1.txt
+++ b/fastlane/metadata/android/zh-TW/changelogs/1.txt
@@ -1,6 +1,7 @@
首次發行。
-- 戰役:五場演習關卡
-- 征服:一百多個國家的世界地圖
-- 20 種兵種、六個研發分支、16 位指揮官
+- 戰役:三章、九場戰役,每一場兩邊都能打
+- 征服:1939、1943、1950、1980 年的世界
+- 丟掉最後一座城的國家會投降
+- 17 種兵種、空中任務、六個研發分支、16 位指揮官
- 正體中文、简体中文、English
diff --git a/fastlane/metadata/android/zh-TW/full_description.txt b/fastlane/metadata/android/zh-TW/full_description.txt
index 7b60edc..0eeb51b 100644
--- a/fastlane/metadata/android/zh-TW/full_description.txt
+++ b/fastlane/metadata/android/zh-TW/full_description.txt
@@ -2,17 +2,19 @@
並且決定下一場戰爭要跟誰打。
戰役
-五場演習,每一關只圍繞一個概念:渡海登陸、把補給線拉過沙漠、只能靠海空拿下的島鏈、
-靠「不輸」取勝的防禦戰,以及輪車與履帶跟不上你的山地攻勢。愈快通關星等愈高;
+三章 —— 二戰歐洲、二戰太平洋、冷戰 —— 九場戰役,從 1939 年的波蘭打到 1985 年的中歐前線。
+每一場兩邊都能打,各有各的目標:攻下指定城市,或堅守到指定回合。愈快通關星等愈高;
星等換成勳章,勳章用來招募指揮官,而指揮官在之後的每一局都能用。
征服
-整張世界地圖、一百多個國家,第一回合所有人都還在和平狀態。
-挑任何一國 —— 超級強權,或是只有一座城市的小國 —— 攻下所有敵國的城市。丟掉最後一座城的國家就會投降。
+1939、1943、1950 或 1980 年的整個世界,當年的陣營都已經劃好。
+攻下所有跟你交戰的國家的全部城市;盟國與中立國不算。
+丟掉最後一座城的國家會投降,它的軍隊消失,領土歸你。每一輪都由你先動。
一場仗是怎麼打起來的
每支部隊都有四個獨立的攻擊值:對步兵、對裝甲、對艦艇、對空。
-反坦克炮打戰車勢如破竹,打步兵卻軟弱無力;戰鬥機制空無敵,對地面卻幾乎沒有作用。
+反坦克炮打戰車勢如破竹,打步兵卻軟弱無力。空軍是花錢買的任務:戰鬥機打擊專剋步兵,
+轟炸機打擊專打戰車、艦艇與城防,而防空火力兩者都能削弱。
火炮從遠處開火且不會被反擊,可是一旦被貼身就幾乎沒有自衛能力。
地形、城牆與築壕都保護守方,所以「在哪裡打」跟「帶了什麼去打」一樣重要。
@@ -21,7 +23,7 @@
跑贏自己後勤的軍隊會逐回合掉戰力,最後餓死。
補給車與司令部自帶一個小型補給圈 —— 攻勢能不能持續下去就靠它們。
-陸海空共 20 種兵種。六個研發分支。16 位技能可疊加的指揮官。
+陸海共 17 種兵種,另有戰鬥機、轟炸機與空降三種空中任務。六個研發分支。16 位技能可疊加的指揮官。
包含戰爭、和平與同盟的外交系統。
自由軟體
From acfe04f777f8347152448376431772552e5599f4 Mon Sep 17 00:00:00 2001
From: AcideFluorhydrique
<139669368+AcideFluorhydrique@users.noreply.github.com>
Date: Tue, 22 Sep 2026 20:07:26 +0800
Subject: [PATCH 10/11] Publish a GitHub Release when a version tag is pushed
Pushing v runs the whole workflow and, once the build, the
reproducibility check and the generated-assets check have passed, a
release job creates the GitHub Release with the signed APK attached as
mapconquer-.apk, the stable name F-Droid's Binaries URL can
point at. The notes are the fastlane changelogs for that versionCode in
all three languages, with the APK's SHA-256.
The version stays in the source, where F-Droid reads it; the job fails if
the tag does not match versionName or the changelog is missing. On a tag,
missing signing secrets are an error rather than a warning, so an
unsigned APK can never be published.
---
.github/workflows/build.yml | 68 +++++++++++++++++++++++++++++++++++++
1 file changed, 68 insertions(+)
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index d909a3e..d4dbdca 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -6,6 +6,8 @@ name: Build
on:
push:
branches: [ main ]
+ # 推 v* tag 會多跑下面的 release job,把簽好章的 APK 放進 GitHub Release。
+ tags: [ 'v*' ]
pull_request:
workflow_dispatch:
@@ -94,6 +96,11 @@ jobs:
RELEASE_KEY_PASSWORD: ${{ secrets.RELEASE_KEY_PASSWORD }}
run: |
if [ -z "$RELEASE_KEYSTORE" ]; then
+ # 發行版本不能沒有簽章:推 tag 時缺 secret 就直接失敗。
+ if [[ "$GITHUB_REF" == refs/tags/* ]]; then
+ echo "::error::RELEASE_KEYSTORE secret 沒有設定,無法簽章發行版本。"
+ exit 1
+ fi
echo "::warning::RELEASE_KEYSTORE secret 沒有設定,只產出未簽章的 release APK。"
exit 0
fi
@@ -178,3 +185,64 @@ jobs:
echo "請在本機執行 python3 tools/genworld.py && python3 tools/genstrings.py 之後一起 commit。"
exit 1
fi
+
+ # 推 v tag 時發行:前面三個 job 都通過才會跑到這裡,
+ # 所以發出去的 APK 一定通過了測試、產生檔檢查與可重現建置檢查。
+ release:
+ if: startsWith(github.ref, 'refs/tags/v')
+ needs: [ build, reproducible, generated-assets ]
+ runs-on: ubuntu-latest
+ permissions:
+ contents: write
+
+ steps:
+ - uses: actions/checkout@v5
+
+ # 版本號寫在原始碼裡(F-Droid 從原始碼讀它),tag 只是指向那個 commit。
+ # 兩者不一致代表忘了改 versionName,或 tag 打錯了 commit。
+ - name: Check the tag against the version in the source
+ id: version
+ run: |
+ name=$(sed -n 's/^ *versionName = "\(.*\)"$/\1/p' app/build.gradle.kts)
+ code=$(sed -n 's/^ *versionCode = \([0-9]*\)$/\1/p' app/build.gradle.kts)
+ if [ "$GITHUB_REF_NAME" != "v$name" ]; then
+ echo "::error::tag $GITHUB_REF_NAME 跟 app/build.gradle.kts 的 versionName $name 不一致。"
+ exit 1
+ fi
+ changelog="fastlane/metadata/android/en-US/changelogs/$code.txt"
+ if [ ! -f "$changelog" ]; then
+ echo "::error::找不到 versionCode $code 的更新說明 $changelog。"
+ exit 1
+ fi
+ echo "name=$name" >> "$GITHUB_OUTPUT"
+ echo "code=$code" >> "$GITHUB_OUTPUT"
+
+ - name: Download the signed APK
+ uses: actions/download-artifact@v5
+ with:
+ name: mapconquer-release
+ path: dist
+
+ - name: Create the GitHub Release
+ env:
+ GH_TOKEN: ${{ github.token }}
+ NAME: ${{ steps.version.outputs.name }}
+ CODE: ${{ steps.version.outputs.code }}
+ run: |
+ apk="dist/mapconquer-$NAME.apk"
+ mv dist/mapconquer-release.apk "$apk"
+ {
+ cat "fastlane/metadata/android/en-US/changelogs/$CODE.txt"
+ for lang in zh-TW zh-CN; do
+ file="fastlane/metadata/android/$lang/changelogs/$CODE.txt"
+ if [ -f "$file" ]; then echo; echo "---"; echo; cat "$file"; fi
+ done
+ echo
+ echo "---"
+ echo
+ echo "SHA-256 of \`mapconquer-$NAME.apk\`: \`$(sha256sum "$apk" | cut -d' ' -f1)\`"
+ } > notes.md
+ gh release create "$GITHUB_REF_NAME" "$apk" \
+ --title "MapConquer $NAME" \
+ --notes-file notes.md \
+ --verify-tag
From 89a0293bd25af78cbc4168c5b030add27fa50d62 Mon Sep 17 00:00:00 2001
From: AcideFluorhydrique
<139669368+AcideFluorhydrique@users.noreply.github.com>
Date: Tue, 22 Sep 2026 20:57:49 +0800
Subject: [PATCH 11/11] Draw the Soviet, East German and wartime German flags
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Flags were emoji only, so the Soviet Union flew the Russian tricolour,
East Germany had no flag at all, and Germany in 1939 and 1943 flew the
Federal Republic's. No emoji font has the flags these need.
A scenario's flag can now be an @-code as well as an emoji, and
render/FlagArt.kt draws those codes in the style of the default Android
emoji flags: the same box, measured from a real emoji flag so the two
always line up, a wave along the top and bottom edges, a light sheen and
a faint dark edge. Each is composed once per pixel size and cached, since
the map shows a hundred city badges a frame. The five places that drew a
flag as text now go through FlagArt; the two that glued flag and name
into one string draw them separately.
- @su: red field, gold star, hammer and sickle — the Soviet Union in
every scenario from 1939 to 1985.
- @gdr: black, red and gold with the wreath, hammer and compass, from 1959.
In 1950 East Germany's flag was the same plain tricolour as West
Germany's, and that is what it flies.
- @reich: Germany from 1935 to 1945. The historical flag is the swastika
flag; by the maintainer's decision the game shows the Wehrmacht's Iron
Cross instead, black with a white rim on field grey.
tools/places.py picks the flag by nation and year (flag_for), for both
conquest and campaign scenarios, and ScenarioAssetTest rejects any @-code
FlagArt does not know.
---
README.md | 4 +-
README.zh.md | 3 +-
.../campaign_cw_03_central_front.scn | 4 +-
.../campaign_cw_03_central_front_pact.scn | 4 +-
.../scenarios/campaign_ww2_01_poland.scn | 4 +-
.../scenarios/campaign_ww2_01_poland_axis.scn | 4 +-
.../scenarios/campaign_ww2_02_france.scn | 4 +-
.../campaign_ww2_02_france_allies.scn | 4 +-
.../scenarios/campaign_ww2_03_desert.scn | 2 +-
.../scenarios/campaign_ww2_03_desert_axis.scn | 2 +-
.../scenarios/campaign_ww2_05_east_front.scn | 4 +-
.../campaign_ww2_05_east_front_axis.scn | 4 +-
.../main/assets/scenarios/conquest_1939.scn | 4 +-
.../main/assets/scenarios/conquest_1943.scn | 4 +-
.../main/assets/scenarios/conquest_1950.scn | 4 +-
.../main/assets/scenarios/conquest_1980.scn | 4 +-
.../mapconquer/render/FlagArt.kt | 347 ++++++++++++++++++
.../mapconquer/render/HudRenderer.kt | 15 +-
.../mapconquer/render/MapRenderer.kt | 4 +-
.../mapconquer/render/MenuRenderer.kt | 2 +-
.../mapconquer/render/PanelRenderer.kt | 12 +-
.../mapconquer/game/ScenarioAssetTest.kt | 16 +
tools/genworld.py | 4 +-
tools/places.py | 28 +-
24 files changed, 445 insertions(+), 42 deletions(-)
create mode 100644 app/src/main/java/io/github/acidefluorhydrique/mapconquer/render/FlagArt.kt
diff --git a/README.md b/README.md
index 57fe713..612651a 100644
--- a/README.md
+++ b/README.md
@@ -173,7 +173,9 @@ A few decisions worth knowing before reading the code:
- **Everything is drawn on a `Canvas`.** One `Activity`, one `SurfaceView`, no
Compose, no fragments, no view hierarchy. Screens are states of `GameView`.
- **No binary assets.** Unit symbols are drawn as vectors, the icon is a vector,
- flags are emoji, and sound effects are synthesised at runtime. Nothing in the
+ flags are emoji — except the Soviet, East German and wartime German flags,
+ which no emoji font has and which are drawn in code in the same waving style —
+ and sound effects are synthesised at runtime. Nothing in the
APK needs a provenance statement.
- **Determinism.** The RNG is a seeded xorshift whose state is part of the save
file, so a battle plays out the same way on a reload.
diff --git a/README.zh.md b/README.zh.md
index 2d8f492..5bc623e 100644
--- a/README.zh.md
+++ b/README.zh.md
@@ -145,7 +145,8 @@ repo 裡的資產永遠對得上產生它的工具。
- **畫面全部畫在 `Canvas` 上。** 一個 Activity、一個 SurfaceView,
沒有 Compose、沒有 Fragment、沒有 View 樹。每個頁面都是 `GameView` 的一個狀態。
-- **沒有任何二進位素材。** 兵種記號是向量畫的、圖示是向量、國旗是 emoji、音效是即時合成的。
+- **沒有任何二進位素材。** 兵種記號是向量畫的、圖示是向量、國旗是 emoji(emoji 裡沒有的蘇聯、東德與戰時德國國旗,
+ 用程式碼照同樣的飄揚樣式畫出來)、音效是即時合成的。
APK 裡沒有一樣東西需要交代來源。
- **決定性。** 亂數是帶種子的 xorshift,狀態本身就是存檔的一部分,
所以讀檔之後同一場仗會打出同樣的結果。
diff --git a/app/src/main/assets/scenarios/campaign_cw_03_central_front.scn b/app/src/main/assets/scenarios/campaign_cw_03_central_front.scn
index 0f15ced..1ee0a68 100644
--- a/app/src/main/assets/scenarios/campaign_cw_03_central_front.scn
+++ b/app/src/main/assets/scenarios/campaign_cw_03_central_front.scn
@@ -21,11 +21,11 @@ GBR|nation_gbr|#8C4C4C|0|BALANCED|1200|1,1,1,0,0,1|🇬🇧|NATO|1
NLD|nation_nld|#C4813C|9|TURTLE|500|1,1,1,0,0,1|🇳🇱|NATO|1
BEL|nation_bel|#9E8C4C|8|TURTLE|500|1,1,1,0,0,1|🇧🇪|NATO|1
DNK|nation_dnk|#A85C6E|35|TURTLE|500|1,1,1,0,0,1|🇩🇰|NATO|1
-RUS|nation_sun|#8C6E4C|43|AGGRESSIVE|2200|3,3,3,2,0,3|🇷🇺|PACT|1
+RUS|nation_sun|#8C6E4C|43|AGGRESSIVE|2200|3,3,3,2,0,3|@su|PACT|1
POL|nation_pol|#B4535C|25|AGGRESSIVE|800|1,1,1,0,0,1|🇵🇱|PACT|1
CZE|nation_cze|#8A96A0|24|BALANCED|600|1,1,1,0,0,1|🇨🇿|PACT|1
HUN|nation_hun|#9E7A4C|27|BALANCED|500|1,1,1,0,0,1|🇭🇺|PACT|1
-DDR|nation_ddr|#8C5A5A|19|BALANCED|600|1,1,1,0,0,1||PACT|1
+DDR|nation_ddr|#8C5A5A|19|BALANCED|600|1,1,1,0,0,1|@gdr|PACT|1
CHE|nation_che|#B45C5C|18|TURTLE|500|1,1,1,0,0,1|🇨🇭||1
AUT|nation_aut|#A0A6AC|23|TURTLE|400|1,1,1,0,0,1|🇦🇹||1
SWE|nation_swe|#4C6E9E|32|TURTLE|500|1,1,1,0,0,1|🇸🇪||1
diff --git a/app/src/main/assets/scenarios/campaign_cw_03_central_front_pact.scn b/app/src/main/assets/scenarios/campaign_cw_03_central_front_pact.scn
index 795b561..f9f4457 100644
--- a/app/src/main/assets/scenarios/campaign_cw_03_central_front_pact.scn
+++ b/app/src/main/assets/scenarios/campaign_cw_03_central_front_pact.scn
@@ -21,11 +21,11 @@ GBR|nation_gbr|#8C4C4C|0|BALANCED|1200|1,1,1,0,0,1|🇬🇧|NATO|1
NLD|nation_nld|#C4813C|9|TURTLE|500|1,1,1,0,0,1|🇳🇱|NATO|1
BEL|nation_bel|#9E8C4C|8|TURTLE|500|1,1,1,0,0,1|🇧🇪|NATO|1
DNK|nation_dnk|#A85C6E|35|TURTLE|500|1,1,1,0,0,1|🇩🇰|NATO|1
-RUS|nation_sun|#8C6E4C|43|AGGRESSIVE|2200|3,3,3,2,0,3|🇷🇺|PACT|1
+RUS|nation_sun|#8C6E4C|43|AGGRESSIVE|2200|3,3,3,2,0,3|@su|PACT|1
POL|nation_pol|#B4535C|25|AGGRESSIVE|800|1,1,1,0,0,1|🇵🇱|PACT|1
CZE|nation_cze|#8A96A0|24|BALANCED|600|1,1,1,0,0,1|🇨🇿|PACT|1
HUN|nation_hun|#9E7A4C|27|BALANCED|500|1,1,1,0,0,1|🇭🇺|PACT|1
-DDR|nation_ddr|#8C5A5A|19|BALANCED|600|1,1,1,0,0,1||PACT|1
+DDR|nation_ddr|#8C5A5A|19|BALANCED|600|1,1,1,0,0,1|@gdr|PACT|1
CHE|nation_che|#B45C5C|18|TURTLE|500|1,1,1,0,0,1|🇨🇭||1
AUT|nation_aut|#A0A6AC|23|TURTLE|400|1,1,1,0,0,1|🇦🇹||1
SWE|nation_swe|#4C6E9E|32|TURTLE|500|1,1,1,0,0,1|🇸🇪||1
diff --git a/app/src/main/assets/scenarios/campaign_ww2_01_poland.scn b/app/src/main/assets/scenarios/campaign_ww2_01_poland.scn
index bc49d5f..6481dae 100644
--- a/app/src/main/assets/scenarios/campaign_ww2_01_poland.scn
+++ b/app/src/main/assets/scenarios/campaign_ww2_01_poland.scn
@@ -16,8 +16,8 @@ starTurns 20,23
[nations]
POL|nation_pol|#B4535C|25|BALANCED|700|1,1,1,0,0,1|🇵🇱|ALLIES|1
-DEU|nation_deu|#6E7A86|19|AGGRESSIVE|1500|3,3,2,1,0,2|🇩🇪|AXIS|1
-RUS|nation_sun|#8C6E4C|43|TURTLE|600|1,1,1,0,0,1|🇷🇺||1
+DEU|nation_deu|#6E7A86|19|AGGRESSIVE|1500|3,3,2,1,0,2|@reich|AXIS|1
+RUS|nation_sun|#8C6E4C|43|TURTLE|600|1,1,1,0,0,1|@su||1
SWE|nation_swe|#4C6E9E|32|TURTLE|400|1,1,1,0,0,1|🇸🇪||1
GBR|nation_gbr|#8C4C4C|0|TURTLE|1100|1,1,1,0,0,1|🇬🇧||1
IRL|nation_irl|#4C8C5C|3|TURTLE|260|1,1,1,0,0,1|🇮🇪||1
diff --git a/app/src/main/assets/scenarios/campaign_ww2_01_poland_axis.scn b/app/src/main/assets/scenarios/campaign_ww2_01_poland_axis.scn
index cfd539a..ce5e115 100644
--- a/app/src/main/assets/scenarios/campaign_ww2_01_poland_axis.scn
+++ b/app/src/main/assets/scenarios/campaign_ww2_01_poland_axis.scn
@@ -16,8 +16,8 @@ starTurns 12,16
[nations]
POL|nation_pol|#B4535C|25|TURTLE|700|1,1,1,0,0,1|🇵🇱|ALLIES|1
-DEU|nation_deu|#6E7A86|19|AGGRESSIVE|1500|3,3,2,1,0,2|🇩🇪|AXIS|1
-RUS|nation_sun|#8C6E4C|43|TURTLE|600|1,1,1,0,0,1|🇷🇺||1
+DEU|nation_deu|#6E7A86|19|AGGRESSIVE|1500|3,3,2,1,0,2|@reich|AXIS|1
+RUS|nation_sun|#8C6E4C|43|TURTLE|600|1,1,1,0,0,1|@su||1
SWE|nation_swe|#4C6E9E|32|TURTLE|400|1,1,1,0,0,1|🇸🇪||1
GBR|nation_gbr|#8C4C4C|0|TURTLE|1100|1,1,1,0,0,1|🇬🇧||1
IRL|nation_irl|#4C8C5C|3|TURTLE|260|1,1,1,0,0,1|🇮🇪||1
diff --git a/app/src/main/assets/scenarios/campaign_ww2_02_france.scn b/app/src/main/assets/scenarios/campaign_ww2_02_france.scn
index 1c23727..789258d 100644
--- a/app/src/main/assets/scenarios/campaign_ww2_02_france.scn
+++ b/app/src/main/assets/scenarios/campaign_ww2_02_france.scn
@@ -15,7 +15,7 @@ startYear 1940
starTurns 16,22
[nations]
-DEU|nation_deu|#6E7A86|19|AGGRESSIVE|1600|3,3,2,1,0,2|🇩🇪|AXIS|1
+DEU|nation_deu|#6E7A86|19|AGGRESSIVE|1600|3,3,2,1,0,2|@reich|AXIS|1
FRA|nation_fra|#4C5C9E|5|TURTLE|1100|2,1,2,0,0,1|🇫🇷|ALLIES|1
GBR|nation_gbr|#8C4C4C|0|BALANCED|1000|1,1,1,0,0,1|🇬🇧|ALLIES|1
BEL|nation_bel|#9E8C4C|8|TURTLE|400|1,1,1,0,0,1|🇧🇪|ALLIES|1
@@ -35,7 +35,7 @@ SWE|nation_swe|#4C6E9E|32|TURTLE|420|1,1,1,0,0,1|🇸🇪||1
NOR|nation_nor|#5C7EA8|34|TURTLE|380|1,1,1,0,0,1|🇳🇴||1
DNK|nation_dnk|#A85C6E|35|TURTLE|320|1,1,1,0,0,1|🇩🇰||1
FIN|nation_fin|#7A9EB4|37|TURTLE|320|1,1,1,0,0,1|🇫🇮||1
-RUS|nation_sun|#8C6E4C|43|TURTLE|1500|1,1,1,0,0,1|🇷🇺||1
+RUS|nation_sun|#8C6E4C|43|TURTLE|1500|1,1,1,0,0,1|@su||1
TUR|nation_tur|#A84C4C|46|TURTLE|740|1,1,1,0,0,1|🇹🇷||1
[relations]
diff --git a/app/src/main/assets/scenarios/campaign_ww2_02_france_allies.scn b/app/src/main/assets/scenarios/campaign_ww2_02_france_allies.scn
index e53079e..aa5f8ad 100644
--- a/app/src/main/assets/scenarios/campaign_ww2_02_france_allies.scn
+++ b/app/src/main/assets/scenarios/campaign_ww2_02_france_allies.scn
@@ -15,7 +15,7 @@ startYear 1940
starTurns 20,23
[nations]
-DEU|nation_deu|#6E7A86|19|AGGRESSIVE|1600|3,3,2,1,0,2|🇩🇪|AXIS|1
+DEU|nation_deu|#6E7A86|19|AGGRESSIVE|1600|3,3,2,1,0,2|@reich|AXIS|1
FRA|nation_fra|#4C5C9E|5|TURTLE|1100|2,1,2,0,0,1|🇫🇷|ALLIES|1
GBR|nation_gbr|#8C4C4C|0|BALANCED|1000|1,1,1,0,0,1|🇬🇧|ALLIES|1
BEL|nation_bel|#9E8C4C|8|TURTLE|400|1,1,1,0,0,1|🇧🇪|ALLIES|1
@@ -35,7 +35,7 @@ SWE|nation_swe|#4C6E9E|32|TURTLE|420|1,1,1,0,0,1|🇸🇪||1
NOR|nation_nor|#5C7EA8|34|TURTLE|380|1,1,1,0,0,1|🇳🇴||1
DNK|nation_dnk|#A85C6E|35|TURTLE|320|1,1,1,0,0,1|🇩🇰||1
FIN|nation_fin|#7A9EB4|37|TURTLE|320|1,1,1,0,0,1|🇫🇮||1
-RUS|nation_sun|#8C6E4C|43|TURTLE|1500|1,1,1,0,0,1|🇷🇺||1
+RUS|nation_sun|#8C6E4C|43|TURTLE|1500|1,1,1,0,0,1|@su||1
TUR|nation_tur|#A84C4C|46|TURTLE|740|1,1,1,0,0,1|🇹🇷||1
[relations]
diff --git a/app/src/main/assets/scenarios/campaign_ww2_03_desert.scn b/app/src/main/assets/scenarios/campaign_ww2_03_desert.scn
index 76d8c62..547e2ea 100644
--- a/app/src/main/assets/scenarios/campaign_ww2_03_desert.scn
+++ b/app/src/main/assets/scenarios/campaign_ww2_03_desert.scn
@@ -17,7 +17,7 @@ starTurns 20,28
[nations]
GBR|nation_gbr|#8C4C4C|9|BALANCED|1300|1,1,1,0,0,1|🇬🇧|ALLIES|1
ITA|nation_ita|#5C9E6E|12|BALANCED|800|1,1,1,0,0,1|🇮🇹|AXIS|1
-DEU|nation_deu|#6E7A86|13|AGGRESSIVE|1000|1,1,1,0,0,1|🇩🇪|AXIS|1
+DEU|nation_deu|#6E7A86|13|AGGRESSIVE|1000|1,1,1,0,0,1|@reich|AXIS|1
TUR|nation_tur|#A84C4C|4|TURTLE|500|1,1,1,0,0,1|🇹🇷||1
ESP|nation_esp|#B08A3C|0|TURTLE|500|1,1,1,0,0,1|🇪🇸||1
PRT|nation_prt|#4C8C7A|2|TURTLE|300|1,1,1,0,0,1|🇵🇹||1
diff --git a/app/src/main/assets/scenarios/campaign_ww2_03_desert_axis.scn b/app/src/main/assets/scenarios/campaign_ww2_03_desert_axis.scn
index 819f76e..38fdb12 100644
--- a/app/src/main/assets/scenarios/campaign_ww2_03_desert_axis.scn
+++ b/app/src/main/assets/scenarios/campaign_ww2_03_desert_axis.scn
@@ -17,7 +17,7 @@ starTurns 24,32
[nations]
GBR|nation_gbr|#8C4C4C|9|BALANCED|1300|1,1,1,0,0,1|🇬🇧|ALLIES|1
ITA|nation_ita|#5C9E6E|12|BALANCED|800|1,1,1,0,0,1|🇮🇹|AXIS|1
-DEU|nation_deu|#6E7A86|13|AGGRESSIVE|1000|1,1,1,0,0,1|🇩🇪|AXIS|1
+DEU|nation_deu|#6E7A86|13|AGGRESSIVE|1000|1,1,1,0,0,1|@reich|AXIS|1
TUR|nation_tur|#A84C4C|4|TURTLE|500|1,1,1,0,0,1|🇹🇷||1
ESP|nation_esp|#B08A3C|0|TURTLE|500|1,1,1,0,0,1|🇪🇸||1
PRT|nation_prt|#4C8C7A|2|TURTLE|300|1,1,1,0,0,1|🇵🇹||1
diff --git a/app/src/main/assets/scenarios/campaign_ww2_05_east_front.scn b/app/src/main/assets/scenarios/campaign_ww2_05_east_front.scn
index fdcefd1..7174a34 100644
--- a/app/src/main/assets/scenarios/campaign_ww2_05_east_front.scn
+++ b/app/src/main/assets/scenarios/campaign_ww2_05_east_front.scn
@@ -15,8 +15,8 @@ startYear 1943
starTurns 24,32
[nations]
-RUS|nation_sun|#8C6E4C|15|AGGRESSIVE|1800|2,2,1,0,0,2|🇷🇺|ALLIES|1
-DEU|nation_deu|#6E7A86|3|OPPORTUNIST|1600|3,3,2,1,0,2|🇩🇪|AXIS|1
+RUS|nation_sun|#8C6E4C|15|AGGRESSIVE|1800|2,2,1,0,0,2|@su|ALLIES|1
+DEU|nation_deu|#6E7A86|3|OPPORTUNIST|1600|3,3,2,1,0,2|@reich|AXIS|1
TUR|nation_tur|#A84C4C|23|TURTLE|500|1,1,1,0,0,1|🇹🇷||1
SWE|nation_swe|#4C6E9E|9|TURTLE|400|1,1,1,0,0,1|🇸🇪||1
ITA|nation_ita|#5C9E6E|0|TURTLE|700|1,1,1,0,0,1|🇮🇹||1
diff --git a/app/src/main/assets/scenarios/campaign_ww2_05_east_front_axis.scn b/app/src/main/assets/scenarios/campaign_ww2_05_east_front_axis.scn
index e19be3f..6d7f000 100644
--- a/app/src/main/assets/scenarios/campaign_ww2_05_east_front_axis.scn
+++ b/app/src/main/assets/scenarios/campaign_ww2_05_east_front_axis.scn
@@ -15,8 +15,8 @@ startYear 1943
starTurns 28,31
[nations]
-RUS|nation_sun|#8C6E4C|15|AGGRESSIVE|1800|2,2,1,0,0,2|🇷🇺|ALLIES|1
-DEU|nation_deu|#6E7A86|3|OPPORTUNIST|1600|3,3,2,1,0,2|🇩🇪|AXIS|1
+RUS|nation_sun|#8C6E4C|15|AGGRESSIVE|1800|2,2,1,0,0,2|@su|ALLIES|1
+DEU|nation_deu|#6E7A86|3|OPPORTUNIST|1600|3,3,2,1,0,2|@reich|AXIS|1
TUR|nation_tur|#A84C4C|23|TURTLE|500|1,1,1,0,0,1|🇹🇷||1
SWE|nation_swe|#4C6E9E|9|TURTLE|400|1,1,1,0,0,1|🇸🇪||1
ITA|nation_ita|#5C9E6E|0|TURTLE|700|1,1,1,0,0,1|🇮🇹||1
diff --git a/app/src/main/assets/scenarios/conquest_1939.scn b/app/src/main/assets/scenarios/conquest_1939.scn
index eed337a..d1225a6 100644
--- a/app/src/main/assets/scenarios/conquest_1939.scn
+++ b/app/src/main/assets/scenarios/conquest_1939.scn
@@ -13,13 +13,13 @@ startYear 1939
startMonth 9
[nations]
-RUS|nation_sun|#8C6E4C|50|AGGRESSIVE|3900|2,2,2,2,2,1|🇷🇺|ALLIES|8
+RUS|nation_sun|#8C6E4C|50|AGGRESSIVE|3900|2,2,2,2,2,1|@su|ALLIES|8
GBR|nation_gbr|#8C4C4C|0|BALANCED|3575|2,2,2,2,2,1|🇬🇧|ALLIES|1
USA|nation_usa|#4C7BA8|182|BALANCED|3200|2,2,2,2,2,1|🇺🇸|ALLIES|10
JPN|nation_jpn|#C45C5C|159|BALANCED|1980|2,2,2,2,2,1|🇯🇵|AXIS|1
ROC|nation_chn|#B4454C|138|BALANCED|1760|2,2,2,2,2,1|🇹🇼|ALLIES|1
FRA|nation_fra|#4C5C9E|5|BALANCED|1757|2,2,2,2,2,1|🇫🇷|ALLIES|1
-DEU|nation_deu|#6E7A86|19|AGGRESSIVE|1495|2,2,2,2,2,1|🇩🇪|AXIS|1
+DEU|nation_deu|#6E7A86|19|AGGRESSIVE|1495|2,2,2,2,2,1|@reich|AXIS|1
BRA|nation_bra|#4F9A50|236|TURTLE|1260|1,1,1,1,1,1|🇧🇷||1
AUS|nation_aus|#C4A05C|244|BALANCED|1189|1,1,1,1,1,1|🇦🇺|ALLIES|1
CAN|nation_can|#6E93B5|200|TURTLE|979|1,1,1,1,1,1|🇨🇦|ALLIES|1
diff --git a/app/src/main/assets/scenarios/conquest_1943.scn b/app/src/main/assets/scenarios/conquest_1943.scn
index 9835a90..fe8060a 100644
--- a/app/src/main/assets/scenarios/conquest_1943.scn
+++ b/app/src/main/assets/scenarios/conquest_1943.scn
@@ -13,11 +13,11 @@ startYear 1943
startMonth 3
[nations]
-RUS|nation_sun|#8C6E4C|50|AGGRESSIVE|3600|2,2,2,2,2,1|🇷🇺|ALLIES|1
+RUS|nation_sun|#8C6E4C|50|AGGRESSIVE|3600|2,2,2,2,2,1|@su|ALLIES|1
GBR|nation_gbr|#8C4C4C|0|BALANCED|3465|2,2,2,2,2,1|🇬🇧|ALLIES|1
JPN|nation_jpn|#C45C5C|138|BALANCED|3240|2,2,2,2,2,1|🇯🇵|AXIS|1
USA|nation_usa|#4C7BA8|182|BALANCED|3040|2,2,2,2,2,1|🇺🇸|ALLIES|1
-DEU|nation_deu|#6E7A86|5|AGGRESSIVE|2645|2,2,2,2,2,1|🇩🇪|AXIS|1
+DEU|nation_deu|#6E7A86|5|AGGRESSIVE|2645|2,2,2,2,2,1|@reich|AXIS|1
ROC|nation_chn|#B4454C|142|BALANCED|1485|2,2,2,2,2,1|🇹🇼|ALLIES|1
FRA|nation_fra|#4C5C9E|85|BALANCED|1425|2,2,2,2,2,1|🇫🇷|ALLIES|1
BRA|nation_bra|#4F9A50|236|TURTLE|1260|1,1,1,1,1,1|🇧🇷||1
diff --git a/app/src/main/assets/scenarios/conquest_1950.scn b/app/src/main/assets/scenarios/conquest_1950.scn
index 531ded5..5d9b804 100644
--- a/app/src/main/assets/scenarios/conquest_1950.scn
+++ b/app/src/main/assets/scenarios/conquest_1950.scn
@@ -13,7 +13,7 @@ startYear 1950
startMonth 1
[nations]
-RUS|nation_sun|#8C6E4C|50|AGGRESSIVE|3824|2,2,2,2,2,1|🇷🇺|EAST|1
+RUS|nation_sun|#8C6E4C|50|AGGRESSIVE|3824|2,2,2,2,2,1|@su|EAST|1
USA|nation_usa|#4C7BA8|182|BALANCED|3040|2,2,2,2,2,1|🇺🇸|WEST|1
CHN|nation_prc|#B4454C|138|BALANCED|2890|2,2,2,2,2,1|🇨🇳|EAST|1
GBR|nation_gbr|#8C4C4C|0|BALANCED|2310|2,2,2,2,2,1|🇬🇧|WEST|1
@@ -31,7 +31,7 @@ ITA|nation_ita|#5C9E6E|15|OPPORTUNIST|840|1,1,0,0,0,1|🇮🇹|WEST|1
IRN|nation_irn|#4C8C6E|80|TURTLE|804|1,1,0,0,0,1|🇮🇷||1
EGY|nation_egy|#C4A84C|93|TURTLE|736|1,1,0,0,0,1|🇪🇬||1
ZAF|nation_zaf|#4C7A5C|121|TURTLE|736|1,1,0,0,0,1|🇿🇦||1
-DDR|nation_ddr|#8C5A5A|19|BALANCED|735|1,1,0,0,0,1||EAST|1
+DDR|nation_ddr|#8C5A5A|19|BALANCED|735|1,1,0,0,0,1|🇩🇪|EAST|1
ARG|nation_arg|#6FA8C4|230|TURTLE|720|1,1,0,0,0,1|🇦🇷||1
MEX|nation_mex|#3F8F6B|209|TURTLE|720|1,1,0,0,0,1|🇲🇽||1
KOR|nation_kor|#5C9EB4|155|TURTLE|682|1,1,0,0,0,1|🇰🇷|WEST|1
diff --git a/app/src/main/assets/scenarios/conquest_1980.scn b/app/src/main/assets/scenarios/conquest_1980.scn
index f3b8483..403f210 100644
--- a/app/src/main/assets/scenarios/conquest_1980.scn
+++ b/app/src/main/assets/scenarios/conquest_1980.scn
@@ -13,7 +13,7 @@ startYear 1980
startMonth 1
[nations]
-RUS|nation_sun|#8C6E4C|50|AGGRESSIVE|3824|2,2,2,2,2,1|🇷🇺|PACT|1
+RUS|nation_sun|#8C6E4C|50|AGGRESSIVE|3824|2,2,2,2,2,1|@su|PACT|1
USA|nation_usa|#4C7BA8|182|BALANCED|3040|2,2,2,2,2,1|🇺🇸|NATO|1
CHN|nation_prc|#B4454C|138|TURTLE|2890|2,2,2,2,2,1|🇨🇳||1
IND|nation_ind|#C4864C|125|TURTLE|1610|2,2,2,2,2,1|🇮🇳||1
@@ -31,7 +31,7 @@ IRN|nation_irn|#4C8C6E|80|TURTLE|804|1,1,0,0,0,1|🇮🇷||1
ITA|nation_ita|#5C9E6E|15|OPPORTUNIST|804|1,1,0,0,0,1|🇮🇹|NATO|1
EGY|nation_egy|#C4A84C|93|TURTLE|736|1,1,0,0,0,1|🇪🇬||1
ZAF|nation_zaf|#4C7A5C|121|TURTLE|736|1,1,0,0,0,1|🇿🇦||1
-DDR|nation_ddr|#8C5A5A|19|BALANCED|735|1,1,0,0,0,1||PACT|1
+DDR|nation_ddr|#8C5A5A|19|BALANCED|735|1,1,0,0,0,1|@gdr|PACT|1
ARG|nation_arg|#6FA8C4|230|TURTLE|720|1,1,0,0,0,1|🇦🇷||1
MEX|nation_mex|#3F8F6B|209|TURTLE|720|1,1,0,0,0,1|🇲🇽||1
KOR|nation_kor|#5C9EB4|155|TURTLE|682|1,1,0,0,0,1|🇰🇷||1
diff --git a/app/src/main/java/io/github/acidefluorhydrique/mapconquer/render/FlagArt.kt b/app/src/main/java/io/github/acidefluorhydrique/mapconquer/render/FlagArt.kt
new file mode 100644
index 0000000..aff9834
--- /dev/null
+++ b/app/src/main/java/io/github/acidefluorhydrique/mapconquer/render/FlagArt.kt
@@ -0,0 +1,347 @@
+// SPDX-FileCopyrightText: 2026 AcideFluorhydrique
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+package io.github.acidefluorhydrique.mapconquer.render
+
+import android.graphics.Bitmap
+import android.graphics.Canvas
+import android.graphics.LinearGradient
+import android.graphics.Paint
+import android.graphics.Path
+import android.graphics.PorterDuff
+import android.graphics.PorterDuffXfermode
+import android.graphics.Rect
+import android.graphics.RectF
+import android.graphics.Shader
+import io.github.acidefluorhydrique.mapconquer.core.Colors
+import io.github.acidefluorhydrique.mapconquer.core.Widgets
+import kotlin.math.PI
+import kotlin.math.ceil
+import kotlin.math.cos
+import kotlin.math.max
+import kotlin.math.roundToInt
+import kotlin.math.sin
+
+/**
+ * 國旗:emoji 交給系統字型,emoji 裡沒有的由這裡自己畫。
+ *
+ * 劇本檔的國旗欄位是一段 emoji,或是一個以 `@` 開頭的代號(見 tools/places.py
+ * 的 flag_for)。代號對應的是 emoji 字型裡不存在的歷史國旗:蘇聯、東德、
+ * 以及用鐵十字代替的納粹德國。
+ *
+ * 自己畫的國旗要跟旁邊的 emoji 國旗放在一起而不顯突兀,所以模仿的是 Android
+ * 預設 emoji 字型的樣子:同樣的外框大小、上下緣一道波浪、一層淡淡的光影與
+ * 一圈半透明的邊。尺寸不是寫死的,而是拿一面真的 emoji 國旗量出來 ——
+ * 字級改了、裝置換了,兩者仍然一樣大。
+ *
+ * 所有呼叫端都走這裡而不是直接畫文字,介面刻意跟 [Widgets] 的文字函式對齊。
+ *
+ * 畫好的旗幟依像素尺寸快取成點陣圖:地圖上一個畫面就有上百枚城市徽章,
+ * 每一幀重畫波浪與光影負擔不起。尺寸先量化再快取,縮放地圖時才不會
+ * 每一幀都產生新的點陣圖。
+ */
+object FlagArt {
+
+ /** 量尺寸用的 emoji 國旗。任何一面都行,emoji 字型裡的國旗外框全部一樣大。 */
+ private const val REFERENCE = "🇩🇪"
+
+ private const val SOVIET = "@su"
+ private const val REICH = "@reich"
+ private const val GDR = "@gdr"
+
+ /** 旗面的長寬比。預設 emoji 字型把每一面國旗都塞進同一個外框。 */
+ private const val ASPECT = 0.68f
+
+ private const val CACHE_LIMIT = 32
+
+ private val measurePaint = Paint(Paint.ANTI_ALIAS_FLAG)
+ private val bounds = Rect()
+ private val dst = RectF()
+ private val blit = Paint(Paint.FILTER_BITMAP_FLAG or Paint.ANTI_ALIAS_FLAG)
+ private val cache = object : LinkedHashMap(16, 0.75f, true) {
+ override fun removeEldestEntry(eldest: MutableMap.MutableEntry?): Boolean =
+ size > CACHE_LIMIT
+ }
+
+ fun isDrawn(flag: String): Boolean = flag.startsWith("@")
+
+ /** 對應 [Widgets.measure]:這面旗在 [size] 字級下佔的寬度。 */
+ fun measure(flag: String, size: Float): Float =
+ Widgets.measure(if (isDrawn(flag)) REFERENCE else flag, size)
+
+ /** 對應 [Widgets.left]。 */
+ fun left(canvas: Canvas, flag: String, x: Float, baselineY: Float, size: Float, color: Int = INK) {
+ if (isDrawn(flag)) draw(canvas, flag, x, baselineY, size)
+ else Widgets.left(canvas, flag, x, baselineY, size, color)
+ }
+
+ /** 對應 [Widgets.centered]。 */
+ fun centered(canvas: Canvas, flag: String, centerX: Float, baselineY: Float, size: Float, color: Int = INK) {
+ if (isDrawn(flag)) draw(canvas, flag, centerX - measure(flag, size) / 2f, baselineY, size)
+ else Widgets.centered(canvas, flag, centerX, baselineY, size, color = color)
+ }
+
+ /** 對應 [Widgets.centeredFit]:放不下 [maxWidth] 就縮小字級。 */
+ fun centeredFit(
+ canvas: Canvas,
+ flag: String,
+ centerX: Float,
+ baselineY: Float,
+ size: Float,
+ maxWidth: Float,
+ color: Int = INK
+ ) {
+ val width = measure(flag, size)
+ val fitted = if (width > maxWidth && width > 0f) size * maxWidth / width else size
+ centered(canvas, flag, centerX, baselineY, fitted, color)
+ }
+
+ private val INK: Int get() = Colors.of(Widgets.INK)
+
+ // ------------------------------------------------------------------
+ // 定位與快取
+ // ------------------------------------------------------------------
+
+ /** 把旗幟畫在一個 emoji 字元會佔的位置上:[left] 是字元左緣,[baselineY] 是基線。 */
+ private fun draw(canvas: Canvas, flag: String, left: Float, baselineY: Float, size: Float) {
+ if (size <= 0f) return
+ measurePaint.textSize = size
+ measurePaint.getTextBounds(REFERENCE, 0, REFERENCE.length, bounds)
+ val advance = measure(flag, size)
+ // emoji 的字框比旗面大一圈:旗面左右各留一點邊,垂直置中在字框裡。
+ val width = advance * 0.92f
+ val pixelWidth = max(8, (ceil(width / 4f) * 4f).toInt())
+ val bitmap = composed(flag, pixelWidth) ?: return
+ val height = width * bitmap.height / bitmap.width
+ val centerY = baselineY + bounds.exactCenterY()
+ val x = left + (advance - width) / 2f
+ dst.set(x, centerY - height / 2f, x + width, centerY + height / 2f)
+ canvas.drawBitmap(bitmap, null, dst, blit)
+ }
+
+ private fun composed(flag: String, pixelWidth: Int): Bitmap? {
+ val key = "$flag:$pixelWidth"
+ cache[key]?.let { return it }
+ val design = designFor(flag) ?: return null
+ val bitmap = wave(pixelWidth, design)
+ cache[key] = bitmap
+ return bitmap
+ }
+
+ // ------------------------------------------------------------------
+ // 波浪、光影與邊框
+ // ------------------------------------------------------------------
+
+ /**
+ * 先把平的旗面畫好,再用網格把它貼成一道波浪。波浪的振幅、光影與邊框
+ * 都是照預設 emoji 國旗的樣子估的:上下緣起伏一次、光從左上來、
+ * 邊緣有一圈很淡的深色。
+ */
+ private fun wave(width: Int, design: (Canvas, Float, Float) -> Unit): Bitmap {
+ val body = max(6, (width * ASPECT).roundToInt())
+ val amp = max(1f, body * 0.055f)
+ val height = body + (amp * 2f).roundToInt() + 2
+
+ val flat = Bitmap.createBitmap(width, body, Bitmap.Config.ARGB_8888)
+ design(Canvas(flat), width.toFloat(), body.toFloat())
+
+ val out = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
+ val canvas = Canvas(out)
+ val columns = 16
+ val verts = FloatArray((columns + 1) * 2 * 2)
+ val top = FloatArray(columns + 1)
+ for (i in 0..columns) {
+ val t = i / columns.toFloat()
+ val x = t * width
+ val y = 1f + amp + amp * sin((t * 1.6f - 0.3f) * PI.toFloat())
+ top[i] = y
+ verts[i * 2] = x
+ verts[i * 2 + 1] = y
+ verts[(columns + 1 + i) * 2] = x
+ verts[(columns + 1 + i) * 2 + 1] = y + body
+ }
+ canvas.drawBitmapMesh(flat, columns, 1, verts, 0, null, 0, blit)
+ flat.recycle()
+
+ // 光影:沿著波浪明暗交替,只蓋在旗面上(SRC_ATOP)。
+ val shade = Paint(Paint.ANTI_ALIAS_FLAG)
+ shade.shader = LinearGradient(
+ 0f, 0f, width.toFloat(), 0f,
+ intArrayOf(
+ Colors.of("#26FFFFFF"), Colors.of("#00FFFFFF"), Colors.of("#1F000000"),
+ Colors.of("#00000000"), Colors.of("#1AFFFFFF"), Colors.of("#14000000")
+ ),
+ floatArrayOf(0f, 0.22f, 0.45f, 0.62f, 0.8f, 1f),
+ Shader.TileMode.CLAMP
+ )
+ shade.xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP)
+ canvas.drawRect(0f, 0f, width.toFloat(), height.toFloat(), shade)
+
+ val edge = Path()
+ edge.moveTo(0f, top[0])
+ for (i in 1..columns) edge.lineTo(verts[i * 2], top[i])
+ for (i in columns downTo 0) edge.lineTo(verts[i * 2], top[i] + body)
+ edge.close()
+ val stroke = Paint(Paint.ANTI_ALIAS_FLAG)
+ stroke.style = Paint.Style.STROKE
+ stroke.strokeWidth = max(1f, width / 40f)
+ stroke.strokeJoin = Paint.Join.ROUND
+ stroke.color = Colors.of("#40000000")
+ canvas.drawPath(edge, stroke)
+ return out
+ }
+
+ // ------------------------------------------------------------------
+ // 旗面(平的,寬 w、高 h)
+ // ------------------------------------------------------------------
+
+ private fun designFor(flag: String): ((Canvas, Float, Float) -> Unit)? = when (flag) {
+ SOVIET -> this::soviet
+ REICH -> this::ironCross
+ GDR -> this::gdr
+ else -> null
+ }
+
+ private val GOLD = "#FFD24A"
+
+ /** 蘇聯:紅底,左上角一顆描邊的星、底下交叉的鐮刀與錘子。 */
+ private fun soviet(canvas: Canvas, w: Float, h: Float) {
+ val paint = Paint(Paint.ANTI_ALIAS_FLAG)
+ paint.color = Colors.of("#D22B20")
+ canvas.drawRect(0f, 0f, w, h, paint)
+
+ paint.color = Colors.of(GOLD)
+ paint.style = Paint.Style.STROKE
+ paint.strokeJoin = Paint.Join.MITER
+ paint.strokeWidth = h * 0.028f
+ canvas.drawPath(star(w * 0.2f, h * 0.17f, h * 0.085f), paint)
+
+ val cx = w * 0.2f
+ val cy = h * 0.47f
+ val s = h * 0.34f
+ paint.strokeCap = Paint.Cap.ROUND
+ // 鐮刀:大半個圓弧,開口朝右上,底端接一小段刀柄。
+ paint.strokeWidth = s * 0.13f
+ val r = s * 0.36f
+ val arc = RectF(cx - r, cy - r - s * 0.04f, cx + r, cy + r - s * 0.04f)
+ canvas.drawArc(arc, -40f, 250f, false, paint)
+ val endAngle = Math.toRadians(210.0)
+ val ex = cx + r * cos(endAngle).toFloat()
+ val ey = cy - s * 0.04f + r * sin(endAngle).toFloat()
+ canvas.drawLine(ex, ey, ex - s * 0.12f, ey + s * 0.34f, paint)
+ // 錘子:柄從左下斜向右上,頭垂直於柄。
+ paint.strokeWidth = s * 0.11f
+ val hx0 = cx - s * 0.32f
+ val hy0 = cy + s * 0.38f
+ val hx1 = cx + s * 0.2f
+ val hy1 = cy - s * 0.16f
+ canvas.drawLine(hx0, hy0, hx1, hy1, paint)
+ paint.strokeCap = Paint.Cap.BUTT
+ paint.strokeWidth = s * 0.17f
+ val dx = (hx1 - hx0)
+ val dy = (hy1 - hy0)
+ val len = kotlin.math.sqrt(dx * dx + dy * dy)
+ val px = -dy / len * s * 0.2f
+ val py = dx / len * s * 0.2f
+ canvas.drawLine(hx1 - px, hy1 - py, hx1 + px, hy1 + py, paint)
+ }
+
+ /**
+ * 納粹德國:史實是卐字旗。這裡刻意改用德軍的鐵十字 —— 原野灰底、
+ * 黑色的十字四臂向外張開,外面一圈白邊。底色要夠深,白邊才看得見;
+ * 白底的版本在地圖徽章的尺寸下會糊成兩個括號。
+ */
+ private fun ironCross(canvas: Canvas, w: Float, h: Float) {
+ val paint = Paint(Paint.ANTI_ALIAS_FLAG)
+ paint.color = Colors.of("#6E7562")
+ canvas.drawRect(0f, 0f, w, h, paint)
+
+ val cx = w / 2f
+ val cy = h / 2f
+ val size = h * 0.84f
+ paint.color = Colors.of("#F4F4F2")
+ canvas.drawPath(crossPattee(cx, cy, size * 1.13f), paint)
+ paint.color = Colors.of("#141414")
+ canvas.drawPath(crossPattee(cx, cy, size * 0.9f), paint)
+ }
+
+ /**
+ * 東德(1959 年起):黑紅金三色,中間是麥穗環圍著錘子與圓規。
+ * 1959 年以前的東德國旗跟西德一樣,那一段直接用 emoji(見 places.flag_for)。
+ */
+ private fun gdr(canvas: Canvas, w: Float, h: Float) {
+ val paint = Paint(Paint.ANTI_ALIAS_FLAG)
+ val band = h / 3f
+ paint.color = Colors.of("#1A1A1A")
+ canvas.drawRect(0f, 0f, w, band, paint)
+ paint.color = Colors.of("#DD0000")
+ canvas.drawRect(0f, band, w, band * 2f, paint)
+ paint.color = Colors.of("#FFCE00")
+ canvas.drawRect(0f, band * 2f, w, h, paint)
+
+ val cx = w / 2f
+ val cy = h / 2f
+ val r = h * 0.3f
+ paint.style = Paint.Style.STROKE
+ paint.strokeCap = Paint.Cap.ROUND
+ // 麥穗環:一圈底部開口的金色弧線,外側再描一圈深色讓它在金色帶上也看得見。
+ val ring = RectF(cx - r, cy - r, cx + r, cy + r)
+ paint.strokeWidth = r * 0.26f
+ paint.color = Colors.of("#8A6A00")
+ canvas.drawArc(ring, 120f, 300f, false, paint)
+ paint.strokeWidth = r * 0.18f
+ paint.color = Colors.of("#F2C200")
+ canvas.drawArc(ring, 120f, 300f, false, paint)
+ // 圓規:倒 V,頂端一個小圓。
+ paint.strokeWidth = r * 0.12f
+ paint.color = Colors.of("#FFD84D")
+ canvas.drawLine(cx, cy - r * 0.55f, cx - r * 0.4f, cy + r * 0.5f, paint)
+ canvas.drawLine(cx, cy - r * 0.55f, cx + r * 0.4f, cy + r * 0.5f, paint)
+ // 錘子:直立的柄,頂端一塊橫的錘頭。
+ paint.strokeWidth = r * 0.12f
+ canvas.drawLine(cx, cy - r * 0.35f, cx, cy + r * 0.55f, paint)
+ paint.strokeCap = Paint.Cap.BUTT
+ paint.strokeWidth = r * 0.2f
+ canvas.drawLine(cx - r * 0.28f, cy - r * 0.42f, cx + r * 0.28f, cy - r * 0.42f, paint)
+ }
+
+ // ------------------------------------------------------------------
+ // 幾何
+ // ------------------------------------------------------------------
+
+ private fun star(cx: Float, cy: Float, r: Float): Path {
+ val path = Path()
+ for (i in 0 until 10) {
+ val radius = if (i % 2 == 0) r else r * 0.42f
+ val angle = -PI / 2 + i * PI / 5
+ val x = cx + radius * cos(angle).toFloat()
+ val y = cy + radius * sin(angle).toFloat()
+ if (i == 0) path.moveTo(x, y) else path.lineTo(x, y)
+ }
+ path.close()
+ return path
+ }
+
+ /** 四臂向外張開的十字(鐵十字的形狀),外接正方形邊長 [size]。 */
+ private fun crossPattee(cx: Float, cy: Float, size: Float): Path {
+ val half = size / 2f
+ val inner = size * 0.13f
+ val outer = size * 0.27f
+ val path = Path()
+ // 從上臂右側開始,順時針繞一圈;每一臂在中心窄、在外端寬。
+ path.moveTo(cx + inner, cy - inner)
+ path.lineTo(cx + outer, cy - half)
+ path.lineTo(cx - outer, cy - half)
+ path.lineTo(cx - inner, cy - inner)
+ path.lineTo(cx - half, cy - outer)
+ path.lineTo(cx - half, cy + outer)
+ path.lineTo(cx - inner, cy + inner)
+ path.lineTo(cx - outer, cy + half)
+ path.lineTo(cx + outer, cy + half)
+ path.lineTo(cx + inner, cy + inner)
+ path.lineTo(cx + half, cy + outer)
+ path.lineTo(cx + half, cy - outer)
+ path.close()
+ return path
+ }
+}
diff --git a/app/src/main/java/io/github/acidefluorhydrique/mapconquer/render/HudRenderer.kt b/app/src/main/java/io/github/acidefluorhydrique/mapconquer/render/HudRenderer.kt
index 9b5976a..f60784f 100644
--- a/app/src/main/java/io/github/acidefluorhydrique/mapconquer/render/HudRenderer.kt
+++ b/app/src/main/java/io/github/acidefluorhydrique/mapconquer/render/HudRenderer.kt
@@ -65,8 +65,8 @@ class HudRenderer(private val session: Session) {
// 國旗 + 國色塊:emoji 認國家,色塊對應地圖上的領土色,兩者互補。
var x = pad
if (nation.flag.isNotEmpty()) {
- Widgets.left(canvas, nation.flag, x, h * 0.68f, Ui.dp(15f), Colors.of(Widgets.INK))
- x += Widgets.measure(nation.flag, Ui.dp(15f)) + Ui.dp(5f)
+ FlagArt.left(canvas, nation.flag, x, h * 0.68f, Ui.dp(15f), Colors.of(Widgets.INK))
+ x += FlagArt.measure(nation.flag, Ui.dp(15f)) + Ui.dp(5f)
}
rect.set(x, h * 0.28f, x + Ui.dp(5f), h * 0.72f)
Widgets.fill(canvas, rect, Palette.nationColour(session, nation.id), Ui.dp(2f))
@@ -225,13 +225,20 @@ class HudRenderer(private val session: Session) {
if (province != null) {
val owner = session.provinceOwner[province.id]
+ // 國旗與國名分開畫:自製的國旗(蘇聯、東德……)不是文字,塞不進字串裡。
+ var nameX = x
val ownerName = if (owner >= 0) {
val n = session.nations[owner]
- (if (n.flag.isEmpty()) "" else n.flag + " ") + Strings.byName(n.nameKey)
+ if (n.flag.isNotEmpty()) {
+ FlagArt.left(canvas, n.flag, nameX, top + Ui.dp(45f), Ui.dp(10.5f))
+ nameX += FlagArt.measure(n.flag, Ui.dp(10.5f)) + Ui.dp(3f)
+ }
+ Strings.byName(n.nameKey)
} else {
Strings.get(R.string.hud_neutral)
}
- Widgets.leftFit(canvas, ownerName, x, top + Ui.dp(45f), Ui.dp(10.5f), Ui.dp(130f),
+ Widgets.leftFit(canvas, ownerName, nameX, top + Ui.dp(45f), Ui.dp(10.5f),
+ Ui.dp(130f) - (nameX - x),
if (owner >= 0) Palette.nationColour(session, owner) else dim)
// 城防:玩家得看得到還要磨幾回合,不然「打不下來」會像是壞掉。
diff --git a/app/src/main/java/io/github/acidefluorhydrique/mapconquer/render/MapRenderer.kt b/app/src/main/java/io/github/acidefluorhydrique/mapconquer/render/MapRenderer.kt
index e75f80f..230fdef 100644
--- a/app/src/main/java/io/github/acidefluorhydrique/mapconquer/render/MapRenderer.kt
+++ b/app/src/main/java/io/github/acidefluorhydrique/mapconquer/render/MapRenderer.kt
@@ -324,7 +324,7 @@ class MapRenderer(private val session: Session) {
paint.style = Paint.Style.FILL
if (flag.isNotEmpty() && plateH >= Ui.dp(7f)) {
- Widgets.centeredFit(
+ FlagArt.centeredFit(
canvas, flag, cx, cy + plateH * 0.36f,
plateH * 0.94f, plateW * 0.86f,
color = Colors.of("#FFF2F6FA")
@@ -477,7 +477,7 @@ class MapRenderer(private val session: Session) {
// 缺字型的裝置會退化成兩個字母,仍然認得出國別。
val flag = session.nations.getOrNull(unit.nationId)?.flag.orEmpty()
if (flag.isNotEmpty() && size >= Ui.dp(11f)) {
- Widgets.centered(
+ FlagArt.centered(
canvas, flag, cx - w / 2f + size * 0.13f, top + size * 0.2f,
size * 0.30f, color = Colors.of("#FFFFFFFF")
)
diff --git a/app/src/main/java/io/github/acidefluorhydrique/mapconquer/render/MenuRenderer.kt b/app/src/main/java/io/github/acidefluorhydrique/mapconquer/render/MenuRenderer.kt
index 83fe263..bb9cf26 100644
--- a/app/src/main/java/io/github/acidefluorhydrique/mapconquer/render/MenuRenderer.kt
+++ b/app/src/main/java/io/github/acidefluorhydrique/mapconquer/render/MenuRenderer.kt
@@ -314,7 +314,7 @@ class MenuRenderer {
// 國旗擺在卡片最上面當主視覺,底下留一條國色 —— 那條色帶
// 對應地圖上的領土色,讓玩家在選完之後認得出自己是哪一片。
if (nation.flag.isNotEmpty()) {
- Widgets.centered(
+ FlagArt.centered(
canvas, nation.flag, inner.centerX(), inner.top + Ui.dp(20f),
Ui.dp(17f), color = Colors.of(Widgets.INK)
)
diff --git a/app/src/main/java/io/github/acidefluorhydrique/mapconquer/render/PanelRenderer.kt b/app/src/main/java/io/github/acidefluorhydrique/mapconquer/render/PanelRenderer.kt
index 08a963b..8c8e6ea 100644
--- a/app/src/main/java/io/github/acidefluorhydrique/mapconquer/render/PanelRenderer.kt
+++ b/app/src/main/java/io/github/acidefluorhydrique/mapconquer/render/PanelRenderer.kt
@@ -420,11 +420,15 @@ class PanelRenderer(private val session: Session) {
val topCount = ranked.firstOrNull()?.let { session.provincesOf(it.id) }?.coerceAtLeast(1) ?: 1
for (nation in shown) {
val count = session.provincesOf(nation.id)
- val label = (if (nation.flag.isEmpty()) "" else nation.flag + " ") +
- Strings.byName(nation.nameKey)
+ // 國旗與國名分開畫:自製的國旗(蘇聯、東德……)不是文字,塞不進字串裡。
+ var labelX = panel.left + Ui.dp(16f)
+ if (nation.flag.isNotEmpty()) {
+ FlagArt.left(canvas, nation.flag, labelX, y, Ui.dp(10.5f))
+ labelX += FlagArt.measure(nation.flag, Ui.dp(10.5f)) + Ui.dp(3f)
+ }
Widgets.leftFit(
- canvas, label, panel.left + Ui.dp(16f), y,
- Ui.dp(10.5f), Ui.dp(100f),
+ canvas, Strings.byName(nation.nameKey), labelX, y,
+ Ui.dp(10.5f), Ui.dp(100f) - (labelX - panel.left - Ui.dp(16f)),
if (nation.id == session.playerNationId) Colors.of("#F2D08A") else dim,
bold = nation.id == session.playerNationId
)
diff --git a/app/src/test/java/io/github/acidefluorhydrique/mapconquer/game/ScenarioAssetTest.kt b/app/src/test/java/io/github/acidefluorhydrique/mapconquer/game/ScenarioAssetTest.kt
index 634b0a8..dcced58 100644
--- a/app/src/test/java/io/github/acidefluorhydrique/mapconquer/game/ScenarioAssetTest.kt
+++ b/app/src/test/java/io/github/acidefluorhydrique/mapconquer/game/ScenarioAssetTest.kt
@@ -89,6 +89,22 @@ class ScenarioAssetTest {
* 反過來驗:同陣營之間不該有任何 WAR,不同陣營之間每一對都要有。
* 手寫關係表最典型的漏就是「對法國宣戰了但忘了對比利時宣戰」。
*/
+ /**
+ * 以 @ 開頭的國旗是遊戲自己畫的(render/FlagArt.kt),只認得這幾個代號。
+ * 產生器打錯一個字,那一國就會默默變成沒有國旗 —— 在這裡攔下來。
+ */
+ @Test
+ fun `every drawn flag is one the game knows how to draw`() {
+ val drawn = setOf("@su", "@reich", "@gdr")
+ for (id in TestAssets.scenarioIds()) {
+ for (nation in TestAssets.scenario(id).nations) {
+ if (nation.flag.startsWith("@")) {
+ assertTrue("$id/${nation.code}: 不認得的國旗 ${nation.flag}", nation.flag in drawn)
+ }
+ }
+ }
+ }
+
@Test
fun `blocs and declared wars agree with each other`() {
for (id in TestAssets.scenarioIds()) {
diff --git a/tools/genworld.py b/tools/genworld.py
index dc9940f..208bd0b 100644
--- a/tools/genworld.py
+++ b/tools/genworld.py
@@ -508,7 +508,7 @@ def nation_row(code):
code, (renames or {}).get(code, "nation_" + code.lower()),
colour, capital, profile, funds,
",".join(str(v) for v in tech_for(funds)),
- places.FLAGS.get(code, ""),
+ places.flag_for(code, start_year),
bloc_of(code, blocs),
(war_turns or {}).get(code, 1),
))
@@ -664,7 +664,7 @@ def write_campaign(built, mission):
mission.get("renames", places.WW2_RENAMES).get(code, "nation_" + code.lower()),
colour, capital, profile, funds,
",".join(str(v) for v in mission.get("tech", {}).get(code, [1, 1, 1, 0, 0, 1])),
- places.FLAGS.get(code, ""),
+ places.flag_for(code, mission["year"]),
bloc_of(code, mission["blocs"]),
mission.get("entry", {}).get(code, 1),
))
diff --git a/tools/places.py b/tools/places.py
index b1346d7..9be8909 100644
--- a/tools/places.py
+++ b/tools/places.py
@@ -648,7 +648,7 @@
# 基準壓到 1100:省份多會被資金公式放大(十五個省乘 1.75),照 2400 算
# 出來是全球最有錢的國家。1939 年的中華民國正在打一場守勢戰爭,不是首富。
"ROC": ("Republic of China", "中華民國", "中华民国", "#B4454C", "BALANCED", 1100),
- # 東德沒有 emoji 國旗可用,旗幟欄留空。
+ # 東德的國旗由 flag_for 依年份決定。
"DDR": ("East Germany", "東德", "东德", "#8C5A5A", "BALANCED", 700),
}
@@ -773,3 +773,29 @@
"RED": "🔴",
"GRN": "🟢",
}
+
+
+# 沒有 emoji 可用的國旗。以 @ 開頭的代號由遊戲端自己畫
+# (render/FlagArt.kt),其餘照舊交給系統的 emoji 字型。
+FLAG_SOVIET = "@su"
+FLAG_REICH = "@reich"
+FLAG_GDR = "@gdr"
+
+
+def flag_for(code, year):
+ """
+ 某國在某一年該掛的國旗。
+
+ - 蘇聯(1922–1991):紅底金色鐮刀錘子,不是俄羅斯的白藍紅。
+ - 納粹德國(1935–1945):史實是卐字旗。這裡刻意改用德軍的鐵十字 ——
+ 納粹標誌在德國與奧地利受法律限制,這是維護者的決定,不是史實。
+ - 東德:1949–1959 年的國旗跟西德一模一樣,就是黑紅金三色旗;1959 年起
+ 中間才加上錘子、圓規與麥穗環。
+ """
+ if code == "RUS" and 1922 <= year < 1992:
+ return FLAG_SOVIET
+ if code == "DEU" and 1935 <= year < 1946:
+ return FLAG_REICH
+ if code == "DDR":
+ return FLAG_GDR if year >= 1959 else FLAGS["DEU"]
+ return FLAGS.get(code, "")