diff options
-rw-r--r-- | data.js | 308 | ||||
-rw-r--r-- | play.html | 33 | ||||
-rw-r--r-- | rules.js | 69 | ||||
-rw-r--r-- | ui.js | 41 |
4 files changed, 262 insertions, 189 deletions
@@ -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); @@ -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> @@ -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, @@ -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) |