summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Andersson <tor@ccxvii.net>2024-05-28 01:48:36 +0200
committerTor Andersson <tor@ccxvii.net>2024-05-30 21:59:25 +0200
commitff01812e85b4744c9ac1f6826e0bf5c53182aa2a (patch)
tree2d9b3b937fb8f57b3307f8126e701e913bdf57bd
parent810e98edf8af847903f8ef4e0700da90b57546a3 (diff)
downloadfriedrich-ff01812e85b4744c9ac1f6826e0bf5c53182aa2a.tar.gz
show stats in power panels
-rw-r--r--play.css52
-rw-r--r--play.html12
-rw-r--r--play.js122
-rw-r--r--rules.js2
4 files changed, 151 insertions, 37 deletions
diff --git a/play.css b/play.css
index 4a776c1..f82e5d6 100644
--- a/play.css
+++ b/play.css
@@ -34,6 +34,16 @@
--color-light-austria: hsl(0, 0%, 97%);
--color-light-imperial: hsl(55, 85%, 75%);
--color-light-france: hsl(0, 70%, 80%);
+ --color-light-clock: hsl(52, 37%, 80%);
+
+ --color-medium-prussia: hsl(210, 30%, 60%);
+ --color-medium-hanover: hsl(200, 25%, 65%);
+ --color-medium-russia: hsl(120, 20%, 55%);
+ --color-medium-sweden: hsl(80, 25%, 55%);
+ --color-medium-austria: hsl(0, 0%, 90%);
+ --color-medium-imperial: hsl(55, 35%, 60%);
+ --color-medium-france: hsl(0, 35%, 70%);
+ --color-medium-clock: hsl(52, 25%, 70%);
--color-dark-prussia: hsl(198, 100%, 24%);
--color-dark-hanover: hsl(203, 72%, 75%);
@@ -118,7 +128,6 @@ span.suit.reserve { color: var(--color-reserve); font-size: 18px; font-weight: b
#mapwrap {
width: 2485px;
height: 1654px;
- margin-bottom: 30px;
}
#map {
@@ -215,13 +224,23 @@ TWOD.piece.cylinder {
.number.france { background-color: var(--color-france); }
*/
-#hand_prussia_header { background-color: var(--color-dark-prussia); color: white; }
-#hand_hanover_header { background-color: var(--color-dark-hanover); color: black; }
-#hand_russia_header { background-color: var(--color-dark-russia); color: white; }
-#hand_sweden_header { background-color: var(--color-dark-sweden); color: black; }
-#hand_austria_header { background-color: var(--color-dark-austria); color: black; }
-#hand_imperial_header { background-color: var(--color-dark-imperial); color: black; }
-#hand_france_header { background-color: var(--color-dark-france); color: black; }
+#hand_prussia_header { background-color: var(--color-light-prussia); }
+#hand_hanover_header { background-color: var(--color-light-hanover); }
+#hand_russia_header { background-color: var(--color-light-russia); }
+#hand_sweden_header { background-color: var(--color-light-sweden); }
+#hand_austria_header { background-color: var(--color-light-austria); }
+#hand_imperial_header { background-color: var(--color-light-imperial); }
+#hand_france_header { background-color: var(--color-light-france); }
+#clock_of_fate_header { background-color: var(--color-light-clock); }
+
+#hand_prussia_panel { background-color: var(--color-medium-prussia); }
+#hand_hanover_panel { background-color: var(--color-medium-hanover); }
+#hand_russia_panel { background-color: var(--color-medium-russia); }
+#hand_sweden_panel { background-color: var(--color-medium-sweden); }
+#hand_austria_panel { background-color: var(--color-medium-austria); }
+#hand_imperial_panel { background-color: var(--color-medium-imperial); }
+#hand_france_panel { background-color: var(--color-medium-france); }
+#clock_of_fate_panel { background-color: var(--color-medium-clock); }
.marker {
pointer-events: none;
@@ -243,23 +262,22 @@ TWOD.piece.cylinder {
}
.panel {
- background-color: #444;
- width: clamp(824px, calc(100% - 30px), 1636px);
- margin: 12px auto 36px auto;
- box-shadow: 1px 2px 6px #0004;
+ background-color: darkgray;
+ width: clamp(500px, calc(100% - 48px), 2485px);
+ margin: 24px auto;
+ box-shadow: 2px 2px 4px #0006;
border: 1px solid #0008;
+ padding: 4px;
}
.panel_header {
- color: white;
- font-weight: bold;
+ border: 1px solid #000a;
+ box-shadow: 1px 1px 4px #0003;
text-align: center;
- padding: 3px 1em;
- border-bottom: 1px solid #0008;
+ padding: 2px 0;
}
.panel_body {
- background-color: #555;
display: flex;
justify-content: start;
flex-wrap: wrap;
diff --git a/play.html b/play.html
index f384dac..3f4a3d6 100644
--- a/play.html
+++ b/play.html
@@ -44,18 +44,6 @@
</div>
</div>
-<div id="defend_panel" class="panel hide">
-<div id="defend_header" class="panel_header">Defend</div>
-<div id="defend" class="panel_body">
-</div>
-</div>
-
-<div id="attack_panel" class="panel hide">
-<div id="attack_header" class="panel_header">Attack</div>
-<div id="attack" class="panel_body">
-</div>
-</div>
-
<div id="power_panel_list">
<div id="hand_prussia_panel" class="panel">
diff --git a/play.js b/play.js
index 9272ab0..2ceef9f 100644
--- a/play.js
+++ b/play.js
@@ -15,6 +15,8 @@ function toggle_pieces() {
/* DATA */
+const max_power_troops = [ 32, 12, 16, 4, 30, 6, 20 ]
+
const P_PRUSSIA = 0
const P_HANOVER = 1
const P_RUSSIA = 2
@@ -26,6 +28,13 @@ const P_FRANCE = 6
const cities = data.cities
const last_city = cities.name.length - 1
+const FC_POEMS = 13
+const FC_LORD_BUTE = 14
+const FC_ELISABETH = 15
+const FC_SWEDEN = 16
+const FC_INDIA = 17
+const FC_AMERICA = 18
+
const ELIMINATED = data.cities.name.length
const REMOVED = ELIMINATED + 1
const ELIMINATED_TRAIN_X = 1065
@@ -100,6 +109,49 @@ function to_value(c) {
return c & 15
}
+function count_captured_objectives(pow) {
+ let n = 0
+ for (let s of objective1[pow])
+ if (set_has(view.conquest, s))
+ ++n
+ for (let s of objective2[pow])
+ if (set_has(view.conquest, s))
+ ++n
+ return n
+}
+
+function has_russia_dropped_out() {
+ return set_has(view.fate, FC_ELISABETH)
+}
+
+function has_sweden_dropped_out() {
+ return set_has(view.fate, FC_SWEDEN)
+}
+
+function has_france_dropped_out() {
+ return set_has(view.fate, FC_INDIA) && set_has(view.fate, FC_AMERICA)
+}
+
+function has_imperial_army_switched_players() {
+ return (has_russia_dropped_out() && has_sweden_dropped_out()) || has_france_dropped_out()
+}
+
+function has_eased_victory(power) {
+ if (power === P_SWEDEN)
+ return has_russia_dropped_out()
+ if (power === P_AUSTRIA)
+ return has_imperial_army_switched_players()
+ if (power === P_IMPERIAL)
+ return has_imperial_army_switched_players()
+ return false
+}
+
+function count_total_objectives(pow) {
+ if (has_eased_victory(pow))
+ return objective1[pow].length
+ return objective1[pow].length + objective2[pow].length
+}
+
/* CARD TEXTS */
const fate_flavor_text = [
@@ -252,16 +304,64 @@ const fate_effect_text = [
/* PANEL ORDER */
const panel_order = [ P_PRUSSIA, P_HANOVER, P_RUSSIA, P_SWEDEN, P_AUSTRIA, P_IMPERIAL, P_FRANCE, P_FRANCE+1 ]
+const panel_start = {
+ "Frederick": P_PRUSSIA,
+ "Elisabeth": P_RUSSIA,
+ "Maria Theresa": P_AUSTRIA,
+ "Pompadour": P_FRANCE,
+}
+
+function remember_position(e) {
+ if (e.parentElement) {
+ let rect = e.getBoundingClientRect()
+ e.my_parent = e.parentElement
+ e.my_x = rect.x
+ e.my_y = rect.y
+ } else {
+ e.my_parent = null
+ e.my_x = 0
+ e.my_y = 0
+ }
+}
+
+function animate_position(e) {
+ if (e.parentElement) {
+ if (e.my_parent) {
+ let rect = e.getBoundingClientRect()
+ let dx = e.my_x - rect.x
+ let dy = e.my_y - rect.y
+ if (dx !== 0 || dy !== 0) {
+ e.animate(
+ [
+ { transform: `translate(${dx}px, ${dy}px)`, },
+ { transform: "translate(0, 0)", },
+ ],
+ { duration: 333, easing: "ease" }
+ )
+ }
+ }
+ }
+}
+
+function sort_power_panel(animate) {
+ let start = panel_start[params.role]
+
+ if (animate)
+ for (let i = 0; i < 8; ++i)
+ remember_position(ui.power_panel[i])
-function sort_power_panel() {
- let start = 0
- if (view)
- start = view.power
ui.power_panel_list.replaceChildren()
for (let i = 0; i < 8; ++i) {
let p = panel_order[(i + start) % 8]
ui.power_panel_list.appendChild(ui.power_panel[p])
}
+
+ if (view && view.actions)
+ ui.power_panel_list.prepend(ui.power_panel[view.power])
+
+ if (animate)
+ for (let i = 0; i < 8; ++i)
+ animate_position(ui.power_panel[i])
}
/* BUILD UI */
@@ -542,7 +642,7 @@ function on_init() {
ui.spaces_element.appendChild(e)
}
- sort_power_panel()
+ sort_power_panel(false)
update_favicon()
}
@@ -776,7 +876,7 @@ function on_update() {
ui.header.classList.toggle("imperial", view.power === P_IMPERIAL)
ui.header.classList.toggle("france", view.power === P_FRANCE)
- sort_power_panel()
+ sort_power_panel(true)
for (let g = 0; g <= 23; ++g)
layout_general(g, view.pos[g])
@@ -789,7 +889,15 @@ function on_update() {
ui.turns[i].classList.toggle("hide", (typeof view.fate === "object") || (i + 1 < view.fate))
for (let pow = 0; pow < 7; ++pow) {
- ui.power_header[pow].textContent = power_name[pow] + " - " + view.pt[pow] + " troops"
+ // let banner = `${power_name[pow]} \u2013 ${view.pt[pow]}/${max_power_troops[pow]} troops`
+ let banner = `${power_name[pow]} \u2014 ${view.pt[pow]} troops`
+ let m_obj = count_total_objectives(pow)
+ if (m_obj > 0) {
+ let n_obj = count_captured_objectives(pow)
+ banner += ` \u2014 ${n_obj} of ${m_obj} objectives`
+ }
+
+ ui.power_header[pow].textContent = banner
ui.power_panel[pow].classList.toggle("hide", has_removed_all_pieces(pow))
ui.hand[pow].replaceChildren()
diff --git a/rules.js b/rules.js
index 1dc14df..c56e879 100644
--- a/rules.js
+++ b/rules.js
@@ -4056,7 +4056,7 @@ function total_troops_list() {
let list = []
for (let pow of all_powers) {
let n = 0
- for (let p of all_power_generals)
+ for (let p of all_power_generals[pow])
n += game.troops[p]
list[pow] = n
}