diff options
author | Tor Andersson <tor@ccxvii.net> | 2023-12-03 13:37:27 +0100 |
---|---|---|
committer | Tor Andersson <tor@ccxvii.net> | 2023-12-03 15:26:05 +0100 |
commit | 4d19bd25fbbb95709d638b3cc75288ce470034dc (patch) | |
tree | 93763b46e9867a34850d116868ce59977ea6e8da | |
parent | 3adbb5a988aea0fc5ab2d09d50a4d6d9a5933a5e (diff) | |
download | julius-caesar-4d19bd25fbbb95709d638b3cc75288ce470034dc.tar.gz |
Show road limits and last used on map.
-rw-r--r-- | play.css | 23 | ||||
-rw-r--r-- | play.html | 1 | ||||
-rw-r--r-- | play.js | 258 | ||||
-rw-r--r-- | rules.js | 5 |
4 files changed, 281 insertions, 6 deletions
@@ -198,6 +198,26 @@ header.your_turn { background-color: orange; } background-color: #0368; } +.road { + position: absolute; + width: 24px; + height: 24px; + border-radius: 50%; + text-align: center; + line-height: 24px; + font-size: 16px; + font-weight: bold; + color: #432; + box-shadow: 0 0 4px 1px #0006; +} + +.road.major { background-color: #c1da96; color: #432; } +.road.minor { background-color: #c1da96; color: #432; } +.road.strait { background-color: #92d6e2; color: #234; } + +.road.Caesar { background-color: #b22; color: gold; } +.road.Pompeius { background-color: #eb2; color: brown; } + #blocks.hide_blocks { display: none; } @@ -284,9 +304,6 @@ body.shift .block.known:hover { background-position: center; } -/* -.block.battle { filter: grayscale(60%) brightness(60%) !important } -*/ .block.battle { opacity: 0; pointer-events: none; } .block { @@ -76,6 +76,7 @@ </details> <div id="offmap" style="visibility:hidden"></div> + <div id="roads"></div> <div id="blocks"></div> <div id="spaces"></div> <div id="turn" class="year_705"></div> @@ -16,6 +16,21 @@ function set_has(set, item) { return false } +function map_get(map, key, missing) { + let a = 0 + let b = (map.length >> 1) - 1 + while (a <= b) { + let m = (a + b) >> 1 + let x = map[m<<1] + if (key < x) + b = m - 1 + else if (key > x) + a = m + 1 + else + return map[(m<<1)+1] + } + return missing +} const CAESAR = "Caesar" const POMPEIUS = "Pompeius" @@ -87,6 +102,7 @@ let ui = { cards: [], card_backs: [], spaces: [], + roads: [], blocks: [], battle_menu: [], battle_block: [], @@ -95,6 +111,201 @@ let ui = { present: new Set(), } +// :r !node tools/genroads.js +const ROADS_XY = { + "Aenos / Byzantium": [ 1953, 440 ], + "Aenos / Pergamum": [ 1912, 491 ], + "Aenos / Serdica": [ 1813, 388 ], + "Aenos / Thessalonica": [ 1806, 453 ], + "Alexandria / Catabathmus": [ 1962, 1102 ], + "Alexandria / Memphis": [ 2100, 1138 ], + "Alexandria / Pelusium": [ 2145, 1069 ], + "Ambracia / Athenae": [ 1648, 636 ], + "Ambracia / Dyrrachium": [ 1571, 555 ], + "Ancyra / Appia": [ 2137, 508 ], + "Ancyra / Eusebia": [ 2286, 506 ], + "Ancyra / Nicomedia": [ 2143, 461 ], + "Ancyra / Sinope": [ 2286, 426 ], + "Antiochia / Damascus": [ 2420, 787 ], + "Antiochia / Tarsus": [ 2348, 666 ], + "Appia / Ephesus": [ 2026, 601 ], + "Appia / Nicomedia": [ 2064, 496 ], + "Appia / Perga": [ 2086, 626 ], + "Aquileia / Ravenna": [ 1176, 230 ], + "Aquileia / Salona": [ 1314, 257 ], + "Aquileia / Sirmium": [ 1382, 180 ], + "Asculum / Ravenna": [ 1210, 340 ], + "Asculum / Roma": [ 1219, 410 ], + "Asculum / Sipontum": [ 1297, 440 ], + "Asturica / Bilbilis": [ 369, 556 ], + "Asturica / Emerita": [ 253, 677 ], + "Asturica / Portus": [ 191, 623 ], + "Asturica / Toletum": [ 332, 642 ], + "Athenae / Pylos": [ 1687, 700 ], + "Athenae / Thessalonica": [ 1704, 571 ], + "Badias / Iomnium": [ 856, 908 ], + "Badias / Tacape": [ 1001, 1010 ], + "Badias / Utica": [ 1016, 905 ], + "Bilbilis / Burdigala": [ 499, 452 ], + "Bilbilis / Tarraco": [ 536, 580 ], + "Bilbilis / Toletum": [ 429, 643 ], + "Brundisium / Neapolis": [ 1360, 519 ], + "Brundisium / Sipontum": [ 1402, 496 ], + "Burdigala / Cenabum": [ 589, 224 ], + "Burdigala / Narbo": [ 607, 406 ], + "Byzantium / Nicomedia": [ 2034, 427 ], + "Carthago Nova / Corduba": [ 415, 825 ], + "Carthago Nova / Gades": [ 390, 885 ], + "Carthago Nova / Tarraco": [ 542, 708 ], + "Carthago Nova / Toletum": [ 448, 749 ], + "Catabathmus / Cyrene": [ 1712, 1035 ], + "Cenabum / Lugdunum": [ 743, 191 ], + "Cenabum / Treviri": [ 768, 82 ], + "Corduba / Gades": [ 294, 865 ], + "Corduba / Toletum": [ 389, 778 ], + "Cyrene / Thubactus": [ 1431, 1173 ], + "Damascus / Jerusalem": [ 2375, 923 ], + "Dyrrachium / Salona": [ 1516, 387 ], + "Dyrrachium / Thessalonica": [ 1616, 486 ], + "Emerita / Gades": [ 239, 838 ], + "Emerita / Olisipo": [ 178, 774 ], + "Ephesus / Perga": [ 2024, 712 ], + "Ephesus / Pergamum": [ 1931, 566 ], + "Eusebia / Sinope": [ 2371, 474 ], + "Eusebia / Tarsus": [ 2298, 617 ], + "Gades / Olisipo": [ 186, 864 ], + "Gades / Tingis": [ 281, 964 ], + "Genua / Lugdunum": [ 916, 268 ], + "Genua / Massilia": [ 944, 359 ], + "Genua / Ravenna": [ 1107, 279 ], + "Genua / Roma": [ 1093, 385 ], + "Iomnium / Siga": [ 632, 903 ], + "Iomnium / Utica": [ 937, 834 ], + "Jerusalem / Pelusium": [ 2295, 1058 ], + "Lilybaeum / Messana": [ 1261, 721 ], + "Lilybaeum / Syracusae": [ 1257, 766 ], + "Lugdunum / Massilia": [ 811, 321 ], + "Lugdunum / Treviri": [ 851, 159 ], + "Massilia / Narbo": [ 746, 405 ], + "Memphis / Pelusium": [ 2136, 1118 ], + "Messana / Rhegium": [ 1344, 708 ], + "Messana / Syracusae": [ 1315, 740 ], + "Narbo / Tarraco": [ 700, 527 ], + "Neapolis / Rhegium": [ 1375, 624 ], + "Neapolis / Roma": [ 1263, 497 ], + "Neapolis / Sipontum": [ 1325, 499 ], + "Nicomedia / Pergamum": [ 1992, 493 ], + "Nicomedia / Sinope": [ 2197, 377 ], + "Olisipo / Portus": [ 118, 720 ], + "Perga / Tarsus": [ 2206, 727 ], + "Ravenna / Roma": [ 1175, 366 ], + "Sala / Siga": [ 373, 1071 ], + "Sala / Tingis": [ 253, 1044 ], + "Salona / Sirmium": [ 1426, 267 ], + "Serdica / Sirmium": [ 1631, 247 ], + "Serdica / Thessalonica": [ 1693, 403 ], + "Siga / Tingis": [ 382, 1009 ], + "Tacape / Thubactus": [ 1167, 1086 ], + "Tacape / Utica": [ 1092, 917 ], +} + +const ROADS_BG = { + "Aenos / Byzantium": "hsl(83, 50%, 73%)", + "Aenos / Pergamum": "hsl(189, 64%, 75%)", + "Aenos / Serdica": "hsl(112, 43%, 67%)", + "Aenos / Thessalonica": "hsl(86, 43%, 69%)", + "Alexandria / Catabathmus": "hsl(77, 56%, 79%)", + "Alexandria / Memphis": "hsl(92, 46%, 67%)", + "Alexandria / Pelusium": "hsl(91, 52%, 74%)", + "Ambracia / Athenae": "hsl(77, 58%, 77%)", + "Ambracia / Dyrrachium": "hsl(77, 47%, 78%)", + "Ancyra / Appia": "hsl(79, 49%, 68%)", + "Ancyra / Eusebia": "hsl(99, 48%, 69%)", + "Ancyra / Nicomedia": "hsl(76, 58%, 71%)", + "Ancyra / Sinope": "hsl(80, 55%, 70%)", + "Antiochia / Damascus": "hsl(71, 42%, 65%)", + "Antiochia / Tarsus": "hsl(81, 50%, 73%)", + "Appia / Ephesus": "hsl(78, 58%, 71%)", + "Appia / Nicomedia": "hsl(76, 48%, 66%)", + "Appia / Perga": "hsl(78, 55%, 71%)", + "Aquileia / Ravenna": "hsl(92, 45%, 74%)", + "Aquileia / Salona": "hsl(79, 52%, 80%)", + "Aquileia / Sirmium": "hsl(118, 40%, 66%)", + "Asculum / Ravenna": "hsl(79, 50%, 80%)", + "Asculum / Roma": "hsl(99, 43%, 68%)", + "Asculum / Sipontum": "hsl(73, 55%, 82%)", + "Asturica / Bilbilis": "hsl(119, 44%, 70%)", + "Asturica / Emerita": "hsl(87, 53%, 71%)", + "Asturica / Portus": "hsl(82, 46%, 66%)", + "Asturica / Toletum": "hsl(104, 51%, 72%)", + "Athenae / Pylos": "hsl(75, 40%, 63%)", + "Athenae / Thessalonica": "hsl(80, 53%, 75%)", + "Badias / Iomnium": "hsl(75, 55%, 70%)", + "Badias / Tacape": "hsl(66, 45%, 67%)", + "Badias / Utica": "hsl(74, 56%, 71%)", + "Bilbilis / Burdigala": "hsl(106, 42%, 69%)", + "Bilbilis / Tarraco": "hsl(62, 52%, 71%)", + "Bilbilis / Toletum": "hsl(87, 49%, 68%)", + "Brundisium / Neapolis": "hsl(83, 49%, 69%)", + "Brundisium / Sipontum": "hsl(72, 53%, 81%)", + "Burdigala / Cenabum": "hsl(118, 37%, 66%)", + "Burdigala / Narbo": "hsl(112, 44%, 68%)", + "Byzantium / Nicomedia": "hsl(189, 65%, 75%)", + "Carthago Nova / Corduba": "hsl(72, 54%, 70%)", + "Carthago Nova / Gades": "hsl(62, 44%, 68%)", + "Carthago Nova / Tarraco": "hsl(74, 53%, 78%)", + "Carthago Nova / Toletum": "hsl(80, 59%, 72%)", + "Catabathmus / Cyrene": "hsl(81, 52%, 78%)", + "Cenabum / Lugdunum": "hsl(114, 43%, 67%)", + "Cenabum / Treviri": "hsl(116, 28%, 60%)", + "Corduba / Gades": "hsl(80, 59%, 72%)", + "Corduba / Toletum": "hsl(82, 54%, 70%)", + "Cyrene / Thubactus": "hsl(77, 51%, 81%)", + "Damascus / Jerusalem": "hsl(69, 49%, 68%)", + "Dyrrachium / Salona": "hsl(80, 46%, 69%)", + "Dyrrachium / Thessalonica": "hsl(81, 45%, 66%)", + "Emerita / Gades": "hsl(79, 58%, 72%)", + "Emerita / Olisipo": "hsl(74, 64%, 73%)", + "Ephesus / Perga": "hsl(77, 45%, 75%)", + "Ephesus / Pergamum": "hsl(78, 59%, 81%)", + "Eusebia / Sinope": "hsl(103, 44%, 74%)", + "Eusebia / Tarsus": "hsl(86, 45%, 68%)", + "Gades / Olisipo": "hsl(78, 64%, 78%)", + "Gades / Tingis": "hsl(189, 65%, 75%)", + "Genua / Lugdunum": "hsl(81, 33%, 78%)", + "Genua / Massilia": "hsl(81, 40%, 72%)", + "Genua / Ravenna": "hsl(119, 41%, 66%)", + "Genua / Roma": "hsl(83, 50%, 75%)", + "Iomnium / Siga": "hsl(84, 53%, 76%)", + "Iomnium / Utica": "hsl(82, 53%, 77%)", + "Jerusalem / Pelusium": "hsl(76, 54%, 77%)", + "Lilybaeum / Messana": "hsl(70, 49%, 81%)", + "Lilybaeum / Syracusae": "hsl(78, 56%, 82%)", + "Lugdunum / Massilia": "hsl(105, 37%, 63%)", + "Lugdunum / Treviri": "hsl(115, 43%, 67%)", + "Massilia / Narbo": "hsl(85, 55%, 71%)", + "Memphis / Pelusium": "hsl(98, 46%, 68%)", + "Messana / Rhegium": "hsl(189, 64%, 75%)", + "Messana / Syracusae": "hsl(77, 49%, 74%)", + "Narbo / Tarraco": "hsl(83, 48%, 73%)", + "Neapolis / Rhegium": "hsl(76, 53%, 81%)", + "Neapolis / Roma": "hsl(81, 54%, 75%)", + "Neapolis / Sipontum": "hsl(87, 51%, 74%)", + "Nicomedia / Pergamum": "hsl(76, 57%, 74%)", + "Nicomedia / Sinope": "hsl(76, 57%, 79%)", + "Olisipo / Portus": "hsl(74, 42%, 78%)", + "Perga / Tarsus": "hsl(76, 45%, 73%)", + "Ravenna / Roma": "hsl(102, 43%, 72%)", + "Sala / Siga": "hsl(83, 46%, 66%)", + "Sala / Tingis": "hsl(77, 54%, 78%)", + "Salona / Sirmium": "hsl(105, 38%, 64%)", + "Serdica / Sirmium": "hsl(114, 39%, 67%)", + "Serdica / Thessalonica": "hsl(98, 34%, 76%)", + "Siga / Tingis": "hsl(78, 51%, 81%)", + "Tacape / Thubactus": "hsl(68, 53%, 76%)", + "Tacape / Utica": "hsl(88, 50%, 74%)", +} + function remember_position(e) { if (e.classList.contains("show")) { let rect = e.getBoundingClientRect() @@ -410,6 +621,21 @@ function build_map() { ui.cards[c] = document.getElementById("card+" + c) for (let c = 1; c <= 6; ++c) ui.card_backs[c] = document.getElementById("back+" + c) + + for (let name in ROADS_XY) { + let [x, y] = ROADS_XY[name] + let [a, b] = name.split(" / ") + let id = SPACES.findIndex(s=>s.name===a) * 100 + SPACES.findIndex(s=>s.name===b) + let e = document.createElement("div") + e.my_id = id + e.my_bgnd = ROADS_BG[name] + e.my_show = "road " + EDGES[id] + e.className = "hide" + e.style.left = (x - 12) + "px" + e.style.top = (y - 12) + "px" + ui.roads.push(e) + document.getElementById("roads").appendChild(e) + } } function update_steps(block, element, animate) { @@ -646,6 +872,33 @@ function update_map() { if (view.actions && view.actions.secret && view.actions.secret.includes(s)) ui.blocks[b].classList.add('highlight') } + + for (let e of ui.roads) { + let cu = set_has(view.last_used[0], e.my_id) + let pu = set_has(view.last_used[1], e.my_id) + let n = map_get(view.limits, e.my_id, "") + if (n && view.main_road && set_has(view.main_road, e.my_id)) + n += "*" + if (cu) { + e.style.backgroundColor = null + e.className = "road Caesar" + e.textContent = n + } else if (pu) { + e.style.backgroundColor = null + e.className = "road Pompeius" + e.textContent = n + } else { + if (n) { + e.style.backgroundColor = e.my_bgnd + e.className = e.my_show + e.textContent = n + } else { + e.style.backgroundColor = null + e.className = "hide" + e.textContent = "" + } + } + } } function compare_blocks(a, b, ballista) { @@ -873,8 +1126,7 @@ function select_card(c) { } document.getElementById("battle").addEventListener("toggle", on_update) - -build_map() - document.getElementById("blocks").classList.add(label_style+'-labels') document.getElementById("battle").classList.add(label_style+'-labels') + +build_map() @@ -2832,11 +2832,16 @@ exports.view = function(state, current) { traitor: game.traitor, steps: game.steps, moved: game.moved, + limits: game.limits, + last_used: [ game.c_last_used, game.p_last_used ], battle: null, prompt: null, actions: null, } + if (game.main_road && game.main_road.length > 0) + view.main_road = game.main_road + states[game.state].prompt(view, current) if (states[game.state].show_battle) |