summaryrefslogtreecommitdiff
path: root/play.js
diff options
context:
space:
mode:
authorTor Andersson <tor@ccxvii.net>2025-02-23 18:37:17 +0100
committerTor Andersson <tor@ccxvii.net>2025-03-08 16:32:19 +0100
commitfe2bc3961ec3b3164786074b37e36581b81fa68c (patch)
treebfc80bc4fb161e83f290da6294f0bffe9116500b /play.js
parenta4c2b8458d1059c373c4a714bce0b5f68a3ce20f (diff)
downloadland-and-freedom-fe2bc3961ec3b3164786074b37e36581b81fa68c.tar.gz
New client and client data processing tools.
Diffstat (limited to 'play.js')
-rw-r--r--play.js1060
1 files changed, 578 insertions, 482 deletions
diff --git a/play.js b/play.js
index 5b002e8..9ef91e1 100644
--- a/play.js
+++ b/play.js
@@ -1,495 +1,591 @@
-'use strict';
-Object.defineProperty(exports, "__esModule", { value: true });
-const BONUSES_COUNT = 2;
-const CARD_COUNT = 109;
-const GLORY_COUNT = 9;
-const medallionS_COUNT = 9;
-const STANDEES_COUNT = 5;
-const TRACK_COUNT = 5;
-const TRACK_LENGTH = 11;
-const FACTIONS = ['a', 'c', 'm'];
+"use strict"
+
+/* global view, action_button, send_action */
+
+// TODO: pool for hero points to animate ?
+// TODO: pool for faction markers to animate ?
+
const ui = {
- bag_of_glory: document.getElementById('bag_of_glory'),
- map: document.getElementById('map'),
- medallions_container: document.getElementById('medallions'),
- markers: document.getElementById('markers'),
- fronts: {
- a: {
- front: document.getElementById('aragon_front'),
- value: document.querySelector('#aragon_front .value'),
- contributions: document.querySelector('#aragon_front .contributions'),
- },
- m: {
- front: document.getElementById('madrid_front'),
- value: document.querySelector('#madrid_front .value'),
- contributions: document.querySelector('#madrid_front .contributions'),
- },
- n: {
- front: document.getElementById('northern_front'),
- value: document.querySelector('#northern_front .value'),
- contributions: document.querySelector('#northern_front .contributions'),
- },
- s: {
- front: document.getElementById('southern_front'),
- value: document.querySelector('#southern_front .value'),
- contributions: document.querySelector('#southern_front .contributions'),
- },
- },
- glory_container: document.getElementById('glory'),
- hand: document.getElementById('hand'),
- player_area: document.getElementById('player_area'),
- current_events: document.getElementById('current_events'),
- roles: {
- a: {
- hero_points: document.querySelector('#role_Anarchist .role_stat'),
- medallions: document.querySelector('#role_Anarchist .role_medallions'),
- },
- c: {
- hero_points: document.querySelector('#role_Communist .role_stat'),
- medallions: document.querySelector('#role_Communist .role_medallions'),
- },
- m: {
- hero_points: document.querySelector('#role_Moderate .role_stat'),
- medallions: document.querySelector('#role_Moderate .role_medallions'),
- },
- pool: {
- hero_points: document.getElementById('pool_hero_points'),
- },
- Anarchist: document.getElementById('role_Anarchist'),
- Communist: document.getElementById('role_Communist'),
- Moderate: document.getElementById('role_Moderate'),
- container: document.getElementById('roles'),
- },
- player_area_tabs: {
- hand_tab: document.getElementById('hand_tab'),
- deck_tab: document.getElementById('deck_tab'),
- discard_tab: document.getElementById('discard_tab'),
- trash_tab: document.getElementById('trash_tab'),
- },
- player_area_cards: {
- hand: document.getElementById('hand'),
- deck: document.getElementById('deck'),
- discard: document.getElementById('discard'),
- trash: document.getElementById('trash'),
- },
- player_areas: {
- container: document.getElementById('player_areas'),
- Anarchist: document.getElementById('player_area_Anarchist'),
- Communist: document.getElementById('player_area_Communist'),
- Moderate: document.getElementById('player_area_Moderate'),
- },
- selectable_cards: document.getElementById('selectable_cards'),
- tableaus: {
- a: document.getElementById('tableau_a'),
- c: document.getElementById('tableau_c'),
- m: document.getElementById('tableau_m'),
- },
- tracks: document.getElementById('tracks'),
- hero_points: document.querySelector('#role_Anarchist .role_stat'),
- turn_info: document.getElementById('turn_info'),
- turn_info_card: document.getElementById('turn_info_card'),
- year: document.getElementById('year'),
- blank_markers: [],
- bonuses: [],
- tokens_on_front: {},
- glory: [],
- initiative_token: undefined,
- medallions: [],
- spaces: [],
- standees: [],
- pieces: [],
- cards: [],
-};
-let action_register = [];
-const LAYOUT_BONUSES = [
- [435, 481],
- [493, 481],
-];
-const LAYOUT_CURRENT_EVENTS = [
- [172, 648],
- [309, 648],
- [445, 648],
- [584, 648],
-];
-const LAYOUT_GLORY = [
- [801, 647],
- [860, 647],
- [897, 647],
- [848, 718],
- [775, 771],
- [812, 771],
- [849, 771],
- [885, 771],
- [922, 771],
-];
-const LAYOUT_medallionS = [
- [364, 556],
- [415, 556],
- [466, 556],
- [517, 556],
- [568, 556],
-];
-const LAYOUT_TRACKS = [
- [
- [581, 46],
- [618, 46],
- [655, 46],
- [691, 46],
- [728, 46],
- [765, 46],
- [801, 46],
- [838, 46],
- [874, 46],
- [911, 46],
- [948, 46],
- ],
- [
- [581, 156],
- [618, 156],
- [655, 156],
- [691, 156],
- [728, 156],
- [765, 156],
- [801, 156],
- [838, 156],
- [874, 156],
- [911, 156],
- [948, 156],
- ],
- [
- [581, 267],
- [618, 267],
- [655, 267],
- [691, 267],
- [728, 267],
- [765, 267],
- [801, 267],
- [838, 267],
- [874, 267],
- [911, 267],
- [948, 267],
- ],
- [
- [581, 378],
- [618, 378],
- [655, 378],
- [691, 378],
- [728, 378],
- [765, 378],
- [801, 378],
- [838, 378],
- [874, 378],
- [911, 378],
- [948, 378],
- ],
- [
- [581, 489],
- [618, 489],
- [655, 489],
- [691, 489],
- [728, 489],
- [765, 489],
- [801, 489],
- [838, 489],
- [874, 489],
- [911, 489],
- [948, 489],
- ],
-];
+ header: document.querySelector("header"),
+ hand_panel: document.getElementById("hand_panel"),
+
+ map_container: document.getElementById("pieces"),
+
+ fascist_cards: document.getElementById("fascist_cards"),
+ trash: document.getElementById("trash"),
+ hand: document.getElementById("hand"),
+
+ player_areas: document.getElementById("player_areas"),
+ panels: {
+ a: document.getElementById("player_area_a"),
+ c: document.getElementById("player_area_c"),
+ m: document.getElementById("player_area_m"),
+ },
+ tableaus: {
+ a: document.getElementById("tableau_a"),
+ c: document.getElementById("tableau_c"),
+ m: document.getElementById("tableau_m"),
+ },
+ tokens: {
+ a: document.getElementById("tokens_a"),
+ c: document.getElementById("tokens_c"),
+ m: document.getElementById("tokens_m"),
+ },
+
+ // spaces
+ tracks_x: [],
+ tracks: [],
+ fronts: [],
+ con_fronts: [],
+ str_fronts: [],
+
+ // tokens
+ standees: [],
+ bonuses: [],
+ medallions: [],
+ blank_markers: [],
+
+ // cards
+ cards: [],
+}
+
+/* :r! node tools/parse-layout.js */
+const boxes = {
+ "Northern": [149,146,149,149],
+ "Aragon": [563,275,149,149],
+ "Southern": [341,641,149,149],
+ "Madrid": [195,398,161,161],
+ "Liberty": [955,65,662,59],
+ "Collectivization": [954,231,663,60],
+ "SovietSupport": [954,564,663,59],
+ "ForeignAid": [954,730,663,59],
+ "Government": [1015,398,602,58],
+ "Medallion1": [608,834,69,70],
+ "Medallion2": [690,834,70,70],
+ "Medallion3": [772,834,70,70],
+ "Medallion4": [855,834,70,70],
+ "Medallion5": [937,834,70,70],
+ "CurrentYearDeck": [38,976,187,261],
+ "CurrentEvent1": [301,976,187,261],
+ "CurrentEvent2": [526,976,187,261],
+ "CurrentEvent3": [751,976,187,261],
+ "CurrentEvent4": [976,976,187,261],
+ "Glory1": [1320,966,59,59],
+ "Glory2": [1418,966,119,59],
+ "Glory3": [1399,1075,58,58],
+ "Glory4": [1278,1153,300,59],
+ "Bonus1": [728,726,74,73],
+ "Bonus2": [818,726,74,73],
+}
+
+function toggle_pieces() { // eslint-disable-line no-unused-vars
+ ui.map_container.classList.toggle("hide")
+}
+
+let animation_register = []
+
+function register_animation(e) {
+ animation_register.push(e)
+}
+
+function remember_position(e) {
+ if (e.parentElement) {
+ let prect = e.parentElement.getBoundingClientRect()
+ let rect = e.getBoundingClientRect()
+ e.my_visible = 1
+ e.my_parent = e.parentElement
+ e.my_px = prect.x
+ e.my_py = prect.y
+ e.my_x = rect.x
+ e.my_y = rect.y
+ } else {
+ e.my_visible = 0
+ e.my_parent = null
+ e.my_x = 0
+ e.my_y = 0
+ e.my_z = 0
+ }
+}
+
+function animate_position(e) {
+ if (e.parentElement && e.my_visible) {
+ let prect = e.parentElement.getBoundingClientRect()
+ let rect = e.getBoundingClientRect()
+ let dx, dy
+ if (e.parentElement === e.my_parent) {
+ // animate element within animated element...
+ dx = (e.my_x - e.my_px) - (rect.x - prect.x)
+ dy = (e.my_y - e.my_py) - (rect.y - prect.y)
+ } else {
+ dx = e.my_x - rect.x
+ dy = e.my_y - rect.y
+ }
+
+ // fade in
+ if (!e.my_parent) {
+ e.animate(
+ [
+ { opacity: 0 },
+ { opacity: 1 }
+ ],
+ { duration: 500, easing: "ease" }
+ )
+ }
+
+ if (dx !== 0 || dy !== 0) {
+ let dist = Math.sqrt((dx * dx) + (dy * dy))
+ let time = Math.max(500, Math.min(1000, dist / 2))
+ e.animate(
+ [
+ { transform: `translate(${dx}px, ${dy}px)`, },
+ { transform: "translate(0, 0)", },
+ ],
+ { duration: time, easing: "ease" }
+ )
+ }
+ }
+}
+
+
+let action_register = []
+
function register_action(e, action, id) {
- e.my_action = action;
- e.my_id = id;
- e.onmousedown = on_click_action;
- action_register.push(e);
+ e.my_action = action
+ e.my_id = id
+ e.onmousedown = on_click_action
+ action_register.push(e)
}
+
function on_click_action(evt) {
- if (evt.button === 0)
- if (send_action(evt.target.my_action, evt.target.my_id))
- evt.stopPropagation();
-}
-function on_click_tab(evt) {
- evt.stopPropagation();
- const { id } = evt.target;
- Object.entries(ui.player_area_tabs).forEach(([tab, elt]) => {
- const cards_area = ui.player_area_cards[tab.split('_')[0]];
- if (tab === id) {
- elt.setAttribute('data-active', 'active');
- cards_area.setAttribute('data-active', 'active');
- }
- else {
- elt.setAttribute('data-active', 'inactive');
- cards_area.setAttribute('data-active', 'inactive');
- }
- });
+ if (evt.button === 0)
+ if (send_action(evt.target.my_action, evt.target.my_id))
+ evt.stopPropagation()
}
+
function is_action(action, arg) {
- if (arg === undefined)
- return !!(view.actions && view.actions[action] === 1);
- return !!(view.actions &&
- view.actions[action] &&
- view.actions[action].includes(arg));
+ if (arg === undefined)
+ return !!(view.actions && view.actions[action] === 1)
+ return !!(view.actions && view.actions[action] && view.actions[action].includes(arg))
+}
+
+let on_init_once = false
+
+function build_track(t, action_name, track_name, a, b) {
+ let [x, y, w, h] = boxes[track_name]
+ let e
+
+ ui.tracks[t] = []
+ ui.tracks_x[t] = []
+ for (let s = a; s <= b; ++s) {
+ const bm = t * 11 + s
+
+ e = (ui.blank_markers[bm] = document.createElement("div"))
+ e.className = "red token blank hide"
+ e.style.top = Math.round(y+4) + "px"
+ e.style.left = Math.round(x+3) + "px"
+ register_action(e, "blank_marker", bm)
+ ui.map_container.appendChild(e)
+
+ ui.tracks_x[t][s] = Math.round(x) + 4 + "px"
+ e = ui.tracks[t][s] = document.createElement("div")
+ e.className = "track"
+ e.style.top = y + "px"
+ e.style.left = Math.round(x) + "px"
+ register_action(e, action_name, s)
+ ui.map_container.appendChild(e)
+
+ x += 60.5
+ }
+
+ e = (ui.standees[t] = document.createElement("div"))
+ e.className = "white token standee standee_" + t
+ e.style.top = y - 10 + "px"
+ e.style.left = boxes[track_name][0] + 4 + "px"
+ register_action(e, "standee", t)
+ register_animation(e)
+ ui.map_container.appendChild(ui.standees[t])
}
-let on_init_once = false;
+
+function build_bonus(b, box_name, cname) {
+ var [x, y, w, h] = boxes[box_name]
+ var e = ui.bonuses[b] = document.createElement("div")
+ e.className = "red token round " + cname
+ e.style.top = Math.round(y + w/2 - 32) + "px"
+ e.style.left = Math.round(x + w/2 - 32) + "px"
+ register_action(e, "bonus", b)
+ ui.map_container.appendChild(e)
+}
+
+function build_front(i, action_id, box_name) {
+ var [x, y, w, h] = boxes[box_name]
+ var e
+
+ e = ui.con_fronts[i] = document.createElement("div")
+ e.className = "front_container"
+ e.style.top = y + 5 + "px"
+ e.style.left = x + "px"
+ e.style.width = w - 25 + "px"
+ e.style.height = 55 + "px"
+ ui.map_container.appendChild(e)
+
+ e = ui.str_fronts[i] = document.createElement("div")
+ e.className = "front_container"
+ e.style.top = y + h - 55 - 5+ "px"
+ e.style.left = x + "px"
+ e.style.width = w - 25 + "px"
+ e.style.height = 55 + "px"
+ ui.map_container.appendChild(e)
+
+ e = ui.fronts[i] = document.createElement("div")
+ e.className = "front"
+ e.style.top = Math.round(y-3) + "px"
+ e.style.left = Math.round(x-3) + "px"
+ e.style.width = Math.round(w - 6) + "px"
+ e.style.height = Math.round(h - 6) + "px"
+ register_action(e, "front", action_id)
+ ui.map_container.appendChild(e)
+}
+
function on_init() {
- if (on_init_once)
- return;
- on_init_once = true;
- Object.values(ui.player_area_tabs).forEach((element) => {
- element.addEventListener('click', on_click_tab);
- });
- for (const player of view.player_order) {
- ui.player_areas.container.insertAdjacentElement('beforeend', ui.player_areas[player]);
- ui.roles.container.insertAdjacentElement('beforeend', ui.roles[player]);
- }
- ui.roles.container.insertAdjacentElement('beforeend', ui.turn_info);
- if (view.current === 'Observer') {
- ui.player_area.style.display = 'none';
- }
- else {
- document
- .getElementById('player_area_header')
- .setAttribute('data-faction-id', view.current_player_faction);
- }
- for (let t = 0; t < TRACK_COUNT; ++t) {
- for (let s = 0; s < TRACK_LENGTH; ++s) {
- const bm = t * 11 + s;
- let e = (ui.blank_markers[bm] = document.createElement('div'));
- e.className = 'blank_marker';
- register_action(e, 'blank_marker', bm);
- }
- }
- for (let b = 0; b < BONUSES_COUNT; ++b) {
- let e = (ui.bonuses[b] = document.createElement('div'));
- e.className = 'bonus';
- e.setAttribute('data-bonus-id', '' + b);
- e.style.left = LAYOUT_BONUSES[b][0] + 'px';
- e.style.top = LAYOUT_BONUSES[b][1] + 'px';
- LAYOUT_BONUSES;
- register_action(e, 'bonus', b);
- ui.map.appendChild(ui.bonuses[b]);
- }
- for (let g = 0; g < GLORY_COUNT; ++g) {
- let e = (ui.glory[g] = document.createElement('div'));
- e.className = 'faction_token';
- ui.glory_container.appendChild(ui.glory[g]);
- e.style.left = LAYOUT_GLORY[g][0] + 'px';
- e.style.top = LAYOUT_GLORY[g][1] + 'px';
- }
- for (let m = 0; m < medallionS_COUNT; ++m) {
- let e = (ui.medallions[m] = document.createElement('div'));
- e.className = 'medallion';
- e.setAttribute('data-medallion-id', '' + m);
- register_action(e, 'medallion', m);
- }
- for (let s = 0; s < STANDEES_COUNT; ++s) {
- let e = (ui.standees[s] = document.createElement('div'));
- e.className = 'standee';
- e.setAttribute('data-standee-id', '' + s);
- register_action(e, 'standee', s);
- ui.tracks.appendChild(ui.standees[s]);
- }
- for (let c = 1; c < CARD_COUNT; ++c) {
- let e = (ui.cards[c] = document.createElement('div'));
- e.className = 'card';
- e.setAttribute('data-card-id', '' + data.cards[c].id);
- register_action(e, 'card', c);
- }
- let e = (ui.initiative_token = document.createElement('div'));
- e.className = 'initiative_token';
- data.fronts.forEach((front) => {
- ui.tokens_on_front[front.id] = {};
- FACTIONS.forEach((faction_id) => {
- let e = (ui.tokens_on_front[front.id][faction_id] =
- document.createElement('div'));
- e.className = 'faction_token';
- e.setAttribute('data-faction-id', faction_id);
- });
- });
- Object.keys(ui.fronts).forEach((front_id) => {
- register_action(ui.fronts[front_id].front, 'front', front_id);
- });
+ var i, e
+
+ if (on_init_once)
+ return
+ on_init_once = true
+
+ ui.roles_list = document.getElementById("roles"),
+ ui.roles = {
+ a: document.getElementById("role_Anarchist"),
+ c: document.getElementById("role_Communist"),
+ m: document.getElementById("role_Moderate"),
+ }
+
+ build_track(0, "tr_liberty", "Liberty", 0, 10)
+ build_track(1, "tr_collectivization", "Collectivization", 0, 10)
+ build_track(2, "tr_government", "Government", 1, 10)
+ build_track(3, "tr_soviet_support", "SovietSupport", 0, 10)
+ build_track(4, "tr_foreign_aid", "ForeignAid", 0, 10)
+
+ build_bonus(0, "Bonus1", "bonus_morale")
+ build_bonus(1, "Bonus2", "bonus_teamwork")
+
+ build_front(0, "a", "Aragon")
+ build_front(1, "m", "Madrid")
+ build_front(2, "n", "Northern")
+ build_front(3, "s", "Southern")
+
+ ui.medallion_container = []
+ for (i = 0; i < 5; ++i) {
+ e = ui.medallion_container[i] = document.createElement("div")
+ e.className = "medallion_container"
+ e.style.top = boxes["Medallion"+(i+1)][1] + "px"
+ e.style.left = boxes["Medallion"+(i+1)][0] + "px"
+ ui.map_container.appendChild(e)
+ }
+
+ ui.raw_glory_container = []
+ for (i = 0; i < 4; ++i) {
+ e = ui.raw_glory_container[i] = document.createElement("div")
+ e.className = "glory_container"
+ e.style.left = boxes["Glory" + (i+1)][0] + "px"
+ e.style.top = boxes["Glory" + (i+1)][1] + "px"
+ ui.map_container.appendChild(e)
+ }
+ ui.glory_container = [
+ ui.raw_glory_container[0],
+ ui.raw_glory_container[1],
+ ui.raw_glory_container[1],
+ ui.raw_glory_container[2],
+ ui.raw_glory_container[3],
+ ui.raw_glory_container[3],
+ ui.raw_glory_container[3],
+ ui.raw_glory_container[3],
+ ui.raw_glory_container[3],
+ ]
+
+ e = ui.fascist_deck = document.createElement("div")
+ e.className = "fascist_deck"
+ e.style.top = boxes["CurrentYearDeck"][1] - 10 + "px"
+ e.style.left = boxes["CurrentYearDeck"][0] - 10 + "px"
+ ui.map_container.appendChild(e)
+
+ ui.current_events = []
+ for (i = 0; i < 4; ++i) {
+ e = (ui.current_events[i] = document.createElement("div"))
+ e.className = "current_events"
+ e.style.left = boxes["CurrentEvent" + (i+1)][0] - 10 + "px"
+ e.style.top = boxes["CurrentEvent" + (i+1)][1] - 10 + "px"
+ ui.map_container.appendChild(e)
+ }
+
+ for (i = 0; i < 9; ++i) {
+ e = (ui.medallions[i] = document.createElement("div"))
+ e.className = "pink token medallion medallion_" + i
+ register_action(e, "medallion", i)
+ register_animation(e)
+ }
+
+ for (i = 1; i <= 120; ++i) {
+ e = (ui.cards[i] = document.createElement("div"))
+ e.className = "card card_" + i
+ register_action(e, "card", i)
+ register_animation(e)
+ }
+
+ e = ui.initiative = document.createElement("div")
+ e.className = "red token round initiative"
+ register_animation(e)
}
+
function place_cards(e, cards) {
- e.replaceChildren();
- for (let c of cards) {
- ui.cards[c].classList.remove('selected');
- e.appendChild(ui.cards[c]);
- if (view.selected_cards.includes(c)) {
- ui.cards[c].classList.add('selected');
- }
- }
+ if (cards) {
+ for (var c of cards) {
+ e.appendChild(ui.cards[c])
+ ui.cards[c].classList.toggle("selected", view.selected_cards.includes(c))
+ }
+ }
+}
+
+const faction_class = {
+ "Anarchist": "anarchist",
+ "Communist": "communist",
+ "Moderate": "moderate",
+ "a": "anarchist",
+ "c": "communist",
+ "m": "moderate",
+}
+
+function update_front(str_container, con_container, front) {
+ var i, n, e, cn
+
+ str_container.replaceChildren()
+ if (front.value < 0) {
+ n = -front.value
+ cn = "brown token front_minus"
+ } else {
+ n = front.value
+ cn = "pink token front_plus"
+ }
+ for (i = 0; i < n; ++i) {
+ e = document.createElement("div")
+ e.className = cn
+ str_container.appendChild(e)
+ }
+
+ con_container.replaceChildren()
+ for (i of ["a", "c", "m"]) {
+ if (front.contributions.includes(i)) {
+ e = document.createElement("div")
+ e.className = "red token player " + faction_class[i]
+ con_container.appendChild(e)
+ }
+ }
+}
+
+function update_medallions(container, list) {
+ for (var i of list)
+ container.appendChild(ui.medallions[i])
+}
+
+function update_hero_points(container, n) {
+ for (var i = 0; i < n; ++i) {
+ var e = document.createElement("div")
+ e.className = "token pink hero_point"
+ container.appendChild(e)
+ }
+}
+
+function update_stat_line(x) {
+ var i, line
+ line = ""
+ for (i = 0; i < view.hero_points[x]; ++i)
+ line += "\u272b"
+ if (view.initiative === x)
+ line += " \u2bc5"
+ return line
}
-function on_update() {
- console.log('on_update', view);
- on_init();
- for (let key of Object.keys(view.hero_points)) {
- ui.roles[key].hero_points.replaceChildren(`Hero Points: ${view.hero_points[key]}`);
- }
- ui.bag_of_glory.replaceChildren(`Bag of Glory: ${view.bag_of_glory_count}`);
- ui.current_events.replaceChildren();
- for (let i = 0; i < view.current_events.length; i++) {
- const cardId = view.current_events[i];
- ui.current_events.appendChild(ui.cards[cardId]);
- ui.cards[cardId].classList.add('event');
- ui.cards[cardId].style.left = LAYOUT_CURRENT_EVENTS[i][0] + 'px';
- ui.cards[cardId].style.top = LAYOUT_CURRENT_EVENTS[i][1] + 'px';
- }
- ui.markers.replaceChildren();
- for (let bm of view.triggered_track_effects) {
- const s = bm % 11;
- const t = Math.floor(bm / 11);
- ui.markers.appendChild(ui.blank_markers[bm]);
- ui.blank_markers[bm].style.left = LAYOUT_TRACKS[t][s][0] + 'px';
- ui.blank_markers[bm].style.top = LAYOUT_TRACKS[t][s][1] + 'px';
- }
- for (let bonus_id of Object.keys(view.bonuses)) {
- ui.bonuses[bonus_id].setAttribute('data-bonus-on', view.bonuses[bonus_id] + 0);
- }
- place_cards(ui.hand, view.hand);
- ui.player_area_tabs.hand_tab.replaceChildren(`Hand (${view.hand.length})`);
- place_cards(ui.player_area_cards.deck, view.deck);
- ui.player_area_tabs.deck_tab.replaceChildren(`Deck (${view.deck.length})`);
- place_cards(ui.player_area_cards.discard, view.discard);
- ui.player_area_tabs.discard_tab.replaceChildren(`Discard (${view.discard.length})`);
- place_cards(ui.player_area_cards.trash, view.trash);
- ui.player_area_tabs.trash_tab.replaceChildren(`Trash (${view.trash.length})`);
- place_cards(ui.selectable_cards, view.selectable_cards);
- for (let faction_id of FACTIONS) {
- place_cards(ui.tableaus[faction_id], view.tableaus[faction_id]);
- }
- for (let i = 0; i < view.tracks.length; ++i) {
- ui.standees[i].style.left = LAYOUT_TRACKS[i][view.tracks[i]][0] + 'px';
- ui.standees[i].style.top = LAYOUT_TRACKS[i][view.tracks[i]][1] + 'px';
- }
- for (let front_id of Object.keys(view.fronts)) {
- const front_data = view.fronts[front_id];
- ui.fronts[front_id].value.replaceChildren(front_data.status !== null ? front_data.status : front_data.value);
- ui.fronts[front_id].contributions.replaceChildren();
- for (let faction_id of front_data.contributions) {
- ui.fronts[front_id].contributions.appendChild(ui.tokens_on_front[front_id][faction_id]);
- }
- }
- ui.medallions_container.replaceChildren();
- for (let i = 0; i < view.medallions.pool.length; ++i) {
- if (view.medallions.pool[i] !== null) {
- const id = view.medallions.pool[i];
- ui.medallions[id].style.left = LAYOUT_medallionS[i][0] + 'px';
- ui.medallions[id].style.top = LAYOUT_medallionS[i][1] + 'px';
- ui.medallions_container.appendChild(ui.medallions[id]);
- }
- }
- for (let f of FACTIONS) {
- ui.roles[f].medallions.replaceChildren();
- for (let m of view.medallions[f]) {
- ui.roles[f].medallions.appendChild(ui.medallions[m]);
- }
- }
- ui.roles[view.initiative].medallions.appendChild(ui.initiative_token);
- ui.initiative_token.setAttribute('data-year', view.year);
- if (view.played_card === null) {
- ui.turn_info.style.display = 'none';
- }
- else {
- ui.turn_info.style.display = '';
- ui.turn_info_card.setAttribute('data-card-id', view.played_card + '');
- }
- Object.values(ui.glory).forEach((elt) => elt.removeAttribute('data-faction-id'));
- for (let g = 0; g < view.glory.length; ++g) {
- ui.glory[g].setAttribute('data-faction-id', view.glory[g]);
- }
- for (let e of action_register)
- e.classList.toggle('action', is_action(e.my_action, e.my_id));
- ui.year.replaceChildren(`Year ${view.year}`);
- action_button('add_to_front', '+1 to a Front');
- action_button('d_liberty', 'Decrease Liberty');
- action_button('soviet_support', 'Soviet Support');
- action_button('collectivization', 'Collectivization');
- action_button('d_collectivization', 'Decrease Collectivization');
- action_button('d_foreign_aid', 'Decrease Foreign Aid');
- action_button('d_government', 'Decrease Government');
- action_button('d_soviet_support', 'Decrease Soviet Support');
- action_button('foreign_aid', 'Foreign Aid');
- action_button('government', 'Government');
- action_button('liberty', 'Liberty');
- action_button('government_to_center', 'Government towards center');
- action_button('teamwork_on', 'Teamwork Bonus On');
- action_button('Anarchist', 'Anarchist');
- action_button('Communist', 'Communist');
- action_button('Moderate', 'Moderate');
- action_button('gain_hp', 'Gain Hero Points');
- action_button('lose_hp', 'Lose Hero Points');
- action_button('draw_card', 'Draw a card');
- action_button('draw_cards', 'Draw cards');
- action_button('play_to_tableau', 'Play card to Tableau');
- action_button('play_for_event', 'Play card for Event');
- action_button('use_ap', 'Use Action Points');
- action_button('use_morale_bonus', 'Use Morale Bonus');
- action_button('move_track', 'Move a Track');
- action_button('turn_on_bonus', 'Turn on a Bonus');
- action_button('add_glory', 'Add to Bag of Glory');
- action_button('draw_glory', 'Draw from Bag of Glory');
- action_button('up', 'Up');
- action_button('down', 'Down');
- action_button('next', 'Next');
- action_button('remove_blank_marker', 'Remove Blank marker');
- action_button('confirm', 'Confirm');
- action_button('yes', 'Yes');
- action_button('no', 'No');
- action_button('skip', 'Skip');
- action_button('spend_hp', 'Spend Hero Points');
- action_button('use_momentum', 'Play second card (Momentum)');
- action_button('done', 'Done');
- action_button('end_turn', 'End turn');
- action_button('undo', 'Undo');
+
+function on_update() { // eslint-disable-line no-unused-vars
+ var i, x, e
+
+ on_init()
+
+ animation_register.forEach(remember_position)
+
+ ui.player_areas.replaceChildren()
+ ui.roles_list.replaceChildren()
+ for (i = 0; i < 3; ++i) {
+ ui.player_areas.appendChild(ui.panels[view.player_order[i]])
+ ui.roles_list.appendChild(ui.roles[view.player_order[i]])
+ }
+
+ ui.header.classList.toggle("fascist", !!view.fascist)
+
+ ui.initiative.classList.toggle("ccw", (view.year & 1) === 0)
+ roles.Anarchist.stat.textContent = update_stat_line("a")
+ roles.Communist.stat.textContent = update_stat_line("c")
+ roles.Moderate.stat.textContent = update_stat_line("m")
+
+ // TODO: played card (side panel?)
+
+ // TODO: player draw/discard/trash
+ // TODO: bag of glory
+
+ ui.fascist_deck.replaceChildren()
+ if (view.year === 1)
+ place_cards(ui.fascist_deck, [ 120, 119, 118 ])
+ else if (view.year === 2)
+ place_cards(ui.fascist_deck, [ 120, 119 ])
+ else
+ place_cards(ui.fascist_deck, [ 120])
+
+ ui.fascist_cards.replaceChildren()
+ place_cards(ui.fascist_cards, view.fascist_cards)
+
+ ui.trash.replaceChildren()
+ place_cards(ui.trash, view.trash)
+
+ ui.hand_panel.classList = "panel " + faction_class[player]
+ ui.hand.replaceChildren()
+ place_cards(ui.hand, view.hand)
+
+ ui.tableaus.a.replaceChildren()
+ ui.tableaus.c.replaceChildren()
+ ui.tableaus.m.replaceChildren()
+ ui.tableaus.a.appendChild(ui.cards[117])
+ ui.tableaus.c.appendChild(ui.cards[116])
+ ui.tableaus.m.appendChild(ui.cards[115])
+ place_cards(ui.tableaus.a, view.tableaus.a)
+ place_cards(ui.tableaus.c, view.tableaus.c)
+ place_cards(ui.tableaus.m, view.tableaus.m)
+
+ for (i = 0; i <= 1; ++i) {
+ ui.bonuses[i].classList.toggle("red", !!view.bonuses[i])
+ ui.bonuses[i].classList.toggle("gray", !view.bonuses[i])
+ ui.bonuses[i].classList.toggle("off", !view.bonuses[i])
+ }
+
+ for (i = 0; i < 4; ++i) {
+ ui.current_events[i].replaceChildren()
+ if (i < view.current_events.length)
+ ui.current_events[i].appendChild(ui.cards[view.current_events[i]])
+ }
+
+ for (i = 0; i < 5; ++i)
+ ui.standees[i].style.left = ui.tracks_x[i][view.tracks[i]]
+
+ for (i = 0; i < 55; ++i) {
+ if (ui.blank_markers[i])
+ ui.blank_markers[i].classList.toggle("hide",
+ !view.triggered_track_effects.includes(i))
+ }
+
+ for (i = 0; i < 5; ++i) {
+ ui.medallion_container[i].replaceChildren()
+ if (i < view.medallions.pool.length) {
+ x = view.medallions.pool[i]
+ if (x !== null)
+ ui.medallion_container[i].appendChild(ui.medallions[x])
+ }
+ }
+
+ ui.tokens.a.replaceChildren()
+ ui.tokens.c.replaceChildren()
+ ui.tokens.m.replaceChildren()
+ ui.tokens[view.initiative].appendChild(ui.initiative)
+ update_medallions(ui.tokens.a, view.medallions.a)
+ update_medallions(ui.tokens.c, view.medallions.c)
+ update_medallions(ui.tokens.m, view.medallions.m)
+ update_hero_points(ui.tokens.a, view.hero_points.a)
+ update_hero_points(ui.tokens.c, view.hero_points.c)
+ update_hero_points(ui.tokens.m, view.hero_points.m)
+
+ update_front(ui.str_fronts[0], ui.con_fronts[0], view.fronts.a)
+ update_front(ui.str_fronts[1], ui.con_fronts[1], view.fronts.m)
+ update_front(ui.str_fronts[2], ui.con_fronts[2], view.fronts.n)
+ update_front(ui.str_fronts[3], ui.con_fronts[3], view.fronts.s)
+
+ for (e of ui.raw_glory_container)
+ e.replaceChildren()
+ for (i = 0; i < view.glory.length; ++i) {
+ x = view.glory[i]
+ e = document.createElement("div")
+ e.className = "red token player " + faction_class[x]
+ ui.glory_container[i].appendChild(e)
+ }
+
+ action_button("add_to_front", "+1 to a Front")
+ action_button("d_liberty", "Decrease Liberty")
+ action_button("soviet_support", "Soviet Support")
+ action_button("collectivization", "Collectivization")
+ action_button("d_collectivization", "Decrease Collectivization")
+ action_button("d_foreign_aid", "Decrease Foreign Aid")
+ action_button("d_government", "Decrease Government")
+ action_button("d_soviet_support", "Decrease Soviet Support")
+ action_button("foreign_aid", "Foreign Aid")
+ action_button("government", "Government")
+ action_button("liberty", "Liberty")
+ action_button("government_to_center", "Government towards center")
+ action_button("teamwork_on", "Teamwork Bonus On")
+ action_button("Anarchist", "Anarchist")
+ action_button("Communist", "Communist")
+ action_button("Moderate", "Moderate")
+ action_button("gain_hp", "Gain Hero Points")
+ action_button("lose_hp", "Lose Hero Points")
+ action_button("draw_card", "Draw a card")
+ action_button("draw_cards", "Draw cards")
+ action_button("play_to_tableau", "Play card to Tableau")
+ action_button("play_for_event", "Play card for Event")
+ action_button("use_ap", "Use Action Points")
+ action_button("use_morale_bonus", "Use Morale Bonus")
+ action_button("move_track", "Move a Track")
+ action_button("turn_on_bonus", "Turn on a Bonus")
+ action_button("add_glory", "Add to Bag of Glory")
+ action_button("draw_glory", "Draw from Bag of Glory")
+ action_button("up", "Up")
+ action_button("down", "Down")
+ action_button("next", "Next")
+ action_button("remove_blank_marker", "Remove Blank marker")
+ action_button("confirm", "Confirm")
+ action_button("yes", "Yes")
+ action_button("no", "No")
+ action_button("skip", "Skip")
+ action_button("spend_hp", "Spend Hero Points")
+ action_button("use_momentum", "Play second card (Momentum)")
+ action_button("done", "Done")
+ action_button("end_turn", "End turn")
+ action_button("undo", "Undo")
+
+ for (e of action_register)
+ e.classList.toggle("action", is_action(e.my_action, e.my_id))
+
+ animation_register.forEach(animate_position)
}
-const IMG_FTA = '<span class="faction_token" data-faction-id="a"></span>';
-const IMG_FTC = '<span class="faction_token" data-faction-id="c"></span>';
-const IMG_FTM = '<span class="faction_token" data-faction-id="m"></span>';
-function on_log(text) {
- let p = document.createElement('div');
- if (text.match(/^>>/)) {
- text = text.substring(2);
- p.className = 'ii';
- }
- if (text.match(/^>/)) {
- text = text.substring(1);
- p.className = 'i';
- }
- if (text.match(/^\.h1/)) {
- text = text.substring(4);
- p.className = 'h1';
- }
- else if (text.match(/^\.h2\.Moderate/)) {
- text = text.substring(13);
- p.className = 'h2 moderate';
- }
- else if (text.match(/^\.h2\.Anarchist/)) {
- text = text.substring(14);
- p.className = 'h2 anarchist';
- }
- else if (text.match(/^\.h2\.Communist/)) {
- text = text.substring(14);
- p.className = 'h2 communist';
- }
- else if (text.match(/^\.h2\.fascist/)) {
- text = text.substring(11);
- p.className = 'h2 fascist';
- }
- else if (text.match(/^\.h2\.glory/)) {
- text = text.substring(9);
- p.className = 'h2 glory';
- }
- else if (text.match(/^\.h2/)) {
- text = text.substring(4);
- p.className = 'h2';
- }
- else if (text.match(/^\.h3/)) {
- text = text.substring(4);
- p.className = 'h3';
- }
- text = text.replace(/<fta>/g, IMG_FTA);
- text = text.replace(/<ftc>/g, IMG_FTC);
- text = text.replace(/<ftm>/g, IMG_FTM);
- p.innerHTML = text;
- return p;
+
+function on_log(text) { // eslint-disable-line no-unused-vars
+ let p = document.createElement("div")
+
+ if (text.match(/^>>/)) {
+ text = text.substring(2)
+ p.className = "ii"
+ }
+ if (text.match(/^>/)) {
+ text = text.substring(1)
+ p.className = "i"
+ }
+
+ text = text.replace(/&/g, "&amp;")
+ text = text.replace(/</g, "&lt;")
+ text = text.replace(/>/g, "&gt;")
+ text = text.replace(/-( ?[\d(])/g, "\u2212$1")
+
+ // text = text.replace(/C(\d+)/g, sub_card)
+
+ if (text.startsWith("#")) {
+ p.className = "h " + text[1]
+ text = text.substring(3)
+ }
+
+ p.innerHTML = text
+ return p
}