"use strict" const ui = { map: document.getElementById('map'), glory_container: document.getElementById('glory'), hand: document.getElementById('hand'), player_areas: { Anarchist: document.getElementById('player_area_Anarchist'), Communist: document.getElementById('player_area_Communist'), Moderate: document.getElementById('player_area_Moderate'), }, tableaus: { a: document.getElementById('tableau_a'), c: document.getElementById('tableau_c'), m: document.getElementById('tableau_m'), }, standees: [], fronts: [], cards: [], }; 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) } function on_click_action(evt) { 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)) } let on_init_once = false; function on_init() { if (on_init_once) return; on_init_once = true; 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); }); } 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") } } } 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'); }