summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Andersson <tor@ccxvii.net>2021-06-20 12:38:03 +0200
committerTor Andersson <tor@ccxvii.net>2022-11-16 19:19:38 +0100
commit3e5c1379b6a230b8ce1d771b31858d9f93f6e46a (patch)
tree65c8ac1f123f55e8da1b64b14eefd6682f8523f8
parent9ecbee1517966c892c60ddc2310e03d57b0de413 (diff)
downloadcrusader-rex-3e5c1379b6a230b8ce1d771b31858d9f93f6e46a.tar.gz
crusader: Add "plural" info to block data for better messages.
-rw-r--r--data.js308
-rw-r--r--play.html33
-rw-r--r--rules.js69
-rw-r--r--ui.js41
4 files changed, 262 insertions, 189 deletions
diff --git a/data.js b/data.js
index 2d138af..17f9eed 100644
--- a/data.js
+++ b/data.js
@@ -103,14 +103,12 @@ const TOWNS = {
"England1":{"x":139,"y":873},
"England2":{"x":140,"y":961},
"England3":{"x":138,"y":1047},
- "F. Pool":{"x":120,"y":2150},
- "S. Pool":{"x":120,"y":2150},
+ "FP":{"x":120,"y":2150},
+ "SP":{"x":120,"y":2150},
*/
"Germania":{"x":139,"y":273},
"France":{"x":140,"y":573},
"England":{"x":139,"y":873},
- "F. Pool":{"x":120,"y":2150},
- "S. Pool":{"x":120,"y":2150},
};
const PORTS = [];
@@ -120,7 +118,7 @@ const PORTS = [];
let nomads = { Arabs: 1, Turks: 1, Kurds: 1 }
- function army(rc, owner, name, home, move, steps, combat, order) {
+ function army(rc, owner, name, home, move, steps, combat, order, plural) {
let id = name;
if (order == 'Military Orders' || order == 'Pilgrims' || order == 'Turcopoles')
id = home + " " + name;
@@ -133,6 +131,7 @@ const PORTS = [];
BLOCKS[id] = {
owner: owner,
name: name,
+ plural: plural,
type: order.toLowerCase().replace(/ /g, "_"),
home: home,
move: move,
@@ -142,90 +141,90 @@ const PORTS = [];
}
}
- function frank(rc, name, home, move, steps, combat, order) {
- army(rc, "Frank", name, home, move, steps, combat, order);
+ function frank(rc, name, home, move, steps, combat, order, plural) {
+ army(rc, "Frank", name, home, move, steps, combat, order, plural);
}
- function saracen(rc, name, home, move, steps, combat, order) {
- army(rc, "Saracen", name, home, move, steps, combat, order);
+ function saracen(rc, name, home, move, steps, combat, order, plural) {
+ army(rc, "Saracen", name, home, move, steps, combat, order, plural);
}
- frank(13, "Barbarossa", "Germania", 2, 4, "B3", "Crusaders");
- frank(23, "Frederik", "Germania", 2, 3, "B2", "Crusaders");
- frank(33, "Leopold", "Germania", 2, 3, "B3", "Crusaders");
-
- frank(11, "Richard", "England", 3, 4, "B4", "Crusaders");
- frank(21, "Robert", "Normandy", 2, 3, "B3", "Crusaders");
- frank(31, "Crossbows", "Aquitaine", 2, 3, "A2", "Crusaders");
-
- frank(12, "Philippe", "France", 2, 4, "B3", "Crusaders");
- frank(22, "Hugues", "Bourgogne", 2, 4, "B2", "Crusaders");
- frank(32, "Fileps", "Flanders", 2, 3, "B3", "Crusaders");
-
- frank(42, "Pilgrims", "Genoa", 2, 4, "C2", "Pilgrims");
- frank(43, "Pilgrims", "Sicily", 2, 3, "C2", "Pilgrims");
- frank(52, "Pilgrims", "Brittany", 2, 4, "C2", "Pilgrims");
-
- frank(14, "Templars", "Jerusalem", 3, 3, "B3", "Military Orders");
- frank(15, "Templars", "Antioch", 3, 3, "B3", "Military Orders");
- frank(16, "Templars", "Gaza", 3, 3, "B3", "Military Orders");
- frank(17, "Templars", "Tartus", 3, 3, "B3", "Military Orders");
- frank(24, "Hospitallers", "Jerusalem", 3, 4, "B3", "Military Orders");
- frank(25, "Hospitallers", "Acre", 3, 3, "B3", "Military Orders");
- frank(26, "Hospitallers", "Krak", 3, 2, "B3", "Military Orders");
-
- frank(27, "Reynald", "Sidon", 2, 3, "B2", "Outremers");
- frank(34, "Conrad", "Tyre", 2, 4, "B3", "Outremers");
- frank(35, "Balian", "Nablus", 2, 3, "B2", "Outremers");
- frank(36, "Walter", "Caesarea", 2, 3, "B2", "Outremers");
- frank(37, "Raymond", "Tiberias", 2, 3, "B2", "Outremers");
- frank(44, "King Guy", "Jerusalem", 2, 4, "B2", "Outremers");
- frank(45, "Reynald", "Kerak", 3, 2, "B3", "Outremers");
- frank(46, "Bohemond", "Antioch", 2, 4, "B2", "Outremers");
- frank(47, "Raymond", "Tripoli", 2, 4, "B2", "Outremers");
- frank(53, "Josselin", "Saone", 2, 3, "B2", "Outremers");
-
- frank(41, "Turcopole", "Antioch", 3, 3, "A2", "Turcopoles");
- frank(51, "Turcopole", "Beirut", 3, 3, "A2", "Turcopoles");
-
- army(54, "Assassins", "Assassins", "Masyaf", 0, 3, "A3", "Assassins");
-
- saracen(55, "Qara-Qush", "Egypt", 3, 3, "B3", "Emirs");
- saracen(56, "Zangi", "Aleppo", 3, 3, "B2", "Emirs");
- saracen(57, "Sanjar", "Aleppo", 3, 3, "B2", "Emirs");
-
- saracen(61, "Yazkuj", "Ashtera", 3, 2, "B2", "Emirs");
- saracen(62, "Sulaiman", "Artah", 3, 2, "B2", "Emirs");
- saracen(63, "Keukburi", "Damascus", 3, 3, "B3", "Emirs");
- saracen(64, "Shirkuh", "Homs", 3, 3, "B2", "Emirs");
- saracen(65, "Jurdik", "Zerdana", 3, 3, "B2", "Emirs");
- saracen(66, "Bahram", "Baalbek", 3, 3, "B2", "Emirs");
- saracen(67, "Tuman", "Homs", 3, 3, "B3", "Emirs");
-
- saracen(71, "Taqi al Din", "Hama", 3, 4, "A2", "Emirs");
- saracen(72, "Al Mashtub", "Damascus", 3, 4, "B3", "Emirs");
- saracen(73, "Al Adil", "Egypt", 3, 4, "A2", "Emirs");
- saracen(74, "Saladin", "Damascus", 3, 4, "A3", "Emirs");
- saracen(75, "Al Aziz", "Egypt", 3, 3, "B2", "Emirs");
- saracen(76, "Al Afdal", "Damascus", 3, 3, "B3", "Emirs");
- saracen(77, "Al Zahir", "Aleppo", 3, 3, "A2", "Emirs");
-
- saracen(81, "Yuzpah", "Egypt", 3, 4, "B2", "Emirs");
- saracen(82, "Qaimaz", "Banyas", 3, 3, "B2", "Emirs");
-
- saracen(83, "Kurds", "Damascus", 3, 4, "C1", "Nomads");
- saracen(84, "Kurds", "Damascus", 3, 4, "C1", "Nomads");
- saracen(85, "Kurds", "Damascus", 3, 3, "C2", "Nomads");
- saracen(86, "Kurds", "Damascus", 3, 3, "C2", "Nomads");
-
- saracen(91, "Turks", "Aleppo", 3, 3, "A2", "Nomads");
- saracen(92, "Turks", "Aleppo", 3, 3, "A2", "Nomads");
- saracen(93, "Turks", "Aleppo", 3, 4, "A1", "Nomads");
- saracen(94, "Turks", "Aleppo", 3, 4, "A1", "Nomads");
-
- saracen(95, "Arabs", "Egypt", 3, 3, "B2", "Nomads");
- saracen(96, "Arabs", "Egypt", 3, 3, "B2", "Nomads");
- saracen(97, "Arabs", "Egypt", 3, 4, "B1", "Nomads");
- saracen(87, "Arabs", "Egypt", 3, 4, "B1", "Nomads");
+ frank(13, "Barbarossa", "Germania", 2, 4, "B3", "Crusaders", 0);
+ frank(23, "Frederik", "Germania", 2, 3, "B2", "Crusaders", 0);
+ frank(33, "Leopold", "Germania", 2, 3, "B3", "Crusaders", 0);
+
+ frank(11, "Richard", "England", 3, 4, "B4", "Crusaders", 0);
+ frank(21, "Robert", "Normandy", 2, 3, "B3", "Crusaders", 0);
+ frank(31, "Crossbows", "Aquitaine", 2, 3, "A2", "Crusaders", 1);
+
+ frank(12, "Philippe", "France", 2, 4, "B3", "Crusaders", 0);
+ frank(22, "Hugues", "Bourgogne", 2, 4, "B2", "Crusaders", 0);
+ frank(32, "Fileps", "Flanders", 2, 3, "B3", "Crusaders", 0);
+
+ frank(42, "Pilgrims", "Genoa", 2, 4, "C2", "Pilgrims", 1);
+ frank(43, "Pilgrims", "Sicily", 2, 3, "C2", "Pilgrims", 1);
+ frank(52, "Pilgrims", "Brittany", 2, 4, "C2", "Pilgrims", 1);
+
+ frank(14, "Templars", "Jerusalem", 3, 3, "B3", "Military Orders", 1);
+ frank(15, "Templars", "Antioch", 3, 3, "B3", "Military Orders", 1);
+ frank(16, "Templars", "Gaza", 3, 3, "B3", "Military Orders", 1);
+ frank(17, "Templars", "Tartus", 3, 3, "B3", "Military Orders", 1);
+ frank(24, "Hospitallers", "Jerusalem", 3, 4, "B3", "Military Orders", 1);
+ frank(25, "Hospitallers", "Acre", 3, 3, "B3", "Military Orders", 1);
+ frank(26, "Hospitallers", "Krak", 3, 2, "B3", "Military Orders", 1);
+
+ frank(27, "Reynald", "Sidon", 2, 3, "B2", "Outremers", 0);
+ frank(34, "Conrad", "Tyre", 2, 4, "B3", "Outremers", 0);
+ frank(35, "Balian", "Nablus", 2, 3, "B2", "Outremers", 0);
+ frank(36, "Walter", "Caesarea", 2, 3, "B2", "Outremers", 0);
+ frank(37, "Raymond", "Tiberias", 2, 3, "B2", "Outremers", 0);
+ frank(44, "King Guy", "Jerusalem", 2, 4, "B2", "Outremers", 0);
+ frank(45, "Reynald", "Kerak", 3, 2, "B3", "Outremers", 0);
+ frank(46, "Bohemond", "Antioch", 2, 4, "B2", "Outremers", 0);
+ frank(47, "Raymond", "Tripoli", 2, 4, "B2", "Outremers", 0);
+ frank(53, "Josselin", "Saone", 2, 3, "B2", "Outremers", 0);
+
+ frank(41, "Turcopole", "Antioch", 3, 3, "A2", "Turcopoles", 0);
+ frank(51, "Turcopole", "Beirut", 3, 3, "A2", "Turcopoles", 0);
+
+ army(54, "Assassins", "Assassins", "Masyaf", 0, 3, "A3", "Assassins", 1);
+
+ saracen(55, "Qara-Qush", "Egypt", 3, 3, "B3", "Emirs", 0);
+ saracen(56, "Zangi", "Aleppo", 3, 3, "B2", "Emirs", 0);
+ saracen(57, "Sanjar", "Aleppo", 3, 3, "B2", "Emirs", 0);
+
+ saracen(61, "Yazkuj", "Ashtera", 3, 2, "B2", "Emirs", 0);
+ saracen(62, "Sulaiman", "Artah", 3, 2, "B2", "Emirs", 0);
+ saracen(63, "Keukburi", "Damascus", 3, 3, "B3", "Emirs", 0);
+ saracen(64, "Shirkuh", "Homs", 3, 3, "B2", "Emirs", 0);
+ saracen(65, "Jurdik", "Zerdana", 3, 3, "B2", "Emirs", 0);
+ saracen(66, "Bahram", "Baalbek", 3, 3, "B2", "Emirs", 0);
+ saracen(67, "Tuman", "Homs", 3, 3, "B3", "Emirs", 0);
+
+ saracen(71, "Taqi al Din", "Hama", 3, 4, "A2", "Emirs", 0);
+ saracen(72, "Al Mashtub", "Damascus", 3, 4, "B3", "Emirs", 0);
+ saracen(73, "Al Adil", "Egypt", 3, 4, "A2", "Emirs", 0);
+ saracen(74, "Saladin", "Damascus", 3, 4, "A3", "Emirs", 0);
+ saracen(75, "Al Aziz", "Egypt", 3, 3, "B2", "Emirs", 0);
+ saracen(76, "Al Afdal", "Damascus", 3, 3, "B3", "Emirs", 0);
+ saracen(77, "Al Zahir", "Aleppo", 3, 3, "A2", "Emirs", 0);
+
+ saracen(81, "Yuzpah", "Egypt", 3, 4, "B2", "Emirs", 0);
+ saracen(82, "Qaimaz", "Banyas", 3, 3, "B2", "Emirs", 0);
+
+ saracen(83, "Kurds", "Damascus", 3, 4, "C1", "Nomads", 1);
+ saracen(84, "Kurds", "Damascus", 3, 4, "C1", "Nomads", 1);
+ saracen(85, "Kurds", "Damascus", 3, 3, "C2", "Nomads", 1);
+ saracen(86, "Kurds", "Damascus", 3, 3, "C2", "Nomads", 1);
+
+ saracen(91, "Turks", "Aleppo", 3, 3, "A2", "Nomads", 1);
+ saracen(92, "Turks", "Aleppo", 3, 3, "A2", "Nomads", 1);
+ saracen(93, "Turks", "Aleppo", 3, 4, "A1", "Nomads", 1);
+ saracen(94, "Turks", "Aleppo", 3, 4, "A1", "Nomads", 1);
+
+ saracen(95, "Arabs", "Egypt", 3, 3, "B2", "Nomads", 1);
+ saracen(96, "Arabs", "Egypt", 3, 3, "B2", "Nomads", 1);
+ saracen(97, "Arabs", "Egypt", 3, 4, "B1", "Nomads", 1);
+ saracen(87, "Arabs", "Egypt", 3, 4, "B1", "Nomads", 1);
function town(axis, major, minor, wrap, region, name, rating, type) {
TOWNS[name].region = region;
@@ -238,9 +237,9 @@ const PORTS = [];
PORTS.push(name);
TOWNS[name].exits = [];
TOWNS[name].layout_axis = axis;
- TOWNS[name].layout_major = (1 - major) / 2;
- TOWNS[name].layout_minor = (1 - minor) / 2;
- TOWNS[name].wrap = wrap ? wrap : Math.max(2, rating);
+ TOWNS[name].layout_major = 1-major;
+ TOWNS[name].layout_minor = 1-minor;
+ TOWNS[name].wrap = wrap;
}
/*
@@ -253,72 +252,73 @@ const PORTS = [];
town('X', 0, 0, 0, "Staging", "Germania1", 0, "staging");
town('X', 0, 0, 0, "Staging", "Germania2", 0, "staging");
town('X', 0, 0, 0, "Staging", "Germania3", 0, "staging");
+ town('X', 0, 0, 0, "Pool", "FP", 0, "pool", "N", 12);
+ town('X', 0, 0, 0, "Pool", "SP", 0, "pool", "N", 12);
*/
- town('X', 0, 0, 0, "Staging", "England", 0, "staging", "S", 3);
- town('X', 0, 0, 0, "Staging", "France", 0, "staging", "S", 3);
- town('X', 0, 0, 0, "Staging", "Germania", 0, "staging", "S", 3);
-
- town('X', 0, 0, 0, "Pool", "F. Pool", 0, "pool", "N", 12);
- town('X', 0, 0, 0, "Pool", "S. Pool", 0, "pool", "N", 12);
-
- town('X', 1, 0, 0, "Syria", "Aleppo", 3, "town", "E");
- town('Y', 0, 0, 0, "Syria", "Artah", 1, "town", "V");
- town('X', 1, 0, 0, "Syria", "Zerdana", 1, "town", "E");
- town('X', 1, 0, 0, "Syria", "Hama", 1, "town", "E");
- town('X', 1, 0, 0, "Syria", "Homs", 2, "town", "E");
- town('X', 0, 0, 0, "Syria", "Lacum", 0, "town", "H");
- town('X', 0, 0, 0, "Syria", "Qaddas", 0, "town", "H");
- town('X', 0, 0, 0, "Syria", "Baalbek", 1, "town", "H");
- town('X', 0, 0, 0, "Syria", "Anjar", 0, "town", "H");
- town('X', 0, 0, 0, "Syria", "Damascus", 4, "town", "H");
- town('X', 1, 0, 0, "Syria", "Banyas", 1, "town", "E");
- town('X', 1, 0, 0, "Syria", "Ashtera", 1, "town", "E");
- town('X', 1, 0, 0, "Syria", "Ajlun", 0, "town", "E");
-
- town('X', 0, 0, 0, "Antioch", "St. Simeon", 0, "port", "W");
- town('Y', 0, 0, 0, "Antioch", "Antioch", 3, "town", "V");
- town('Y', 1, 0, 0, "Antioch", "Harim", 0, "town", "S");
- town('X', 0, 0, 0, "Antioch", "Kassab", 0, "town", "H");
- town('X', 0, 0, 0, "Antioch", "Shughur", 0, "town", "H");
- town('X', -1, 0, 0, "Antioch", "Latakia", 1, "port", "W");
- town('X', 0, 0, 0, "Antioch", "Saone", 1, "town", "H");
- town('Y', 0, 0, 0, "Antioch", "Albara", 0, "town", "V");
- town('X', -1, 0, 0, "Antioch", "Margat", 1, "port", "W");
-
- town('X', 0, 0, 0, "Masyaf", "Masyaf", 1, "town", "H");
-
- town('Y', 0, 0, 0, "Tripoli", "Monterrand", 0, "town", "V");
- town('X', -1, 0, 0, "Tripoli", "Tartus", 1, "port", "W");
- town('X', 1, 0, 0, "Tripoli", "Krak", 1, "town", "E");
- town('X', -1, 0, 0, "Tripoli", "Tripoli", 2, "fortified-port", "W");
- town('X', -1, 0, 0, "Tripoli", "Botron", 0, "town", "W");
-
- town('X', -1, 0, 0, "Jerusalem", "Beirut", 2, "port", "W");
- town('X', -1, 0, 0, "Jerusalem", "Sidon", 1, "port", "W");
- town('X', -1, 0, 0, "Jerusalem", "Tyre", 2, "fortified-port", "W");
- town('Y', 0, 0, 0, "Jerusalem", "Beaufort", 1, "town", "V");
- town('X', -1, 0, 0, "Jerusalem", "Acre", 3, "port", "W");
- town('X', 1, 0, 0, "Jerusalem", "Tiberias", 2, "town", "E");
- town('Y', 1, 0, 0, "Jerusalem", "Legio", 0, "town", "N");
- town('X', 1, 0, 0, "Jerusalem", "Baisan", 1, "town", "E");
- town('X', -1, 0, 0, "Jerusalem", "Caesarea", 1, "port", "W");
- town('X', 0, 0, 0, "Jerusalem", "Nablus", 1, "town", "H");
- town('X', 0, 0, 0, "Jerusalem", "Damiya", 0, "town", "H");
- town('X', 0, 0, 0, "Jerusalem", "Amman", 1, "town", "H");
- town('X', -1, 0, 0, "Jerusalem", "Jaffa", 1, "port", "W");
- town('Y', 0, 0, 0, "Jerusalem", "Ramallah", 0, "town", "V");
- town('X', 0, 0, 0, "Jerusalem", "Jerusalem", 3, "town", "H");
- town('Y', 0, 0, 0, "Jerusalem", "Jericho", 0, "town", "V");
- town('X', -1, 0, 0, "Jerusalem", "Ascalon", 2, "port", "W");
- town('Y', 0, 0, 0, "Jerusalem", "Lachish", 0, "town", "V");
- town('X', 0, 0, 0, "Jerusalem", "Hebron", 1, "town", "H");
- town('X', 1, 0, 0, "Jerusalem", "Kerak", 1, "town", "E");
- town('X', 0, 0, 0, "Jerusalem", "Gaza", 1, "town", "H");
- town('Y', 0, 0, 0, "Jerusalem", "Beersheba", 0, "town", "V");
- town('X', 0, 0, 0, "Jerusalem", "Dimona", 0, "town", "H");
- town('X', 1, 0, 0, "Jerusalem", "Zoar", 0, "town", "E");
-
- town('X', 0, 0, 0, "Egypt", "Egypt", 4, "port", "H");
+
+ town('X', 0.5, 0.5, 3, "Staging", "England", 0, "staging");
+ town('X', 0.5, 0.5, 3, "Staging", "France", 0, "staging");
+ town('X', 0.5, 0.5, 3, "Staging", "Germania", 0, "staging");
+
+
+ town('X', 1.0, 0.5, 3, "Syria", "Aleppo", 3, "town");
+ town('Y', 0.5, 0.5, 3, "Syria", "Artah", 1, "town");
+ town('X', 1.0, 0.5, 3, "Syria", "Zerdana", 1, "town");
+ town('X', 1.0, 0.5, 3, "Syria", "Hama", 1, "town");
+ town('X', 1.0, 0.5, 3, "Syria", "Homs", 2, "town");
+ town('X', 0.5, 0.5, 3, "Syria", "Lacum", 0, "town");
+ town('X', 0.5, 0.5, 3, "Syria", "Qaddas", 0, "town");
+ town('X', 0.5, 0.5, 3, "Syria", "Baalbek", 1, "town");
+ town('X', 0.5, 0.5, 3, "Syria", "Anjar", 0, "town");
+ town('X', 0.5, 0.5, 4, "Syria", "Damascus", 4, "town");
+ town('X', 1.0, 0.5, 3, "Syria", "Banyas", 1, "town");
+ town('X', 1.0, 0.5, 3, "Syria", "Ashtera", 1, "town");
+ town('X', 1.0, 0.5, 3, "Syria", "Ajlun", 0, "town");
+
+ town('X', 0.5, 0.5, 3, "Antioch", "St. Simeon", 0, "port");
+ town('Y', 0.5, 0.5, 3, "Antioch", "Antioch", 3, "town");
+ town('Y', 1.0, 0.5, 3, "Antioch", "Harim", 0, "town");
+ town('X', 0.5, 0.5, 3, "Antioch", "Kassab", 0, "town");
+ town('X', 0.5, 0.5, 3, "Antioch", "Shughur", 0, "town");
+ town('X', 0.0, 0.5, 3, "Antioch", "Latakia", 1, "port");
+ town('X', 0.5, 0.5, 3, "Antioch", "Saone", 1, "town");
+ town('Y', 0.5, 0.5, 3, "Antioch", "Albara", 0, "town");
+ town('X', 0.0, 0.5, 3, "Antioch", "Margat", 1, "port");
+
+ town('X', 0.5, 0.5, 1, "Masyaf", "Masyaf", 1, "town");
+
+ town('Y', 0.5, 0.5, 3, "Tripoli", "Monterrand", 0, "town");
+ town('X', 0.0, 0.5, 3, "Tripoli", "Tartus", 1, "port");
+ town('X', 1.0, 0.5, 3, "Tripoli", "Krak", 1, "town");
+ town('X', 0.0, 0.5, 3, "Tripoli", "Tripoli", 2, "fortified-port");
+ town('X', 0.0, 0.5, 3, "Tripoli", "Botron", 0, "town");
+
+ town('X', 0.0, 0.5, 3, "Jerusalem", "Beirut", 2, "port");
+ town('X', 0.0, 0.5, 3, "Jerusalem", "Sidon", 1, "port");
+ town('X', 0.0, 0.5, 3, "Jerusalem", "Tyre", 2, "fortified-port");
+ town('Y', 0.5, 0.5, 3, "Jerusalem", "Beaufort", 1, "town");
+ town('X', 0.0, 0.5, 3, "Jerusalem", "Acre", 3, "port");
+ town('X', 1.0, 0.5, 3, "Jerusalem", "Tiberias", 2, "town");
+ town('Y', 1.0, 0.5, 3, "Jerusalem", "Legio", 0, "town");
+ town('X', 1.0, 0.5, 3, "Jerusalem", "Baisan", 1, "town");
+ town('X', 0.0, 0.5, 3, "Jerusalem", "Caesarea", 1, "port");
+ town('X', 0.5, 0.5, 3, "Jerusalem", "Nablus", 1, "town");
+ town('X', 0.5, 0.5, 3, "Jerusalem", "Damiya", 0, "town");
+ town('X', 0.5, 0.5, 3, "Jerusalem", "Amman", 1, "town");
+ town('X', 0.0, 0.5, 3, "Jerusalem", "Jaffa", 1, "port");
+ town('Y', 0.5, 0.5, 3, "Jerusalem", "Ramallah", 0, "town");
+ town('X', 0.5, 0.5, 3, "Jerusalem", "Jerusalem", 3, "town");
+ town('Y', 0.5, 0.5, 3, "Jerusalem", "Jericho", 0, "town");
+ town('X', 0.0, 0.5, 3, "Jerusalem", "Ascalon", 2, "port");
+ town('Y', 0.5, 0.5, 3, "Jerusalem", "Lachish", 0, "town");
+ town('X', 0.5, 0.5, 3, "Jerusalem", "Hebron", 1, "town");
+ town('X', 1.0, 0.5, 3, "Jerusalem", "Kerak", 1, "town");
+ town('X', 0.5, 0.5, 3, "Jerusalem", "Gaza", 1, "town");
+ town('Y', 0.5, 0.5, 3, "Jerusalem", "Beersheba", 0, "town");
+ town('X', 0.5, 0.5, 3, "Jerusalem", "Dimona", 0, "town");
+ town('X', 1.0, 0.5, 3, "Jerusalem", "Zoar", 0, "town");
+
+ town('X', 0.5, 0.5, 4, "Egypt", "Egypt", 4, "port");
function road(A,B,type) {
let id = (A < B) ? (A + "/" + B) : (B + "/" + A);
diff --git a/play.html b/play.html
index e3d0e5a..67c85f9 100644
--- a/play.html
+++ b/play.html
@@ -19,12 +19,12 @@
.grid_log { background-color: ghostwhite; }
.grid_top { background-color: gainsboro; }
.grid_top.your_turn { background-color: orange; }
-.grid_top.Frank.your_turn { background-color: khaki; }
+.grid_top.Frank.your_turn { background-color: gold; }
.grid_top.Saracen.your_turn { background-color: lightgreen; }
.grid_top.disconnected { background-color: red; }
.role_info { background-color: silver; }
.one .role_name { background-color: khaki; }
-.two .role_name { background-color: lightgreen; }
+.two .role_name { background-color: darkseagreen; }
#turn {
padding: 8px 0px 8px 8px;
@@ -136,8 +136,6 @@ body.shift .block.known:hover {
.map .block.known { z-index: 5; }
.map .block.known:hover { z-index: 6; }
-.block.highlight { cursor: pointer; box-shadow: 0px 0px 4px 1px white; }
-
.block {
background-size: cover;
background-repeat: no-repeat;
@@ -147,25 +145,32 @@ body.shift .block.known:hover {
box-shadow: 0px 0px 4px 0px black;
}
-.block.Frank { border: 3px solid orange; background-color: orange; }
-.block.Saracen { border: 3px solid green; background-color: green; }
-.block.Assassins { border: 3px solid purple; background-color: purple; }
+.block.Frank { border: 3px solid darkkhaki; background-color: khaki; }
+.block.Saracen { border: 3px solid seagreen; background-color: darkseagreen; }
+.block.Assassins { border: 3px solid rebeccapurple; background-color: rebeccapurple; }
.block.Frank.highlight { border-color: white; }
.block.Saracen.highlight { border-color: white; }
.block.Assassins.highlight { border-color: white; }
-.block.Frank.selected { border-color: yellow; }
-.block.Saracen.selected { border-color: yellow; }
-.block.Assassins.selected { border-color: yellow; }
+.block.Frank.selected { border-color: gold; }
+.block.Saracen.selected { border-color: lightgreen; }
+.block.Assassins.selected { border-color: hotpink; }
-.block.selected { box-shadow: 0 0 4px 1px yellow; }
-.block.moved { filter: brightness(85%) grayscale(50%); }
-.block.highlight.moved { filter: brightness(95%) grayscale(60%); }
+.block.highlight { cursor: pointer; }
+.block.highlight { box-shadow: 0px 0px 4px 1px white; }
+.block.selected { box-shadow: 0 0 4px 1px white; }
+.block.moved { filter: brightness(80%) grayscale(40%); }
+.block.highlight.moved { filter: brightness(95%) grayscale(40%); }
+.block.r0 { transform: rotate(0deg); }
.block.r1 { transform: rotate(-90deg); }
.block.r2 { transform: rotate(-180deg); }
.block.r3 { transform: rotate(-270deg); }
+.block.r0hh { transform: rotate(-30deg); }
+.block.r1hh { transform: rotate(-120deg); }
+.block.r2hh { transform: rotate(-210deg); }
+.block.r3hh { transform: rotate(-300deg); }
.block {
transition-property: top, left, transform;
@@ -305,8 +310,8 @@ body.shift .block.known:hover {
<div class="menu_popup">
<div class="menu_item" onclick="toggle_fullscreen()">Fullscreen</div>
<div class="menu_separator"></div>
- <div class="menu_item" onclick="wide_map()">Wide Map</div>
<div class="menu_item" onclick="tall_map()">Tall Map</div>
+ <div class="menu_item" onclick="wide_map()">Wide Map</div>
<div class="menu_separator"></div>
<div class="menu_item" onclick="set_spread_layout()">Spread blocks</div>
<div class="menu_item" onclick="set_stack_layout()">Stack blocks</div>
diff --git a/rules.js b/rules.js
index dc56ea9..ff8d3f2 100644
--- a/rules.js
+++ b/rules.js
@@ -19,8 +19,8 @@ const ENEMY = { Frank: "Saracen", Saracen: "Frank" };
const OBSERVER = "Observer";
const BOTH = "Both";
const DEAD = "Dead";
-const F_POOL = "F. Pool";
-const S_POOL = "S. Pool";
+const F_POOL = "FP";
+const S_POOL = "SP";
// serif cirled numbers
const DIE_HIT = [ 0, '\u2776', '\u2777', '\u2778', '\u2779', '\u277A', '\u277B' ];
@@ -180,6 +180,10 @@ function deal_cards(deck, n) {
return hand;
}
+function block_plural(who) {
+ return BLOCKS[who].plural;
+}
+
function block_name(who) {
return who; // BLOCKS[who].name;
}
@@ -467,8 +471,10 @@ function can_block_muster_with_3_moves(n0, muster) {
return false;
}
-function can_block_muster_with_2_moves(n0, muster) {
+function can_block_muster_with_2_moves(n0, muster, avoid) {
for (let n1 of TOWNS[n0].exits) {
+ if (n1 == avoid)
+ continue;
if (can_block_use_road_to_muster(n0, n1)) {
if (n1 == muster)
return true;
@@ -495,7 +501,7 @@ function can_block_muster(who, muster) {
if (block_move(who) == 3)
return can_block_muster_with_3_moves(from, muster);
else
- return can_block_muster_with_2_moves(from, muster);
+ return can_block_muster_with_2_moves(from, muster, null);
}
return false;
}
@@ -524,13 +530,19 @@ function is_defender(who) {
}
function disband(who) {
- log(block_name(who) + " disbands.");
+ if (block_plural(who))
+ log(block_name(who) + " disband.");
+ else
+ log(block_name(who) + " disbands.");
game.location[who] = block_pool(who);
game.steps[who] = block_max_steps(who);
}
function eliminate_block(who) {
- log(block_name(who) + " is eliminated.");
+ if (block_plural(who))
+ log(block_name(who) + " are eliminated.");
+ else
+ log(block_name(who) + " is eliminated.");
if (is_saladin_family(who) || block_type(who) == 'crusaders' || block_type(who) == 'military_orders')
game.location[who] = null; // permanently eliminated
else
@@ -802,6 +814,7 @@ states.group_move = {
game.who = who;
game.origin = game.location[who];
game.distance = 0;
+ game.last_from = null;
game.state = 'group_move_to';
},
sea_move: function () {
@@ -827,7 +840,7 @@ states.group_move_to = {
if (game.distance > 0)
gen_action(view, 'town', from);
for (let to of TOWNS[from].exits) {
- if (can_block_land_move_to(game.who, from, to))
+ if (to != game.last_from && can_block_land_move_to(game.who, from, to))
gen_action(view, 'town', to);
}
},
@@ -844,6 +857,7 @@ states.group_move_to = {
log_move_continue(to + mark);
else
log_move_continue(to);
+ game.last_from = from;
if (!can_block_continue(game.who, from, to))
end_move();
},
@@ -1016,7 +1030,7 @@ states.muster_move_1 = {
if (block_move(game.who) == 3) {
for (let to of TOWNS[from].exits) {
if (can_block_use_road_to_muster(from, to)) {
- if (to == muster || can_block_muster_with_2_moves(to, muster))
+ if (to == muster || can_block_muster_with_2_moves(to, muster, from))
gen_action(view, 'town', to);
}
}
@@ -1288,19 +1302,32 @@ function roll_attack(active, b, verb) {
}
game.flash = name + " " + verb + " " + rolls.join(" ") + " ";
- if (game.hits == 0)
- game.flash += "and misses.";
- else if (game.hits == 1)
- game.flash += "and scores 1 hit.";
- else
- game.flash += "and scores " + game.hits + " hits.";
+ if (block_plural(b)) {
+ if (game.hits == 0)
+ game.flash += "and miss.";
+ else if (game.hits == 1)
+ game.flash += "and score 1 hit.";
+ else
+ game.flash += "and score " + game.hits + " hits.";
+ } else {
+ if (game.hits == 0)
+ game.flash += "and misses.";
+ else if (game.hits == 1)
+ game.flash += "and scores 1 hit.";
+ else
+ game.flash += "and scores " + game.hits + " hits.";
+ }
log(active[0] + ": " + name + " " + verb + " " + rolls.join("") + ".");
}
function fire_with_block(b) {
game.moved[b] = true;
- roll_attack(game.active, b, "fires");
+ console.log ("fire", block_plural(b));
+ if (block_plural(b))
+ roll_attack(game.active, b, "fire");
+ else
+ roll_attack(game.active, b, "fires");
if (game.hits > 0) {
game.active = ENEMY[game.active];
goto_battle_hits();
@@ -1353,7 +1380,10 @@ function goto_battle_hits() {
}
function apply_hit(who) {
- game.flash = block_name(who) + " takes a hit.";
+ if (block_plural(who))
+ game.flash = block_name(who) + " take a hit.";
+ else
+ game.flash = block_name(who) + " takes a hit.";
reduce_block(who, 'combat');
game.hits--;
if (game.hits == 0)
@@ -1488,7 +1518,10 @@ states.retreat_in_battle = {
gen_action(view, 'town', to);
},
town: function (to) {
- game.flash = block_name(game.who) + " retreats.";
+ if (block_plural(game.who))
+ game.flash = block_name(game.who) + " retreat.";
+ else
+ game.flash = block_name(game.who) + " retreats.";
logp("retreats to " + to + ".");
game.location[game.who] = to;
resume_battle();
@@ -1664,6 +1697,7 @@ exports.setup = function (scenario, players) {
road_limit: {},
last_used: {},
location: {},
+ castle: {},
log: [],
main_road: {},
moved: {},
@@ -1720,6 +1754,7 @@ exports.view = function(state, current) {
hand: (current == FRANK) ? game.f_hand : (current == SARACEN) ? game.s_hand : [],
who: (game.active == current) ? game.who : null,
location: game.location,
+ castle: game.castle,
steps: game.steps,
reserves: game.reserves1.concat(game.reserves2),
moved: game.moved,
diff --git a/ui.js b/ui.js
index d72e440..aff3787 100644
--- a/ui.js
+++ b/ui.js
@@ -4,8 +4,9 @@ const FRANK = "Frank";
const SARACEN = "Saracen";
const ASSASSINS = "Assassins";
const ENEMY = { Saracen: "Frank", Frank: "Saracen" }
-const POOL = "Pool";
const DEAD = "Dead";
+const F_POOL = "FP";
+const S_POOL = "SP";
let label_layout = window.localStorage['crusader-rex/label-layout'] || 'spread';
@@ -331,13 +332,43 @@ function update_steps(b, steps, element) {
}
function layout_blocks(location, secret, known) {
- if (label_layout == 'spread' || (location == POOL || location == DEAD))
+ if (label_layout == 'spread' || (location == S_POOL || location == F_POOL || location == DEAD))
layout_blocks_spread(location, secret, known);
else
layout_blocks_stacked(location, secret, known);
}
-function layout_blocks_spread(town, secret, known) {
+// function position_block(town, row, n_rows, col, n_cols, element) {
+
+function layout_blocks_spread(town, north, south) {
+ let wrap = TOWNS[town].wrap;
+ let rows = [];
+
+ if (north.length + south.length > wrap * 3) {
+ north = north.concat(south);
+ south = [];
+ }
+
+ function wrap_row(input) {
+ while (input.length > wrap) {
+ rows.push(input.slice(0, wrap));
+ input = input.slice(wrap);
+ }
+ if (input.length > 0)
+ rows.push(input);
+ }
+
+ wrap_row(north);
+ wrap_row(south);
+
+ for (let r = 0; r < rows.length; ++r) {
+ let cols = rows[r];
+ for (let c = 0; c < cols.length; ++c)
+ position_block(town, r, rows.length, c, cols.length, cols[c]);
+ }
+}
+
+function layout_blocks_spread_old(town, secret, known) {
let wrap = TOWNS[town].wrap;
let s = secret.length;
let k = known.length;
@@ -465,6 +496,8 @@ function update_map() {
let town = game.location[b];
if (town in TOWNS) {
let moved = game.moved[b] ? " moved" : "";
+ let castle = game.castle[b] ? " castle" : "";
+ // TODO: show besieging blocks too!
if (info.owner == player || info.owner == ASSASSINS) {
let image = " known block_" + info.image;
let steps = " r" + (info.steps - game.steps[b]);
@@ -493,7 +526,7 @@ function update_map() {
for (let where of game.actions.town)
ui.towns[where].classList.add('highlight');
if (game.muster)
- ui.towns[game.where].classList.add('muster');
+ ui.towns[game.muster].classList.add('muster');
if (!game.battle) {
if (game.actions && game.actions.block)