diff options
-rw-r--r-- | about.html | 8 | ||||
-rw-r--r-- | play.css | 89 | ||||
-rw-r--r-- | play.html | 42 | ||||
-rw-r--r-- | play.js | 126 |
4 files changed, 152 insertions, 113 deletions
@@ -4,14 +4,10 @@ from the Ionian Revolt in 499 BCE to the Peace of Callias around 449 BCE. One player leads the Greek army, assembled around Athens and Sparta, and the other leads the Persian army. -<br clear="left"> - <p> Designer: Yasushi Nakaguro - -<p> -© 2018 Bonsai Games & -© 2020 <a href="https://www.nutspublishing.com/eshop/our-games/300-en">Nuts! Publishing</a> +<br> Copyright © 2018 Bonsai Games & © 2020 <a href="https://www.nutspublishing.com/eshop/our-games/300-en">Nuts! Publishing</a>. +<br> Programming © 2021 Tor Andersson. <ul> <li><a href="/300-earth-and-water/info/rules.html">Rulebook</a> @@ -45,12 +45,12 @@ body.Greece header.your_turn { background-color: salmon; } } .role_info { - padding: 10px 20px; + padding: 3px 18px; background-color: gainsboro; white-space: pre-wrap; } .card_info { - padding: 10px 20px; + padding: 3px 18px; background-color: silver; } #deck_info { @@ -68,13 +68,20 @@ body.Greece header.your_turn { background-color: salmon; } } .hand { - margin: 15px; + margin-top: 15px; + padding: 15px; display: flex; flex-wrap: wrap; justify-content: center; min-height: 370px; } +@media (max-width: 800px) { + .hand { + min-width: 1210px; + } +} + .hand .card { margin: 10px; } @@ -95,7 +102,7 @@ body.Greece header.your_turn { background-color: salmon; } } .card_info .card { - margin: 15px auto; + margin: 10px auto 5px auto; width: 125px; height: 175px; border-radius: 10px; @@ -105,54 +112,43 @@ body.Greece header.your_turn { background-color: salmon; } border-bottom: 1px solid black; } -#tooltip.card { +#tooltip { + pointer-events: none; position: fixed; - z-index: 200; + z-index: 600; right: 230px; top: 60px; } -/* PHONE SIZE: squeeze side bar on small screens */ - -#log_button { display: none } - -@media (max-height: 700px) { - .card_info .card { - margin: 0 auto; - width: 100px; - height: 140px; - border-radius: 5px; +@media (max-width: 800px) { + #tooltip { + top: 0; + left: 0; + right: 0; + bottom: 0; + margin: auto; } - .role_info { padding: 3px 20px; } - .card_info { padding: 5px 0px; } - #deck_info { padding-top: 5px; } } -@media (max-width: 1200px) { - #prompt { - font-size: medium; - margin: 0 5px; - } - #log_button { display: block } +@media (max-height: 700px) { + .card_info { padding: 3px 18px; } + .card_info .card { display: none; } } /* CARD ACTION POPUP MENU */ #popup { - position: fixed; - user-select: none; - background-color: gainsboro; - left: 10px; - top: 100px; - box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.3); - z-index: 200; - min-width: 20ex; - white-space: nowrap; - display: none; + min-width: 150px; + box-shadow: 0px 8px 16px 0px #0004; } -#popup div { padding: 3pt 8pt; color: gray; } -#popup div.enabled { color: black; } -#popup div.enabled:hover { background-color: teal; color: white; } + +body.Greece #popup { background-color: hsl(12, 40%, 93%) } +body.Greece #popup li.title { color: black; background-color: hsl(12, 40%, 78%) } +body.Greece #popup li.action:hover { background-color: hsl(12, 40%, 43%) } + +body.Persia #popup { background-color: hsl(216, 21%, 86%) } +body.Persia #popup li.title { color: black; background-color: hsl(216, 21%, 71%) } +body.Persia #popup li.action:hover { background-color: hsl(216, 21%, 31%) } /* MAP WITH ARMIES, FLEETS, AND MARKERS */ @@ -278,23 +274,6 @@ body.Greece header.your_turn { background-color: salmon; } left: 932px; top: 655px; } -/* MOBILE PHONE LAYOUT */ - -@media (max-width: 640px) { - .hand .card { - width: 125px; - height: 175px; - border-radius: 6px; - } - .hand { - min-height: 125px; - } - #tooltip.card { - top: 10px; - right: 10px; - } -} - /* CARD IMAGES */ .card_back { background-image: url('cards.1x/card_back.jpg'); } @@ -1,41 +1,41 @@ <!DOCTYPE html> <html lang="en"> <head> -<meta name="viewport" content="width=device-width, height=device-height, initial-scale=1"> +<meta name="viewport" content="width=device-width, height=device-height, user-scalable=no, interactive-widget=resizes-content, viewport-fit=cover"> +<meta name="theme-color" content="#444"> <meta charset="UTF-8"> <title>300: E&W</title> <link rel="icon" href="Achaemenid_Falcon.svg"> <link rel="stylesheet" href="/fonts/fonts.css"> -<link rel="stylesheet" href="/common/play.css"> +<link rel="stylesheet" href="/common/client.css"> <link rel="stylesheet" href="play.css"> -<script defer src="/common/play.js"></script> +<script defer src="/common/client.js"></script> <script defer src="play.js"></script> </head> <body> <div id="tooltip" class="card"></div> -<div id="popup" onmouseleave="hide_popup_menu()"> - <div id="menu_card_event" onclick="on_card_event()">Play Event</div> - <div id="menu_card_move" onclick="on_card_move()">Play for Movement</div> -</div> +<menu id="popup"> + <li class="title">TITLE + <li class="separator"> + <li data-action="card_event"> 🎴 Event + <li data-action="card_move"> 👣 Movement +</menu> <header> <div id="toolbar"> - <div class="menu"> - <div class="menu_title"><img src="/images/cog.svg"></div> - <div class="menu_popup"> - <a class="menu_item" href="info/notes.html" target="_blank">Notes</a> - <a class="menu_item" href="info/rules.html" target="_blank">Rules</a> - <a class="menu_item" href="info/cards.html" target="_blank">Cards</a> - <div class="resign menu_separator"></div> - <div class="resign menu_item" onclick="confirm_resign()">Resign</div> - </div> - </div> - <div id="log_button" class="icon_button" onclick="toggle_log()"><img src="/images/scroll-quill.svg"></div> + <details> + <summary><img src="/images/cog.svg"></summary> + <menu> + <li><a href="info/notes.html" target="_blank">Notes</a> + <li><a href="info/rules.html" target="_blank">Rules</a> + <li><a href="info/cards.html" target="_blank">Cards</a> + <li class="resign separator"> + <li class="resign" onclick="confirm_resign()">Resign + </menu> + </details> </div> - <div id="prompt"></div> - <div id="actions"></div> </header> <aside> @@ -56,7 +56,7 @@ <div id="log"></div> </aside> -<main> +<main data-min-zoom="1" data-max-zoom="2" onmousedown="hide_popup_menu()"> <div id="map"> <div id="campaign" class="marker campaign_1"></div> @@ -19,6 +19,44 @@ const SPACES = [ "extra", ]; +const PERSIAN_EVENT_NAMES = { + 1: "Cavalry of Mardonius", + 2: "Tribute of Earth and Water", + 3: "Tribute of Earth and Water", + 4: "Carneia Festival", + 5: "The Immortals", + 6: "Ostracism", + 7: "The Great King", + 8: "The Royal Road", + 9: "Hippias", + 10: "Separate Peace", + 11: "Sudden Death of the Great King", + 12: "Defection of Thebes", + 13: "Tribute of Earth and Water", + 14: "Alliance with Carthage", + 15: "Acropolis on Fire", + 16: "Pacification of Babylon or Egypt", +}; + +const GREEK_EVENT_NAMES = { + 1: "Mines of Laurion", + 2: "Ionian Revolt", + 3: "Wrath of Poseidon", + 4: "Miltiades", + 5: "Themistocles", + 6: "Pausanias", + 7: "Oracle of Delphi", + 8: "Leonidas", + 9: "Artemisia I", + 10: "Evangelion", + 11: "Melas Zomos", + 12: "Molon Labe", + 13: "Triremes", + 14: "Support from Syracuse", + 15: "300 Spartans", + 16: "Desertion of Greek Soldiers", +}; + const PORTS = { "Abydos":{"x":866,"y":625,"w":138,"h":138,"layout_x":855,"layout_y":585,"wrap":4}, "Ephesos":{"x":450,"y":765,"w":138,"h":138,"layout_x":424,"layout_y":743,"wrap":3}, @@ -57,6 +95,7 @@ let ui = { all_armies: [], selected_armies: null, selected_fleets: null, + popup_label: document.getElementById("menu_card_label"), }; function on_log(text) { @@ -570,28 +609,61 @@ function update_ui() { e.classList.remove("selected"); } -let current_popup_card = 0; -function show_popup_menu(evt, list) { - document.querySelectorAll("#popup div").forEach(e => e.classList.remove('enabled')); - for (let item of list) { - let e = document.getElementById("menu_" + item); - e.classList.add('enabled'); +function is_action(action, card) { + return view.actions && view.actions[action] && view.actions[action].includes(card); +} + +function show_popup_menu(evt, menu_id, target_id, title) { + let menu = document.getElementById(menu_id) + + let show = true + for (let item of menu.querySelectorAll("li")) { + let action = item.dataset.action + if (action) { + if (is_action(action, target_id)) { + show = true + item.classList.add("action") + item.classList.remove("disabled") + item.onclick = function () { + send_action(action, target_id) + hide_popup_menu() + evt.stopPropagation() + } + } else { + item.classList.remove("action") + item.classList.add("disabled") + item.onclick = null + } + } } - let popup = document.getElementById("popup"); - popup.style.display = 'block'; - popup.style.left = (evt.clientX-50) + "px"; - popup.style.top = (evt.clientY-12) + "px"; - ui.cards[current_popup_card].classList.add("selected"); + + if (show) { + menu.onmouseleave = hide_popup_menu + menu.style.display = "block" + if (title) { + let item = menu.querySelector("li.title") + if (item) { + item.onclick = hide_popup_menu + item.textContent = title + } + } + + let w = menu.clientWidth + let h = menu.clientHeight + let x = Math.max(5, Math.min(evt.clientX - w / 2, window.innerWidth - w - 5)) + let y = Math.max(5, Math.min(evt.clientY - 12, window.innerHeight - h - 40)) + menu.style.left = x + "px" + menu.style.top = y + "px" + + return true + } + + return false } function hide_popup_menu() { - let popup = document.getElementById("popup"); - popup.style.display = 'none'; - if (current_popup_card) { - ui.cards[current_popup_card].classList.remove("selected"); - current_popup_card = 0; - } + document.getElementById("popup").style.display = "none" } function on_card_event() { @@ -603,25 +675,17 @@ function on_card_move() { hide_popup_menu(); } -function is_card_action(action, card) { - return view.actions && view.actions[action] && view.actions[action].includes(card); -} - function on_card(evt) { if (view.actions) { let card = evt.target.card; - if (is_card_action('discard', card)) { + if (is_action('discard', card)) { send_action('discard', card); } else { - let menu = []; - if (is_card_action('card_event', card)) - menu.push('card_event'); - if (is_card_action('card_move', card)) - menu.push('card_move'); - if (menu.length > 0) { - current_popup_card = card; - show_popup_menu(evt, menu); - } + if (player === GREECE) + show_popup_menu(evt, "popup", card, GREEK_EVENT_NAMES[card]) + else + show_popup_menu(evt, "popup", card, PERSIAN_EVENT_NAMES[card]) + evt.stopPropagation() } } } |