summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--about.html8
-rw-r--r--play.css89
-rw-r--r--play.html42
-rw-r--r--play.js126
4 files changed, 152 insertions, 113 deletions
diff --git a/about.html b/about.html
index 3e9110a..8f1fba5 100644
--- a/about.html
+++ b/about.html
@@ -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>
-&copy; 2018 Bonsai Games &amp;
-&copy; 2020 <a href="https://www.nutspublishing.com/eshop/our-games/300-en">Nuts! Publishing</a>
+<br> Copyright &copy; 2018 Bonsai Games &amp; &copy; 2020 <a href="https://www.nutspublishing.com/eshop/our-games/300-en">Nuts! Publishing</a>.
+<br> Programming &copy; 2021 Tor Andersson.
<ul>
<li><a href="/300-earth-and-water/info/rules.html">Rulebook</a>
diff --git a/play.css b/play.css
index b38db82..cb58ac6 100644
--- a/play.css
+++ b/play.css
@@ -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'); }
diff --git a/play.html b/play.html
index c2fe1e7..8bd7ae2 100644
--- a/play.html
+++ b/play.html
@@ -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&amp;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"> &#x1f3b4; &nbsp; Event
+ <li data-action="card_move"> &#x1f463; &nbsp; 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>
diff --git a/play.js b/play.js
index d36c503..7249bee 100644
--- a/play.js
+++ b/play.js
@@ -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()
}
}
}