summaryrefslogtreecommitdiff
path: root/rules.js
diff options
context:
space:
mode:
authoriainp5 <iain.pearce.ip@gmail.com>2024-11-23 08:51:45 +0000
committeriainp5 <iain.pearce.ip@gmail.com>2024-11-23 08:51:45 +0000
commita35b49e654f2ad82c14855b3c36195c2c2e26d10 (patch)
tree0f56a45c62741907a2ac9dbbe315e025af2dcd7c /rules.js
parentdd4ef001caac00050d00f8ae1dfa87da9e95eb7c (diff)
parentdb464d9b4adb87cd4316f59058b6b70f61fbeaa3 (diff)
download1989-dawn-of-freedom-a35b49e654f2ad82c14855b3c36195c2c2e26d10.tar.gz
Merge branch 'work-in-progress'
Diffstat (limited to 'rules.js')
-rw-r--r--rules.js18574
1 files changed, 8917 insertions, 9657 deletions
diff --git a/rules.js b/rules.js
index 6a8501a..df304db 100644
--- a/rules.js
+++ b/rules.js
@@ -1,9657 +1,8917 @@
-//"use strict"
-
-const { spaces, cards, power_cards } = require("./data.js")
-
-var game, view, states = {}
-
-const DEM = "Democrat"
-const COM = "Communist"
-
-const first_strategy_card = 1
-const last_strategy_card = 110
-
-const dem_tst_req = [5, 5, 6, 6, 7, 8, 9, 10]
-const com_tst_req = [6, 6, 7, 7, 8, 7, 6, 5]
-const scoring_cards = [22, 23, 42, 43, 55, 95]
-const leader_cards = [37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48]
-const leaders = [1, 4, 5, 6, 7]
-const support_loss_roll = [0, 0, 1, 1, 2, 2, 3, 4]
-const vp_roll = [0, 0, 1, 1, 2, 2, 3, 4]
-const countries = ['Poland', 'Hungary', 'East_Germany', 'Bulgaria', 'Czechoslovakia', 'Romania']
-const elite_spaces = [12, 15, 27, 43, 51, 69]
-const all_power_cards = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52 ]
-const numberless_cards = [25, 26, 27, 28, 29, 30, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52]
-const auto_resolve_events = [5, 8, 9, 13, 17, 25, 26, 30, 35, 50, 53, 54, 58, 59, 62, 63, 65, 70, 72, 74, 99, 102, 108]
-const switch_events = [6, 20, 71]
-
-exports.scenarios = [ "Standard" ]
-
-exports.roles = [ DEM, COM ]
-
-// --- SET UP ---
-
-exports.setup = function (seed, scenario, options) {
- game = {
- seed: seed,
- log: [],
- undo: [],
- summary: [],
- active: null,
- state: "com_init",
- return: '',
- vm: null,
- vm_event: 0,
- vm_event_to_do: false,
- vm_infl_to_do: false,
-
- played_card: 0,
- table_cards: [],
- available_ops: 0,
- vm_available_ops: 0,
- valid_spaces: [],
- valid_cards: [],
-
- vp: 0,
- turn: 0,
- round: 0,
- round_player: COM,
- stability: 0,
- dem_tst_position: 0,
- com_tst_position: 0,
- dem_tst_attempted: 0,
- com_tst_attempted: 0,
- dem_tst_attempted_this_turn: 0,
- com_tst_attempted_this_turn: 0,
-
- demInfl: [],
- comInfl: [],
-
- strategy_deck: [],
- strategy_discard: [],
- discard: false,
- view_opp_hand: false,
- strategy_removed: [],
- persistent_events: [],
- power_struggle_deck: [],
- power_struggle_discard: [],
- dem_hand_limit: 8,
- com_hand_limit: 8,
- democrat_hand: [],
- communist_hand: [],
-
- pwr_struggle_in: [],
- is_pwr_struggle: false,
- dem_pwr_hand_limit: 0,
- com_pwr_hand_limit: 0,
- dem_pwr_hand: [],
- com_pwr_hand: [],
- raised_stakes_discard: 0,
- raised_stakes: 0,
- raised_stakes_round: 0,
- phase: 0,
- times_held: [0, 0, 0, 0, 0, 0],
- revolutions: [false, false, false, false, false, false],
- remove_opponent_infl: false,
- tactics_fails: '',
- }
-
- log_h1("1989 Dawn of Freedom")
-
- game.active = COM
- start_game()
-
- return game
-}
-
-function start_game() {
- //starting influence
-
- // Draw cards
- /* const card_numbers = cards.filter(card => card !== null && card !== undefined).map(card => card.number);
- console.log('card numbers: ', card_numbers) */
- game.strategy_deck = draw_deck(cards)
- reset_power()
-
- //Set starting influence
- spaces.forEach((space, index) => {
- if (space !== null) {
- game.demInfl[index] = space.demInfl
- game.comInfl[index] = space.comInfl
- }
- })
-
- //Set starting placement ops
- game.starting_infl = {
- com_starting_infl: 0,
- dem_starting_infl: 0
- },
-
- // Set variable event cards where event is playable at start of game
-
- game.playable_cards = [14, 15, 21, 70]
-
- //console.log('game.strategy_deck: ', game.strategy_deck[1])
- draw_cards(game.strategy_deck, game.democrat_hand, game.communist_hand, game.dem_hand_limit, game.com_hand_limit)
- //.log('game.strategy_deck: ', game.strategy_deck[1], 'democrat_hand:', game.democrat_hand)
-
- game.valid_spaces = valid_spaces_setup()
- game.available_ops = 2
- game.phase = 0
- log_h1("Place starting Support Points")
- log_side()
-}
-
-
-exports.view = function(state, player) {
- game = state
-
- view = {
- log: game.log,
- active: game.active,
- prompt: null,
- actions: null,
-
- played_card: game.played_card,
- table_cards: game.table_cards,
- valid_spaces: game.valid_spaces,
- valid_cards: game.valid_cards,
-
- demInfl: game.demInfl,
- comInfl: game.comInfl,
- turn: game.turn,
- round: game.round,
- round_player: game.round_player,
- vp: game.vp,
- stability: game.stability,
- dem_tst: game.dem_tst_position,
- com_tst: game.com_tst_position,
- persistent_events: game.persistent_events,
- systematization: game.systematization,
- the_tyrant_is_gone: game.the_tyrant_is_gone,
-
- strategy_deck: game.strategy_deck.length,
- strategy_removed: game.strategy_removed,
- discard: game.discard,
- show_opp_hand: game.view_opp_hand,
-
- democrat_hand: game.democrat_hand.length,
- communist_hand: game.communist_hand.length,
- democrat_power_hand: game.dem_pwr_hand.length,
- communist_power_hand: game.com_pwr_hand.length,
- ceausescu_cards: game.ceausescu_cards,
- is_pwr_struggle: game.is_pwr_struggle,
- times_held: game.times_held,
- revolutions: game.revolutions,
-
- hand: [],
- set_aside: [],
- pwr_hand: [],
-
-
- }
-
- if (game.is_pwr_struggle) {
- view.strategy_discard = game.power_struggle_discard
- } else {
- view.strategy_discard = game.strategy_discard
- }
-
- if (player === game.active && game.vm && game.vm.draw)
- view.drawn = game.vm.draw
-
- if (player === game.active) {
- if (game.selected_space > 0 ) {
- view.valid_spaces = [game.selected_space]
- } else {
- view.valid_spaces = game.valid_spaces
- }
- } else {
- view.valid_spaces = []
- }
-
- if (player === game.active) {
- view.valid_cards = game.valid_cards
- } else {
- view.valid_cards = []
- }
-
- if (player === DEM) {
- view.hand = game.democrat_hand
- if (game.communist_hand_red) {
- view.opp_hand = game.communist_hand_red
- }
- view.set_aside = game.democrat_set_aside /*Is this being used? */
- view.power_hand = game.dem_pwr_hand.sort((a, b) => a - b)
-
- } else if (player === COM) {
- view.hand = game.communist_hand
- view.opp_hand = game.dem_pwr_hand.sort((a, b) => a - b) /*Does the Communist ever see Democrat hand? */
- view.power_hand = game.com_pwr_hand.sort((a, b) => a - b)
- }
-
- if (game.active === DEM) {
- view.samizdat = game.samizdat_card
- }
-
- if (game.state === "game_over") {
- view.prompt = game.victory
- } else if (player === "Observer" || (game.active !== player && game.active !== "Both")) {
- if (states[game.state]) {
- let inactive = states[game.state].inactive
- if (typeof inactive === "function")
- view.prompt = `Waiting for ${game.active} ${inactive()}`
- else
- view.prompt = `Waiting for ${game.active} to ${inactive}`
- } else {
- view.prompt = "A Unknown state: " + game.state
- }
- } else {
- view.actions = {}
-
- if (states[game.state])
- states[game.state].prompt(player)
- else
- view.prompt = "B Unknown state: " + game.state
- if (view.actions.undo === undefined) {
- if (game.undo && game.undo.length > 0)
- view.actions.undo = 1
- else
- view.actions.undo = 0
- }
- }
-
- return view
-}
-
-
-// === ACTIONS ===========
-
-function gen_action(action, argument) {
-//console.log('gen_action called with ', action, ' and ', argument)
- if (argument === undefined) {
- //console.log('argument undefined')
- view.actions[action] = 1
- } else {
- if (!(action in view.actions)) {
- //console.log('push argument')
- view.actions[action] = []
- }
- view.actions[action].push(argument)
- }
- //console.log('view.actions: ', view.actions, 'view.actions[action]: ', view.actions[action])
-}
-
-function gen_action_infl(space){
- gen_action("infl", space)
-}
-
-function gen_action_card(card){
- gen_action("card", card)
-}
-
-function gen_action_sc(space){
- gen_action("sc", space)
-}
-
-function gen_action_scoring(){
- gen_action("scoring")
-}
-
-exports.action = function (state, player, action, arg) {
- //console.log('exports.action called with state:' , state, 'player:', player, 'action: ', action, 'arg: ', arg)
- game = state
- if (states[game.state] && action in states[game.state]) {
- states[game.state][action](arg, player)
- } else {
- if (action === "undo" && game.undo && game.undo.length > 0)
- pop_undo()
- else
- throw new Error("Invalid action: " + action)
- }
- return game
-}
-
-// ============= GAME STATES =======================
-
-states.com_init = {
- inactive: 'place starting SPs',
- prompt() {
- if (game.available_ops == 0) {
- view.prompt = 'Place starting SPs: done.';
- gen_action("done");
- return;
- } else if (game.starting_infl.dem_starting_infl === 2) {
- view.prompt = `Place your last ${pluralize(game.available_ops,'starting SP')}.`
- } else {
- view.prompt = `Place ${pluralize(game.available_ops,'starting SP')}.`
- }
- for (let space_id of game.valid_spaces) {
- if (space_id) {
- gen_action_infl(spaces[space_id].name_unique);
- }
- }
- },
- infl(space) {
- add_infl(space)
-
- },
- done() {
- if (game.summary.length > 0) {
- pop_summary()
- log_br()
- }
-
- game.starting_infl.com_starting_infl++
- if (game.starting_infl.com_starting_infl == 1){
- game.available_ops = 3
- game.state = 'dem_init'
- valid_spaces_setup()
- next_player()
- } else if (game.starting_infl.com_starting_infl == 2) {
- game.available_ops = 4
- game.state = 'dem_init'
- valid_spaces_setup()
- next_player()
- } else if (game.starting_infl.com_starting_infl == 3) {
- delete game.starting_infl
- game.state = 'start_game'
- }
- }
-}
-
-states.dem_init = {
- inactive: 'place starting SPs.',
- prompt() {
- if (game.available_ops == 0) {
- view.prompt = 'Place starting SPs: done.';
- gen_action("done");
- return;
- } else if (game.starting_infl.com_starting_infl === 2) {
- view.prompt = `Place your last ${pluralize(game.available_ops,'starting SP')}.`
- } else {
- view.prompt = `Place ${pluralize(game.available_ops,'starting SP')}.`
- }
- for (let space_id of game.valid_spaces) {
- gen_action_infl(spaces[space_id].name_unique);
- }
- },
- infl(space) {
- add_infl(space)
- },
-
- done() {
- if (game.summary.length > 0) {
- pop_summary()
- log_br()
- }
-
- game.starting_infl.dem_starting_infl++
- if (game.starting_infl.dem_starting_infl == 1){
- game.available_ops = 3
- } else if (game.starting_infl.dem_starting_infl == 2) {
- game.available_ops = 2
- }
- game.state = 'com_init'
- valid_spaces_setup()
- next_player()
- }
-}
-
-states.start_game = {
- inactive: 'start Turn 1.',
- prompt() {
- view.prompt = 'Start Turn 1.'
- gen_action('start')
- },
- start() {
- new_turn()
- clear_undo()
- game.state = 'choose_card'
- }
-}
-
-states.choose_card = {
- inactive: 'choose a card.',
- prompt() {
- /*if (game.played_card > 0) {
- game.state = 'play_card'
- view.prompt = 'Choose a card: done.'
- gen_action("done");
- return;
- } */
- if ((game.active===DEM && game.democrat_hand.length === 0) || game.active === COM && game.communist_hand.length === 0) {
- view.prompt = 'No cards remaining: you must pass.'
- gen_action('pass')
- } else {
- view.prompt = 'Play a card.'
- let available_cards
- if (game.active === DEM) {
- available_cards = game.democrat_hand
- } else {
- available_cards = game.communist_hand
- }
- for (let card of available_cards) {
- //gen_action('card_event', card)
-
- if (scoring_cards.includes(card)) {
- /*view.prompt = 'Play for:'*/
- gen_action('card_event', card)
- }
-
-
- //Check for Tiananmen Square Track awards special abilities
-
- if ((game.active === DEM && cards[card].side !== 'C' && game.dem_tst_position >= 7 && game.com_tst_position < 7 && !game.tst_7) || (game.active === COM && cards[card].side !== 'D' && game.com_tst_position >= 7 && game.dem_tst_position < 7 && !game.tst_7)){
- gen_action('card_tst_7', card)
- }
-
- console.log('game.tst_8', game.tst_8)
- if ((game.active === DEM && cards[card].side !== 'C' && game.dem_tst_position >= 8 && game.com_tst_position < 8 && !game.tst_8) || (game.active === COM && cards[card].side !== 'D' && game.com_tst_position >= 8 && game.dem_tst_position < 8 && !game.tst_8)){
- gen_action('card_tst_8', card)
- }
-
- // Check for Reformer Rehabilitated
-
- //console.log('game.active', game.active, 'game.playable_cards[67].playable', game.playable_cards[67].playable)
-
-
- if (card === 67 && game.playable_cards.includes(67)){
- if (game.active === DEM && (game.dem_tst_position > game.com_tst_position)) {
- gen_action('card_event', card)
- }
- if (game.active === COM && (game.dem_tst_position < game.com_tst_position)) {
- gen_action('card_event', card)
- }
- }
-
- //Continue with normal logic
-
- //Check if it is a card with an event which is always playable
-
- if (cards[card].playable) {
- get_events(card)
- }
-
- // Resolve cards with variable events (not Reformer)
-
- if (card !== 67 && game.playable_cards.includes(card)) {
- get_events(card)
- }
-
- //Actions for non-scoring cards
-
- if (!scoring_cards.includes(card)) {
- gen_action('card_influence', card)
- if (game.active === DEM && game.dem_tst_attempted_this_turn === 0 && game.dem_tst_position <=8 || game.active === COM && game.com_tst_attempted_this_turn === 0 && game.com_tst_position <= 8) {
- gen_action('card_tst', card)
- }
- gen_action('card_support_check', card)
- }
- }
- }
- },
- /*card_event(card) {
- push_undo()
- //Check if player is at risk of losing game due to held scoring card
- if (!scoring_cards.includes(card)) {
- let scoring_cards_count = count_scoring_cards()
-
- if (game.round !== 8 && scoring_cards_count >= (8-game.round)){
- game.temp = card
- game.state = 'confirm_card'
- return
- }
- }
- select_card(card)
- },*/
- pass() {
- log('No cards remaining. Passed')
- end_round()
- },
- card_event(card) {
- push_undo()
- select_card(card)
- console.log('played event, game.active', game.active, 'game.view_opp_hand', game.view_opp_hand)
- log_gap(`Played C${cards[game.played_card].number} for the event`)
- if (scoring_cards.includes(game.played_card)) {game.phase = 0}
- else {game.phase = 1}
- game.return = game.active
- if (switch_events.includes(game.played_card)) {next_player()}
- game.vm_event = game.played_card
- goto_vm(game.vm_event)
- },
- card_opp_event(card) {
- push_undo()
- select_card(card)
- log_gap(`Played C${cards[game.played_card].number} for the event`)
- game.phase = 1 /*Do I still need this?*/
- game.vm_infl_to_do = true
- game.return = game.active
- game.vm_event = game.played_card
- if (auto_resolve_events.includes(game.played_card) || switch_events.includes(game.played_card)) {
- goto_vm(game.vm_event)}
- else {
- next_player()
- log(`C${game.vm_event}`)
- goto_vm(game.vm_event)
- }
- },
- card_influence(card) {
- push_undo()
- select_card(card)
- log_gap(`Played C${cards[game.played_card].number} to place SPs`)
-
-
- // Check if Common European Home played for influence
- if (game.played_card === 21) {
- if (game.active === DEM) {
- game.vp --
- log('-1 VP')
- if (check_vp()) {
- return
- }
- } else {
- game.vp ++
- log('+1 VP')
- if (check_vp()) {
- return
- }
- }
- }
- // Check if card is opponent card with event that needs to be resolved
-
- if (cards[game.played_card].playable || game.playable_cards.includes(game.played_card)) {
- if ((game.active === DEM && cards[game.played_card].side === "C" ) || (game.active === COM && cards[game.played_card].side === "D")) {
- //game.phase = 1 /*Do I need this? */
- game.vm_event_to_do = true
- }
- }
-
- // If ABHR - Set AHBR tracker to true
- if (game.persistent_events.includes(58)) {
- game.austria_hungary_border_reopened_tracker = true
- }
- game.state='add_influence'
- valid_spaces_infl()
- },
- card_tst(card) {
- push_undo()
- select_card(card)
- log_gap(`Played C${cards[game.played_card].number} to the Tiananmen Square Track`)
- game.state='tiananmen_square_attempt'
- },
- card_support_check(card) {
- push_undo()
- select_card(card)
- log_gap(`Played C${cards[game.played_card].number} for support checks`)
-
- // Check if card is opponent card with event that needs to be resolved
- /*if (game.phase === 0 && game.active === DEM && cards[game.played_card].side === "C" && game.playable_cards[game.played_card].playable === 1 || game.phase === 0 && game.active === COM && cards[game.played_card].side === "D" && game.playable_cards[game.played_card].playable === 1 ) {
- game.vm_event_to_do = true
- }*/
-
- if (cards[game.played_card].playable || game.playable_cards.includes(game.played_card)) {
- if ((game.active === DEM && cards[game.played_card].side === "C" ) || (game.active === COM && cards[game.played_card].side === "D")) {
- game.vm_event_to_do = true
- }
- }
-
- game.available_ops = 2
- game.state='support_check_prep'
- valid_spaces_sc()
- },
- card_tst_7() {
- select_card(card)
- game.vm_infl_to_do = true
- game.tst_7 = true
- game.state = 'resolve_opponent_event'
- },
- card_tst_8(card) { /*Play card for ops and event */
- select_card(card)
- game.vm_event_to_do = true
- game.vm_infl_to_do = true
- game.tst_8 = true
- game.state = 'vm_tst_8'
- },
-
- /*done () {
- game.state = 'play_card'
- } */
-}
-
-states.confirm_card = {
- inactive: 'choose a card.',
- prompt() {
- let scoring_cards_count = count_scoring_cards()
- view.prompt = `${pluralize(scoring_cards_count,'scoring card')} in hand with ${pluralize(8-game.round,'turn')} remaining. Scoring cards may not be held. Continue?`
- gen_action('continue')
- },
- continue() {
- select_card(game.temp)
- }
-}
-
-states.play_card ={
- get inactive() {
- return `play ${clean_name(cards[game.played_card].name)}.`
- },
- prompt () {
- if (game.phase >= 1) {
- view.prompt = `${clean_name(cards[game.played_card].name)}: done.`
- gen_action('done')
- return
- }
-
- view.prompt = `Play ${clean_name(cards[game.played_card].name)} for:`
-
- if (scoring_cards.includes(game.played_card)) {
- /*view.prompt = 'Play for:'*/
- gen_action('event')
- return
- }
-
-
- //Check for Tiananmen Square Track awards special abilities
- if ((game.active === DEM && cards[game.played_card].side !== 'C' && game.dem_tst_position >= 8 && game.com_tst_position < 8 && !game.tst_8) || (game.active === COM && cards[game.played_card].side !== 'D' && game.com_tst_position >= 8 && game.dem_tst_position < 8 && !game.tst_8)){
- gen_action('tst_8')
- }
-
- // Check for Reformer Rehabilitated
-
- //console.log('game.active', game.active, 'game.playable_cards[67].playable', game.playable_cards[67].playable)
-
-
- if (game.played_card === 67 && game.playable_cards.includes(67)){
- if (game.active === DEM && (game.dem_tst_position > game.com_tst_position)) {
- gen_action('event')
- }
- if (game.active === COM && (game.dem_tst_position < game.com_tst_position)) {
- gen_action('event')
- }
- }
-
- //Continue with normal logic
-
- //Check if it is a card with an event which is always playable
-
- if (cards[game.played_card].playable) {
- get_events(game.played_card)
- }
-
- // Resolve cards with variable events (not Reformer)
-
- if (game.played_card !== 67 && game.playable_cards.includes(game.played_card)) {
- get_events(game.played_card)
- } /*
- if ((game.active === DEM && cards[game.played_card].side === 'D' && game.playable_cards[game.played_card].playable === 1) || (game.active === COM && cards[game.played_card].side === 'C' && game.playable_cards[game.played_card].playable ===1) || (cards[game.played_card].side === 'N'&& game.playable_cards[game.played_card].playable ===1)) {
- gen_action('event')
- } else if ((game.active === DEM && (cards[game.played_card].side === 'C' && game.playable_cards[game.played_card].playable ===1)) || game.active === COM && (cards[game.played_card].side === 'D' && game.playable_cards[game.played_card].playable ===1)) {
- gen_action('opp_event')
- } */
-
- gen_action('influence')
- if (game.active === DEM && game.dem_tst_attempted_this_turn === 0 && game.dem_tst_position <=8 || game.active === COM && game.com_tst_attempted_this_turn === 0 && game.com_tst_position <= 8) {
- gen_action('tst')
- }
- gen_action('support_check')
- },
- event() {
- push_undo()
- console.log('played event, game.active', game.active, 'game.view_opp_hand', game.view_opp_hand)
- log_gap(`Played C${cards[game.played_card].number} for the event`)
- if (scoring_cards.includes(game.played_card)) {game.phase = 0}
- else {game.phase = 1}
- game.return = game.active
- if (switch_events.includes(game.played_card)) {next_player()}
- game.vm_event = game.played_card
- goto_vm(game.vm_event)
- },
- opp_event() {
- push_undo()
- log_gap(`Played C${cards[game.played_card].number} for the event`)
- game.phase = 1 /*Do I still need this?*/
- game.vm_infl_to_do = true
- game.return = game.active
- game.vm_event = game.played_card
- if (auto_resolve_events.includes(game.played_card) || switch_events.includes(game.played_card)) {
- goto_vm(game.vm_event)}
- else {
- next_player()
- log(`C${game.vm_event}`)
- goto_vm(game.vm_event)
- }
- },
- influence() {
- push_undo()
- log_gap(`Played C${cards[game.played_card].number} to place SPs`)
-
-
- // Check if Common European Home played for influence
- if (game.played_card === 21) {
- if (game.active === DEM) {
- game.vp --
- log('-1 VP')
- if (check_vp()) {
- return
- }
- } else {
- game.vp ++
- log('+1 VP')
- if (check_vp()) {
- return
- }
- }
- }
- // Check if card is opponent card with event that needs to be resolved
-
- if (cards[game.played_card].playable || game.playable_cards.includes(game.played_card)) {
- if ((game.active === DEM && cards[game.played_card].side === "C" ) || (game.active === COM && cards[game.played_card].side === "D")) {
- //game.phase = 1 /*Do I need this? */
- game.vm_event_to_do = true
- }
- }
-
- // If ABHR - Set AHBR tracker to true
- if (game.persistent_events.includes(58)) {
- game.austria_hungary_border_reopened_tracker = true
- }
- game.state='add_influence'
- valid_spaces_infl()
- },
- tst() {
- push_undo()
- log_gap(`Played C${cards[game.played_card].number} to the Tiananmen Square Track`)
- game.state='tiananmen_square_attempt'
- },
- support_check() {
- push_undo()
- log_gap(`Played C${cards[game.played_card].number} for support checks`)
-
- // Check if card is opponent card with event that needs to be resolved
- /*if (game.phase === 0 && game.active === DEM && cards[game.played_card].side === "C" && game.playable_cards[game.played_card].playable === 1 || game.phase === 0 && game.active === COM && cards[game.played_card].side === "D" && game.playable_cards[game.played_card].playable === 1 ) {
- game.vm_event_to_do = true
- }*/
-
- if (cards[game.played_card].playable || game.playable_cards.includes(game.played_card)) {
- if ((game.active === DEM && cards[game.played_card].side === "C" ) || (game.active === COM && cards[game.played_card].side === "D")) {
- game.vm_event_to_do = true
- }
- }
-
-
-
- game.available_ops = 2
- game.state='support_check_prep'
- valid_spaces_sc()
- },
- tst_8() { /*Play card for ops and event */
- game.vm_event_to_do = true
- game.vm_infl_to_do = true
- game.tst_8 = true
- game.state = 'vm_tst_8'
- },
- done () {
- end_round()
- }
-
-}
-
-states.resolve_opponent_event = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- console.log('in resolve opponent event: discard', game.strategy_discard)
- if (game.vm_infl_to_do) {
- view.prompt = 'Event resolved. Choose to play card for:'
- gen_action('influence')
- gen_action('support_check')
- } else if (game.vm_event_to_do) {
- // Check for Tiananmen Square Track ability - play opponent card without triggering event
- if ((game.active === DEM && game.dem_tst_position >= 7 && game.com_tst_position < 7 && !game.tst_7) || (game.active === COM && game.com_tst_position >= 7 && game.dem_tst_position < 7 && !game.tst_7)){
- gen_action('tst_7')
- }
- view.prompt = `${clean_name(cards[game.played_card].name)}: you must resolve the opponent event.`
- gen_action('opp_event')
- } else {
- view.prompt = 'Event resolved. End the action round.'
- gen_action('done')
- }
- },
- influence(){
- push_undo()
- // If ABHR - Set AHBR tracker to true
- if (game.persistent_events.includes(58)) {
- game.austria_hungary_border_reopened_tracker = true
- }
- game.state = 'finish_add_infl'
- valid_spaces_infl()
- },
- support_check() {
- push_undo()
- game.available_ops = 2
- game.state = 'finish_support_check_prep'
- valid_spaces_sc()
- },
- opp_event() {
- game.vm_event_to_do = false
- game.return_state = 'resolve_opponent_event'
- if (auto_resolve_events.includes(game.played_card) || switch_events.includes(game.played_card)) {
- game.return = game.active
- log(`Played C${game.played_card} for the event`)
- goto_vm(game.played_card)}
- else {
- if (game.active === DEM) {
- game.return = COM
- } else {
- game.return = DEM
- }
- next_player()
- log(`C${game.played_card}`)
- goto_vm(game.played_card)
- }
- },
- tst_7() {
- push_undo()
- log('Event cancelled using Tiananmen Square Track Award')
- game.tst_7 = true
- game.vm_event_to_do = false
- },
- done() {
- /*if(game.round_player === COM && game.active === DEM) {
- log_h3('End of Communist Action Round')
- change_player()
- } */
- end_round()
- }
-}
-
-
-states.finish_add_infl = {
- inactive: 'add SPs.',
- prompt () {
- if (game.available_ops === 0) {
- view.prompt = 'Place SPs: done.'
- gen_action("done")
- return;
- }
-
- view.prompt = `Add SPs: ${game.available_ops} remaining`
-
- // Generate actions for valid spaces
- for (let space_id of game.valid_spaces) {
- gen_action_infl(spaces[space_id].name_unique)
- }
- },
- infl(space) {
- add_infl(space)
- },
- done() {
- if (game.summary.length > 0) {
- pop_summary()
- log_br()
- }
-
- end_round()
- }
-}
-
-states.finish_support_check_prep = {
- inactive: 'do support checks.',
- prompt () {
- if (game.available_ops === 0) {
- view.prompt = 'Support checks: done.'
- gen_action('done')
- //return
- } else {
- view.prompt = `Select a space. ${pluralize(game.available_ops, 'support check')} remaining.`
- for (let space_id of game.valid_spaces) {
- gen_action_sc(spaces[space_id].name_unique)
- }
- }
- },
- sc(space) {
- push_undo()
- game.selected_space = find_space_index(space)
- // Check for Austria-Hungary Border Reopened - check on first support check only
- //console.log('game.austria_hungary_border_reopened_checked', game.austria_hungary_border_reopened_checked)
- if (game.persistent_events.includes(58)){
- if (game.active === DEM && game.available_ops > 1) {
- //console.log('in ahb check, country, ', spaces[game.selected_space].country, 'ahb', 'austria_hungary_border_reopened'])
- if (spaces[game.selected_space].country === 'East_Germany' && game.persistent_events.includes(58) && game.active === DEM) {
- game.state = 'finish_austria_hungary_border_reopened_check'
- return
- }
- }
- }
- game.state = 'finish_do_support_check'
- },
- done () {
- end_round()
- }
-}
-
-states.finish_austria_hungary_border_reopened_check = {
- inactive: 'decide Austria-Hungary Border Reopened',
- prompt() {
- view.prompt = 'Austria-Hungary Border Reopened: will both support checks be in East Germany?'
- gen_action('yes')
- gen_action('no')
- },
- yes() {
- game.austria_hungary_border_reopened_tracker = true
- game.state = 'finish_do_support_check'
- },
- no() {
- game.state = 'finish_do_support_check'
- }
-}
-
-states.finish_do_support_check = {
- inactive: 'do support checks',
- prompt () {
- view.prompt = `Support check: ${spaces[game.selected_space].name_unique}. Roll a die.`
- gen_action('roll')
- },
- roll() {
- clear_undo()
- do_sc(spaces[game.selected_space].name_unique)
- game.available_ops--
- if (game.available_ops === 0) {
- game.valid_spaces = []
- }
- game.state = 'finish_support_check_prep'
- return
- }
-}
-
-states.add_influence = {
- inactive: 'add SPs.',
- prompt () {
- if (game.available_ops <= 0) {
- view.prompt = 'Place SPs: done.'
- gen_action("done")
- return
- }
-
- view.prompt = `Add SPs: ${game.available_ops} remaining.`
-
- // Generate actions for valid spaces
- for (let space_id of game.valid_spaces) {
- gen_action_infl(spaces[space_id].name_unique);
- }
- },
- infl(space) {
- add_infl(space)
- },
- done() {
- if (game.summary.length > 0) {
- pop_summary()
- log_br()
- }
-
- if(game.vm_event_to_do) {
- reset_austria_hungary_border_reopened()
- game.state = 'resolve_opponent_event'}
- else {
- end_round()}
- }
-}
-
-states.tiananmen_square_attempt = {
- inactive: 'do Tiananmen Square Attempt.',
- prompt () {
- view.prompt = 'Tiananmen Square Track attempt: Roll a die.'
- gen_action('roll')
- },
- roll() {
- clear_undo()
- do_tst_attempt ()
- }
-}
-
-states.tiananmen_square_attempt_success = {
- inactive: 'do Tiananmen Square Attempt.',
- prompt () {
- view.prompt = 'Tiananmen Square Track attempt successful.'
- gen_action('done')
- },
- done () {
- end_round()
- }
-}
-
-states.tiananmen_square_attempt_fail = {
- inactive: 'do Tiananmen Square Attempt.',
- prompt () {
- view.prompt = 'Tiananmen Square Track attempt failed.'
- gen_action('done')
- },
- done () {
- end_round()
- }
-}
-
-states.tst_goddess = {
- inactive: 'choose whether to discard a card.',
- prompt() {
- //if (game.phase === 0) {
- view.prompt = 'Tiananmen Square Track award: you may discard a non-Power Struggle Card and draw a replacement.'
- for (let card of game.valid_cards) {
- gen_action_card(card)
- }
- gen_action('pass')
- /*} else {
- view.prompt = 'Discard a card: done.'
- gen_action('done')
- }*/
- },
- card(card) {
- push_undo()
- discard(card)
- game.valid_cards = []
- game.state = 'tst_goddess_draw'
- //game.phase++
- /*if (game.active === DEM) {
- draw_cards(game.strategy_deck, game.democrat_hand, game.communist_hand, game.democrat_hand.length +1, game.communist_hand.length)
- } else {
- draw_cards(game.strategy_deck, game.democrat_hand, game.communist_hand, game.democrat_hand.length, game.communist_hand.length +1)
- }*/
- },
- pass() {
- log('Did not discard')
- log_h2("Action Round " + game.round)
- if (game.active === DEM) {
- next_player()
- } else {
- log_side()
- }
- if (game.persistent_events.includes(5)) {
- game.state = 'general_strike'
- } else {
- game.state = 'choose_card'
- }
- },
- done() {
-
- log_h2("Action Round " + game.round)
- if (game.active === DEM) {
- next_player()
- } else {
- log_side()
- }
- game.phase = 0
- if (game.persistent_events.includes(5)) {
- game.state = 'general_strike'
- } else {
- game.state = 'choose_card'
- }
- }
-}
-
-states.tst_goddess_draw = {
- inactive: 'choose whether to discard a card.',
- prompt() {
- view.prompt = 'Draw a replacement card.'
- gen_action('draw')
- },
- draw() {
- if (game.active === DEM) {
- draw_cards(game.strategy_deck, game.democrat_hand, game.communist_hand, game.democrat_hand.length +1, game.communist_hand.length)
- } else {
- draw_cards(game.strategy_deck, game.democrat_hand, game.communist_hand, game.democrat_hand.length, game.communist_hand.length +1)
- }
- log_h2("Action Round " + game.round)
- if (game.active === DEM) {
- next_player()
- } else {
- log_side()
- }
- game.phase = 0
- if (game.persistent_events.includes(5)) {
- game.state = 'general_strike'
- } else {
- game.state = 'choose_card'
- }
- }
-}
-
-
-
-states.support_check_prep = {
- inactive: 'do support checks',
- prompt () {
- if (game.available_ops === 0) {
- view.prompt = 'Support checks: done.'
- gen_action('done')
- //return
- }
- if (game.available_ops > 0) {
- view.prompt = `Select a space. ${pluralize(game.available_ops, 'support check')} remaining.`
-
- for (let space_id of game.valid_spaces) {
- gen_action_sc(spaces[space_id].name_unique)
- }
- }
- },
- sc(space) {
- push_undo()
- game.selected_space = find_space_index(space)
-
- // Check for Austria-Hungary Border Reopened - check on first support check only
- //console.log('game.austria_hungary_border_reopened_checked', game.austria_hungary_border_reopened_checked)
- if (game.persistent_events.includes(58)) {
- if (game.active === DEM && game.available_ops > 1) {
- if (spaces[game.selected_space].country === 'East_Germany' && game.persistent_events.includes(58) && game.active === DEM) {
- game.state = 'austria_hungary_border_reopened_check'
- return
- }
- //game.state = 'do_support_check'
- } /*else { */
- }
- game.state = 'do_support_check'
- console.log('game.state after space selected:', game.state)
- //}
- },
- done () {
- if (game.is_pwr_struggle) {/*Crowd Turns Against Ceausescu should be the only time you end up here during a power struggle */
- if (game.return !== game.active) {
- next_player()
- }
- game.state = 'raise_stakes_1'
- return
- }
-
- if (game.vm_event_to_do) {
- reset_austria_hungary_border_reopened()
- game.state = 'resolve_opponent_event'
- } else {
- end_round()
- }
- }
-}
-
-states.do_support_check = {
- inactive: 'do support checks.',
- prompt () {
- console.log('in do_support_check')
- view.prompt = `Support check: ${spaces[game.selected_space].name_unique}. Roll a die.`
- gen_action('roll')
- },
- roll() {
- clear_undo()
- do_sc(spaces[game.selected_space].name_unique)
- game.available_ops--
- if (game.available_ops === 0) {
- game.valid_spaces = []
- }
- game.state = 'support_check_prep'
- return
- }
-}
-
-states.austria_hungary_border_reopened_check = {
- inactive: 'decide Austria-Hungary Border Reopened',
- prompt() {
- view.prompt = 'Austria-Hungary Border Reopened: will both support checks be in East Germany?'
- gen_action('yes')
- gen_action('no')
- },
- yes() {
- game.austria_hungary_border_reopened_tracker = true
- game.state = 'do_support_check'
- },
- no() {
- game.state = 'do_support_check'
- }
-}
-
-//======================= POWER STRUGGLE ===============================
-
-states.draw_power_cards = {
- inactive: 'draw cards.',
- prompt() {
- view.prompt = 'Draw cards.'
- gen_action('draw')
- },
- draw() {
- push_undo()
- game.power_struggle_deck = [...all_power_cards]
- console.log('game.power_struggle_deck.length', game.power_struggle_deck.length)
- console.log('called draw cards, country', game.pwr_struggle_in, 'game.active', game.active, 'game.view_opp_hand', game.view_opp_hand)
- console.log('test3')
- let presence = check_presence(game.pwr_struggle_in)
- console.log('test2')
- if (presence.dem_spaces > 0) {
- game.dem_pwr_hand_limit = 6 + 2*(presence.dem_spaces - 1)
- } else {
- game.dem_pwr_hand_limit = 0
- }
- if (presence.com_spaces > 0 ) {
- game.com_pwr_hand_limit = 6 + 2*(presence.com_spaces - 1)
- } else {
- game.com_pwr_hand_limit = 0
- }
- // Events which affect cards drawn
- if (game.persistent_events.includes(17) && game.com_pwr_hand_limit >= 2) {
- log('Democrat receives 2 cards from Communist due to C17')
- game.dem_pwr_hand_limit += 2
- game.com_pwr_hand_limit -= 2
- discard_from_table(17)
- game.persistent_events = game.persistent_events.filter(n => n !== 17)
- }
-
- if (game.persistent_events.includes(72)) {
- let farmer_check
- for (let space of spaces) {
- if (space && space.country === game.pwr_struggle_in && space.socio === 3 && check_dem_control(space.space_id)) {
- farmer_check = true
- }
- }
- if (farmer_check && game.com_pwr_hand_limit > 0) {
- log('Democrat receives 1 cards from Communist due to C72')
- game.dem_pwr_hand_limit += 1
- game.com_pwr_hand_limit -= 1
- permanently_remove(72)
- game.persistent_events = game.persistent_events.filter(n => n !== 72)
- }
- }
-
- if (game.persistent_events.includes(102) && game.dem_pwr_hand_limit >=2 && (game.pwr_struggle_in === 'Romania' || game.pwr_struggle_in === 'Bulgaria')) {
- log('Communist receives 2 cards from Democrat due to C102')
- game.dem_pwr_hand_limit -= 2
- game.com_pwr_hand_limit += 2
- permanently_remove(102)
- game.persistent_events = game.persistent_events.filter(n => n !== 102)
- }
-
- //Draw Power Cards
- game.is_pwr_struggle = true
- console.log('game.dem_pwr_hand_limit', game.dem_pwr_hand_limit, 'game.com_pwr_hand_limit', game.com_pwr_hand_limit)
- draw_cards(game.power_struggle_deck, game.dem_pwr_hand, game.com_pwr_hand, game.dem_pwr_hand_limit, game.com_pwr_hand_limit)
- game.valid_cards = all_power_cards
-
- log(`Communist: ${game.com_pwr_hand.length} cards`)
- log(`Democrat: ${game.dem_pwr_hand.length} cards`)
-
- //Check if The Crowd Turns Against Ceausescu occurs
- if (game.table_cards.includes(54) && game.pwr_struggle_in === 'Romania') {
- console.log('draw cards: crowd subcheck, game.active', game.active)
- if (game.active === COM) {
- game.return = COM
- next_player()
- }
- log_h3('The Crowd Turns Against Ceausescu')
- game.persistent_events.push(54)
- game.state = 'the_crowd_turns_against_ceausescu_prep'
- } else {
- log_h2('Raise the Stakes')
- game.state = 'raise_stakes_1'
- console.log('game.state', game.state, 'game.active', game.active, 'game.view_opp_hand', game.view_opp_hand)
- }
- }
-}
-
-states.the_crowd_turns_against_ceausescu_prep = {
- get inactive() {
- return `resolve ${clean_name(cards[54].name)}.`
- },
- prompt() {
- view.prompt = 'The Crowd Turns Against Ceausescu: draw cards.'
- gen_action('draw')
- },
- draw() {
- game.ceausescu_cards = []
- draw_cards(game.power_struggle_deck, game.ceausescu_cards, game.com_pwr_hand, 15, game.com_pwr_hand.length)
- console.log('game.ceausescu_cards', game.ceausescu_cards)
- game.temp = game.ceausescu_cards.filter(card => card && card >=25 && card <= 30).length
- log(`Drew ${pluralize(game.temp, 'Rally in the Square')}.`)
- game.vm_available_ops = game.temp * 3
- game.state = 'vm_the_crowd_turns_against_ceausescu'
- }
-}
-
-states.vm_the_crowd_turns_against_ceausescu = {
- get inactive() {
- return `resolve ${clean_name(cards[54].name)}.`
- },
- prompt() {
- view.prompt = `You have ${game.vm_available_ops} operations points. Play for:`
- gen_action('influence')
- gen_action('support_check')
- },
- influence() {
- push_undo()
- delete game.ceausescu_cards
- valid_spaces_infl()
- game.valid_spaces = game.valid_spaces.filter(n => spaces[n].country === 'Romania')
- game.state = 'the_crowd_turns_against_ceausescu_infl' /* Send this to add_infl. Add check at end of add_infl similar to valid_spaces*/
- },
- support_check() {
- push_undo()
- delete game.ceausescu_cards
- valid_spaces_sc()
- game.available_ops = 2
- game.state = 'support_check_prep'
- }
-}
-
-states.the_crowd_turns_against_ceausescu_infl = {
- inactive: 'add SPs.',
- prompt () {
- if (game.vm_available_ops === 0)
- {
- view.prompt = 'Place SPs: done.';
- gen_action("done");
- return;
- }
-
- view.prompt = `Add SPs: ${game.vm_available_ops} remaining`
- for (let space of game.valid_spaces) {
- gen_action_infl(spaces[space].name_unique)
- }
- },
- infl(space) {
- vm_do_add_infl(space)
- },
- done() {
- if (game.summary.length > 0) {
- pop_summary()
- log_br()
- }
-
- if (game.return !== game.active) {
- next_player()
- }
- log_h2('Raise the Stakes')
- game.state = 'raise_stakes_1'
- }
-}
-
-states.raise_stakes_1 = {
- inactive: 'raise the stakes',
-
- prompt () {
- console.log('raise the stakes: game.played_power_card', game.played_power_card, 'game.active', game.active, 'game.view_opp_hand', game.view_opp_hand)
- if (game.raised_stakes_discard === 3) {
- view.prompt = 'Raise the stakes: done.'
- gen_action('done')
- } else {
- view.prompt = `Discard ${3-game.raised_stakes_discard} cards to raise the stakes.`
- if (game.raised_stakes_discard === 0) {
- gen_action('pass')
- }
- for (let card of game.valid_cards) {
- gen_action_card(card)
- }
- }
- },
- card(card) {
- push_undo()
- if (numberless_cards.includes(card)) {
- log(`Discarded: P${card}`)
- } else {
- log(`Discarded: P${card} V${power_cards[card].value}`)
- }
- discard(card)
-
- game.raised_stakes_discard ++
- if (game.raised_stakes_discard === 3) {
- game.raised_stakes++
- }
-
-
- },
- pass(){
- log('Did not raise the stakes')
- game.raised_stakes_discard = 0
- next_player()
- game.state = 'raise_stakes_2'
- },
- done () {
- log_gap('Raised the stakes')
- game.raised_stakes_discard = 0
- next_player()
- game.state = 'raise_stakes_2'
- }
-}
-
-states.raise_stakes_2 = {
- inactive: 'raise the stakes',
-
- prompt () {
-
- if (game.raised_stakes_discard === 3) {
- view.prompt = 'Raise the stakes: done.'
- gen_action('done')
- } else {
- view.prompt = `Discard ${3-game.raised_stakes_discard} cards to raise the stakes.`
- if (game.raised_stakes_discard === 0) {
- gen_action('pass')
- }
- for (let card of game.valid_cards) {
- gen_action_card(card)
- }
- }
- },
- card(card) {
- push_undo()
- if (numberless_cards.includes(card)) {
- log(`Discarded: P${card}`)
- } else {
- log(`Discarded: P${card} V${power_cards[card].value}`)
- }
- discard(card)
-
- game.raised_stakes_discard ++
- if (game.raised_stakes_discard === 3) {
- game.raised_stakes++
- }
-
- },
- pass() {
- log('Did not raise the stakes')
- game.raised_stakes_discard = 0
- game.valid_cards = []
- log_h2('Play Cards')
- next_player()
- game.state = 'begin_power_struggle'
- },
- done () {
- log_gap('Raised the stakes')
- game.raised_stakes_discard = 0
- game.valid_cards = []
- log_h2('Play Cards')
- next_player()
- game.state = 'begin_power_struggle'
- },
-}
-
-states.begin_power_struggle = {
- inactive: 'begin power struggle.',
- prompt() {
- view.prompt = 'Begin power struggle.'
- gen_action('struggle')
- },
- struggle () {
- do_valid_cards()
- game.state = 'power_struggle'
- }
-}
-
-states.power_struggle = {
- inactive: 'play a card.',
- prompt () {
- console.log('game.tactics_fails', game.tactics_fails)
- if (game.phase === 0) {
- if (game.valid_cards.length > 0) {
- view.prompt = "Play a card."
- for (let card of game.valid_cards) {
- gen_action_card(card)
- }
- } else if ( game.valid_cards.length === 0) {
- view.prompt = 'No valid cards. You must concede.'
- gen_action('concede')
- }
- }
- if (game.phase === 1) {
- if (game.valid_cards.length > 0) {
- view.prompt = `${power_cards[game.played_power_card].name} played. You must match or concede.`
- gen_action('concede')
- for (let card of game.valid_cards) {
- gen_action_card(card)
- }
- } else if (game.valid_cards.length === 0) {
- view.prompt = `${power_cards[game.played_power_card].name} played. You must concede.`
- gen_action('concede')
- }
- }
- else if (game.phase === 2) {
- view.prompt = 'You matched. Roll a die.'
- gen_action('roll')
- }
- else if (game.phase === 3) {
- view.prompt = 'Play leader as:'
- if (game.tactics_fails !== "Strike") {gen_action('strike')}
- if (game.tactics_fails !== "March") {gen_action('march')}
- if (game.tactics_fails !== "Rally in the Square") {gen_action('rally')}
- if (game.tactics_fails !== "Petition") {gen_action('petition')}
- }
- },
- card(card) {
- push_undo()
- discard(card)
- game.valid_cards=[]
- game.return_state = 'power_struggle'
- if (card === 52) {
- log_gap(`Played P52: P${power_cards[game.played_power_card].number} no longer playable`)
-
- } else {
- if (game.phase === 0 && leader_cards.includes(card)) {} /* Log nothing. Probably a better way to do this */
- else if (numberless_cards.includes(card)) {
- log_gap(`Played: P${card}`)
- } else {
- log_gap(`Played: P${card} V${power_cards[card].value}`)
- }
- }
- if (game.phase === 0) {
- if (card >= 37 && card <= 48) { /*When a leader is played */
- game.played_power_card = card
- game.phase = 3
- } else if (card === 49){ /*Scare Tactics */
- game.return = ''
- goto_vm(349) /*Can I combine these 3 into a single stage where you goto_vm(300 + card) ? */
- } else if (card === 50) { /*Support Surges */
- if (game.active === DEM) {
- game.return = COM
- } else {
- game.return = DEM
- }
- goto_vm(350)
- } else if (game.phase === 0 && card === 51) { /*Support Falters */
- next_player()
- goto_vm(351)
- } else {
- game.played_power_card = card
- game.phase = 1
- next_player()
- do_valid_cards()
- }
- } else if (game.phase === 1) {
- if (card === 52) {
- game.tactics_fails = power_cards[game.played_power_card].name
- game.phase = 0
- next_player()
- do_valid_cards()
- } else if (power_cards[game.played_power_card].value === 1) {
- log('Takes initiative')
- game.phase = 0
- do_valid_cards()
- } else {
- game.phase = 2
- }
- }
- },
- roll () {
- let roll = Math.floor(Math.random() * 6) + 1
- log(`Rolled a ${roll}`)
- if (roll >= power_cards[game.played_power_card].value) {
- log('Initiative roll successful')
- game.phase = 0
- do_valid_cards()
- } else {
- log(`Initiative roll failed. Required ${power_cards[game.played_power_card].value} or more`)
- game.phase = 0
- next_player()
- do_valid_cards()
- }
- },
- concede () {
- push_undo()
- log('Conceded')
- log_h2('Aftermath')
- log_h3('Support Loss')
- //if ((game.played_power_card >= 25 && game.played_power_card <= 30) || game.played_power_card === 53) {game.rally_win = 2}
- //if ((game.played_power_card >= 31 && game.played_power_card <= 36) || game.played_power_card === 54) {game.petition_win = 2}
- if (game.phase === 0) {
- game.played_power_card = 0 /*If conceded when held the initiative but had no playable cards, ignore the last played card */
- }
- game.phase = 0
- game.state = 'support_loss'
- },
- strike () {
- log(`Played: P${power_cards[game.played_power_card].number} as a Strike`)
- game.played_power_card = 9
- game.phase = 1
- next_player()
- do_valid_cards()
- },
- march () {
- log(`Played: P${power_cards[game.played_power_card].number} as a March`)
- game.played_power_card = 21
- game.phase = 1
- next_player()
- do_valid_cards()
- },
- rally () {
- log(`Played: P${power_cards[game.played_power_card].number} as a Rally in the Square`)
- game.played_power_card = 53
- game.phase = 1
- next_player()
- do_valid_cards()
- },
- petition () {
- log(`Played: P${power_cards[game.played_power_card].number} as a Petition`)
- game.played_power_card = 54
- game.phase = 1
- next_player()
- do_valid_cards()
- },
- /*draw () {
- if (game.active === DEM) {
- draw_cards(game.power_struggle_deck, game.dem_pwr_hand, game.com_pwr_hand, game.dem_pwr_hand.length+2, game.com_pwr_hand.length)
- } else {draw_cards(game.power_struggle_deck, game.dem_pwr_hand, game.com_pwr_hand, game.dem_pwr_hand.length, game.com_pwr_hand.length+2)}
- game.phase = 0
- next_player()
- do_valid_cards()
- },*/
- /*infl(space) {
- game.remove_opponent_infl = true
- remove_infl(space)
- game.phase = 6
- },
- discard () { /*Is this still needed?
- if (game.active === DEM) {discard_card(game.dem_pwr_hand)}
- else {discard_card(game.com_pwr_hand)}
- game.available_ops --
- }, */
- done () {
- if (game.phase === 7) { /*Is this ever called anymore? */
- game.phase = 0
- log_msg_gap('Takes initiative')
- do_valid_cards()
- } else {
- game.phase = 0
- next_player()
- do_valid_cards()
- }
- }
-}
-
-states.support_loss ={
- inactive: 'do Support Loss.',
- prompt () {
- console.log('game.played_power_card', game.played_power_card)
- if (game.phase === 0) {
- view.prompt = 'You lost the Power Struggle. Roll a die for Support Loss.'
- gen_action('roll')
- } else if (game.phase === 1 && game.available_ops > 0 && game.valid_spaces.length > 0) {
- view.prompt = `Support Loss: remove ${pluralize(game.available_ops,'SP')}.`
-
- for (let space_id of game.valid_spaces) {
- gen_action_infl(spaces[space_id].name_unique)
- }
- } else if (game.phase === 1 && game.available_ops === 0 ) {
- view.prompt = 'Support Loss: finished.'
- gen_action('done')
- } else if (game.phase === 1 && game.valid_spaces.length === 0) {
- view.prompt = 'Support Loss: no remaining SPs to remove.'
- gen_action('done')
- }
- },
- roll () {
- clear_undo()
- let roll = Math.floor(Math.random() * 6) + 1
- let rally_win = 0
- let petition_win = 0
- log(`Rolled a ${roll}`)
- if ((game.played_power_card >= 25 && game.played_power_card <= 30) || game.played_power_card === 53) { rally_win = 2}
- if ((game.played_power_card >= 31 && game.played_power_card <= 36) || game.played_power_card === 54) { petition_win = 2}
- let modified_roll = roll + game.raised_stakes + rally_win - petition_win
-
- // Roll modifiers
- if (game.active === COM && game.persistent_events.includes(62)) {
- log('+1 from C62')
- modified_roll ++
- }
-
- if (modified_roll < 0) {modified_roll = 0}
- else if (modified_roll > 7) {modified_roll = 7}
-
-
- if (game.raised_stakes !== 0) {
- log(`+${game.raised_stakes} from Raising the Stakes`)
- }
- if (rally_win !== 0) {
- log('+2 from winning on a P25')
- }
- if (petition_win !== 0) {
- log('-2 from winning on a P31')
- }
- if (modified_roll !== roll) {
- log(`Modified roll: ${modified_roll}`)
- }
- game.available_ops = support_loss_roll[modified_roll]
- if (game.available_ops === 0) {
- log('Does not remove SPs')
- }
- game.phase++
- valid_spaces_support_loss()
- },
- infl (space) {
- game.remove_opponent_infl = false /* Don't know why this is needed... */
- remove_infl(space)
- if (game.available_ops === 0 ) {
- game.valid_spaces = []
- }
- },
- done () {
- if (game.summary.length > 0) {
- pop_summary()
- log_br()
- }
- next_player()
- log_h3('Victory Point')
- game.phase = 0
- game.state = 'vp_roll'
- }
-}
-
-states.vp_roll = {
- inactive: 'do VP Roll',
- prompt () {
- if (game.phase === 0) {
- view.prompt = 'Roll a die for Victory.'
- gen_action('roll')
- } else if (game.phase === 1) {
- view.prompt = 'Take power.'
- gen_action('take')
- } else if (game.phase === 2) {
- view.prompt = 'Proceed to scoring.'
- gen_action('scoring')
- }
- },
- roll () {
- let roll = Math.floor(Math.random() * 6) + 1
- log(`Rolled a ${roll}`)
- let rally_win = 0
- let petition_win = 0
- if ((game.played_power_card >= 25 && game.played_power_card <= 30) || game.played_power_card === 53) {rally_win = 2}
- if ((game.played_power_card >= 31 && game.played_power_card <= 36) || game.played_power_card === 54) {petition_win = 2}
- let modified_roll = roll + game.raised_stakes + rally_win - petition_win
- if (game.active === DEM && game.persistent_events.includes(62)) {
- log('+1 from C62')
- modified_roll ++
- }
- if (modified_roll < 0) {modified_roll = 0}
- else if (modified_roll > 7) {modified_roll = 7}
-
- if (game.raised_stakes !== 0) {
- log(`+${game.raised_stakes} from Raising the Stakes`)
- }
- if (rally_win !== 0) {
- log('+2 from winning on a P25')
- }
- if (petition_win !== 0) {
- log('-2 from winning on a P31')
- }
- if (modified_roll !== roll) {
- log(`Modified roll: ${modified_roll}`)
- }
- let vp_change = vp_roll[modified_roll]
- if (game.active === DEM) {
- log(`+${vp_change} VP`)
- } else {
- log(`-${vp_change} VP`)
- }
- if (roll >= 4)
- console.log('VP before', game.vp)
- if (game.active === DEM) {game.vp += vp_change}
- else {game.vp -= vp_change}
- console.log('VP after', game.vp)
- if (game.active === DEM && modified_roll >= 4) {
- game.phase = 1
- } else {
- game.phase = 0
- if (game.active === DEM) {next_player()}
- game.state = 'choose_power'
- }
- },
- take () {
- push_undo()
- //Find name of scoring card
- let scoring_card = scoring_cards[countries.indexOf(game.pwr_struggle_in)]
- permanently_remove(scoring_card)
- take_power(game.pwr_struggle_in)
- game.phase = 2
- },
- scoring () {
- push_undo()
- log_h2('Scoring')
- score_country(game.pwr_struggle_in)
- game.state = 'finish_scoring'
- },
-}
-
-states.choose_power = {
- inactive: 'choose whether to remain in power.',
- prompt () {
- if (game.phase === 0) {
- view.prompt = 'Choose whether to remain in power.'
- gen_action('retain')
- gen_action('surrender')
- } else if (game.phase === 1) {
- view.prompt = 'Proceed to scoring.'
- gen_action('scoring')
- }
- },
- retain() {
- push_undo()
- retain_power(game.pwr_struggle_in)
- game.phase = 1
- },
- surrender () {
- push_undo()
- take_power(game.pwr_struggle_in)
- permanently_remove(game.played_card)
- game.phase = 1
- },
- scoring () {
- push_undo()
- score_country(game.pwr_struggle_in)
-
- //Check if The Tyrant is Gone occurs
- if (game.table_cards.includes(97) && game.pwr_struggle_in === 'Romania' && game.persistent_events.includes(54)) {
- game.return_state = 'finish_scoring'
- game.state = 'the_tyrant_is_gone'
- } else {
- game.state = 'finish_scoring'
- }
- }
-}
-/*
-states.score_country = {
- inactive: `score country`,
- prompt () {
- view.prompt = 'Scoring: done.'
- gen_action('done')
- },
- done () {
- reset_power()
- /*if (game.return !== game.active) {
- next_player()}
- game.state = 'finish_scoring'
- }
-}
-*/
-
-states.the_tyrant_is_gone ={
- inactive: 'resolve The Tyrant is Gone.',
- prompt() {
- view.prompt = 'Play The Tyrant is Gone for the event.'
- gen_action('event')
- },
- event() {
- if (game.active !== DEM) {
- next_player()
- }
- log_h3(`C97`)
- game.vm_event = 97
- goto_vm(game.vm_event)
- }
-}
-
-states.finish_scoring ={
- inactive: 'finish scoring.',
- prompt() {
- view.prompt = 'End power struggle.'
- gen_action('done')
- } ,
- done() {
- console.log('game.return_state', game.return_state)
- log('Power Struggle resolved') /*At this point log card dicarded or permanently removed? */
- if (game.persistent_events.includes(111)) {
- game.state = 'new_years_eve_party'
- return
- }
- if (check_vp()) {
- return
- }
- reset_power()
- end_round()
- }
-}
-
-// ======================================= END TURN STATES ==========================================
-
-states.end_turn_4_5_4 = {
- inactive: 'verify held cards.',
- prompt() {
- view.prompt = 'End Turn: verify held cards.'
- gen_action('check')
- },
- check() {
- log_h2('Verify held cards')
- const dem_has_scoring_card = game.democrat_hand.some(card => scoring_cards.includes(card))
- const com_has_scoring_card = game.communist_hand.some(card => scoring_cards.includes(card))
- if (!dem_has_scoring_card && !com_has_scoring_card) {
- log('No held scoring cards')
- }
-
- if (dem_has_scoring_card && com_has_scoring_card) {
- log('Both players have held scoring cards')
- game.state = 'game_end_tie'
- }
- else if (dem_has_scoring_card) {
- log('Democrat player has a held scoring card')
- goto_game_over(COM, `${COM} won by held scoring card!`)
- }
- else if (com_has_scoring_card) {
- log('Communist player has a held scoring card')
- goto_game_over(DEM, `${DEM} won by held scoring card!`)
- }
- else if (game.persistent_events.includes(104)) {
- log_h1(`New Year's Eve Party`)
- //Check if the Communist receives VP from The Tyrant is Gone
- if (game.persistent_events.includes(97)) {
- game.vp -= 2
- log(`Communist receives 2 VP from C97`)
- }
- game.persistent_events.push(111)
- game.state = 'new_years_eve_party'
- }
- else if(game.turn === 10) {
- clear_undo()
- log_h2('Final Scoring')
-
- //Check if the Communist receives VP from The Tyrant is Gone
- if (game.persistent_events.includes(97)) {
- game.vp -= 2
- log(`Communist receives 2 VP from C97`)
- }
- game.state = 'final_scoring_held'
-
- } else {
- game.return_state = ''
- new_turn()
- }
- }
-}
-
-states.final_scoring_held = {
- inactive: 'resolve final scoring.',
- prompt() {
- view.prompt = 'Final Scoring: Communist scores VP bonus for the number of countries they retain power.'
- gen_action('bonus')
- },
- bonus() {
- console.log('game.revolutions: ', game.revolutions)
- const held_countries = game.revolutions.filter(value => value === false).length
- let vp_gain = 4*held_countries
- log(`Communist holds ${held_countries} countries: -${vp_gain} VP`)
- game.vp -= 4*held_countries
- game.temp = {'East_Germany': false, 'Poland': false, 'Czechoslovakia': false, 'Hungary': false, 'Romania': false, 'Bulgaria': false}
- game.state = 'final_scoring'
- }
-}
-
-states.final_scoring = {
- inactive: 'score countries.',
- prompt() {
- if (game.temp['East_Germany'] && game.temp['Poland'] && game.temp['Czechoslovakia'] && game.temp['Hungary'] && game.temp['Romania'] && game.temp['Bulgaria']) {
- view.prompt = 'Country scoring: done.'
- gen_action('done')
- } else {
- view.prompt = 'Choose a country to score'
- if (!game.temp['East_Germany']) {gen_action('east_germany')}
- if (!game.temp['Poland']) {gen_action('poland')}
- if (!game.temp['Czechoslovakia']) {gen_action('czechoslovakia')}
- if (!game.temp['Hungary']) {gen_action('hungary')}
- if (!game.temp['Romania']) {gen_action('romania')}
- if (!game.temp['Bulgaria']) {gen_action('bulgaria')}
- }
- },
- east_germany() {
- score_country('East_Germany')
- game.temp['East_Germany'] = true
- },
- poland() {
- score_country('Poland')
- game.temp['Poland'] = true
- },
- czechoslovakia() {
- score_country('Czechoslovakia')
- game.temp['Czechoslovakia'] = true
- },
- hungary() {
- score_country('Hungary')
- game.temp['Hungary'] = true
- },
- romania() {
- score_country('Romania')
- game.temp['Romania'] = true
- },
- bulgaria() {
- score_country('Bulgaria')
- game.temp['Bulgaria'] = true
- },
- done() {
- delete game.temp
- if (game.vp > 0) {
- goto_game_over(DEM, `${DEM} wins on Victory Point Track!`)
- } else if (game.vp < 0) {
- goto_game_over(COM, `${COM} wins on Victory Point Track!`)
- } else if (game.vp === 0) {
- goto_game_over('', `The game is tied!`) /*Not sure what to pass for result */
- }
- }
-}
-
-states.game_over = {
- get inactive() {
- return game.victory
- },
- prompt() {
- view.prompt = game.victory
- },
-}
-
-// ========================== EVENT SPECIFIC STATES =================================
-
-states.general_strike = {
- inactive: 'discard a card.',
- prompt() {
- if (game.played_card === 0 ) {
- view.prompt = 'General Strike: you must discard a card or play a Scoring Card.'
- available_cards = game.communist_hand
- for (let card of available_cards) {
- gen_action_card(card)
- }
- } else if (game.phase >= 1) {
- view.prompt = 'General Strike: done.'
- gen_action('done')
- } else if (game.played_card > 0 ) {
- view.prompt = 'Roll a die.'
- gen_action('roll')
- }
- },
- card (card) {
- push_undo()
- game.played_card = card
- let find_card
- find_card = game.communist_hand.indexOf(card)
- game.communist_hand.splice(find_card, 1)
- game.available_ops = get_card_ops(card)
- if (scoring_cards.includes(card)) {
- game.vm_event = card
- log(`Played C${card} for the event`)
- game.return_state = 'general_strike'
- goto_vm(game.vm_event)
- } else {
- log(`Discarded C${cards[card].number}`)
- }
- },
- roll() {
- clear_undo()
- let roll = Math.floor(Math.random() * 6) + 1
- log(`Rolled a ${roll}`)
-
- log(`+${game.available_ops} from card ops`)
-
- let total = roll + game.available_ops
- log(`Modified total: ${total}`)
-
- if (total > 5) {
- log('The strike is over.')
- permanently_remove(5)
- game.persistent_events = game.persistent_events.filter(n => n !== 5)
- } else {
- log('The strike continues. Required 6 or more')
- }
- game.phase = 1
- },
- done () {
- end_round()
- }
-}
-
-states.honecker ={
- inactive: 'resolve Honecker.',
- prompt() {
- view.prompt = 'Honecker: you may take an extra action round.'
- gen_action('extra')
- gen_action('pass')
- },
- extra() {
- push_undo()
- game.round++
- game.round_player = COM
- game.persistent_events = game.persistent_events.filter(n => n !== 15)
- game.state = 'choose_card'
- },
- pass() {
- log('C15: passed')
- game.persistent_events = game.persistent_events.filter(n => n !== 15)
- end_round()
- }
-}
-
-states.new_years_eve_party = {
- get inactive() {
- return `resolve ${clean_name(cards[104].name)}.`
- },
- prompt() {
- if (!game.is_pwr_struggle) {
- view.prompt = `New Year's Eve Party: you may choose a country to have a final power struggle.`
- if (!game.revolutions[0]) {gen_action('poland')}
- if (!game.revolutions[1]) {gen_action('hungary')}
- if (!game.revolutions[2]) {gen_action('east_germany')}
- if (!game.revolutions[3]) {gen_action('bulgaria')}
- if (!game.revolutions[4]) {gen_action('czechoslovakia')}
- if (!game.revolutions[5]) {gen_action('romania')}
- gen_action('pass')
- } else {
- view.prompt = `New Year's Eve Party: done.`
- gen_action('end')
- }
- },
- east_germany() {
- push_undo()
- log('Chose to score East Germany')
- game.vm_event = 42
- goto_vm(42)
- },
- poland() {
- push_undo()
- log('Chose to score Poland')
- game.vm_event = 22
- goto_vm(22)
- },
- czechoslovakia() {
- push_undo()
- log('Chose to score Czechoslovakia')
- game.vm_event = 55
- goto_vm(55)
- },
- hungary() {
- push_undo()
- log('Chose to score Hungary')
- game.vm_event = 23
- goto_vm(23)
- },
- romania() {
- push_undo()
- log('Chose to score Romania')
- game.vm_event = 95
- goto_vm(95)
- },
- bulgaria () {
- push_undo()
- log('Chose to score Bulgaria')
- game.vm_event = 43
- goto_vm(43)
- },
- pass() {
- push_undo()
- log('No final power struggle')
- if (game.vp > 0) {
- goto_game_over(DEM, `C104: ${DEM} wins on Victory Point Track!`)
- } else if (game.vp < 0) {
- goto_game_over(COM, `C104: ${COM} wins on Victory Point Track!`)
- } else if (game.vp === 0) {
- goto_game_over('', `C104: The game is tied!`) /*Not sure what to pass for result */
- }
- },
- end() {
- if (game.vp > 0) {
- goto_game_over(DEM, `C104: ${DEM} wins on Victory Point Track!`)
- } else if (game.vp < 0) {
- goto_game_over(COM, `C104: ${COM} wins on Victory Point Track!`)
- } else if (game.vp === 0) {
- goto_game_over('', `C104: The game is tied!`) /*Not sure what to pass for result */
- }
- }
-}
-
-states.stasi_end_round = {
- inactive: 'choose next card due to Stasi.',
- prompt() {
- console.log('game.stasi_card', game.stasi_card)
- if (!game.stasi_card || game.stasi_card === 0 ) {
- let available_cards = game.democrat_hand
- if (available_cards.length === 0) {
- view.prompt = 'Stasi: no cards remaining.'
- gen_action('pass')
- return
- }
- view.prompt = 'Stasi: you must select your next card to play.'
-
- for (let card of available_cards) {
- gen_action_card(card)
- }
- } else {
- view.prompt = 'Stasi. Choose card: done.'
- gen_action('done')
- }
- },
- card(card) {
- push_undo()
- log_gap(`Stasi: selected C${cards[card].number}`)
- game.stasi_card = card
- },
- pass() {
- log('Stasi: Democrat has no remaining cards')
- game.stasi_card = 0
- end_stasi_choose_card()
- },
- done() {
- push_undo()
- if (game.stasi_card === 21) {
- game.state = 'stasi_confirm'
- } else {
- end_stasi_choose_card()
- }
- }
-}
-
-states.stasi_confirm = {
- inactive: 'choose next card due to Stasi.',
- prompt() {
- if (game.stasi_card === 21 ) {
- view.prompt = `If Common European Home selected, it must be played for Operations. Otherwise select the opponent's card instead.`
- gen_action('done')
- }
- },
- done() {
- game.playable_cards = game.playable_cards.filter( n => n !== 21)
- end_stasi_choose_card()
- }
-}
-
-states.stasi_play_card = {
- inactive: 'play a card.',
- prompt () { /*Should get rid of the play card 'done' prompt for consistency with general play */
- /*if (game.played_card > 0) {
- game.state = 'play_card'
- view.prompt = 'Play card: done.'
- gen_action("done");
- return;*/
- //} else
- if (game.stasi_card === 0) {
- view.prompt = 'Stasi: you must pass.'
- gen_action('pass')
- } else {
- view.prompt = `Stasi: you must play ${clean_name(cards[game.stasi_card].name)}.`
- /*let available_cards = [game.stasi_card]
- for (let card of available_cards) {
- gen_action_card(card)
- }*/
- let available_cards = [game.stasi_card]
-
- for (let card of available_cards) {
-
- if (scoring_cards.includes(card)) {
- /*view.prompt = 'Play for:'*/
- gen_action('card_event', card)
- return
- }
-
- //Check if Player has Common European Home in hand
- if (game.active === DEM) {
- if (game.democrat_hand.includes(21) && cards[card].side === "C" && card !== 21) {
- gen_action('card_ceh', card)
- }
- } else {
- if (game.communist_hand.includes(21) && cards[card].side === "D" && card !== 21) {
- gen_action('card_ceh', card)
- }
- }
-
- //Check for Tiananmen Square Track awards special abilities
- if ((game.active === DEM && cards[card].side !== 'C' && game.dem_tst_position >= 8 && game.com_tst_position < 8 && !game.tst_8) || (game.active === COM && cards[card].side !== 'D' && game.com_tst_position >= 8 && game.dem_tst_position < 8 && !game.tst_8)){
- gen_action('card_tst_8', card)
- }
-
- // Check for Reformer Rehabilitated
-
- //console.log('game.active', game.active, 'game.playable_cards[67].playable', game.playable_cards[67].playable)
-
-
- if (card === 67 && game.playable_cards.includes(67)){
- if (game.active === DEM && (game.dem_tst_position > game.com_tst_position)) {
- gen_action('card_event', card)
- }
- if (game.active === COM && (game.dem_tst_position < game.com_tst_position)) {
- gen_action('card_event', card)
- }
- }
-
- //Continue with normal logic
-
- //Check if it is a card with an event which is always playable. May not play Common European Home for event in Stasi
-
- if (cards[card].playable && card !== 21) {
- console.log('get events called normally for card', card)
- get_events(card)
- }
-
- // Resolve cards with variable events (not Reformer, not Common European Home in Stasi)
-
- if (card !== 67 && card !== 21 && game.playable_cards.includes(card)) {
- console.log('get events called variable for card', card)
- get_events(card)
- } /*
- if ((game.active === DEM && cards[game.played_card].side === 'D' && game.playable_cards[game.played_card].playable === 1) || (game.active === COM && cards[game.played_card].side === 'C' && game.playable_cards[game.played_card].playable ===1) || (cards[game.played_card].side === 'N'&& game.playable_cards[game.played_card].playable ===1)) {
- gen_action('event')
- } else if ((game.active === DEM && (cards[game.played_card].side === 'C' && game.playable_cards[game.played_card].playable ===1)) || game.active === COM && (cards[game.played_card].side === 'D' && game.playable_cards[game.played_card].playable ===1)) {
- gen_action('opp_event')
- } */
-
- gen_action('card_influence', card)
- if (game.active === DEM && game.dem_tst_attempted_this_turn === 0 && game.dem_tst_position <=8 || game.active === COM && game.com_tst_attempted_this_turn === 0 && game.com_tst_position <= 8) {
- gen_action('card_tst', card)
- }
- gen_action('card_support_check', card)
- }
- }
- },
- card(card) {
- push_undo()
- log_msg_gap(`Stasi: played C${card}`)
- game.played_card = card
- let find_card
- find_card = game.democrat_hand.indexOf(card);
- game.democrat_hand.splice(find_card, 1);
- game.available_ops = get_card_ops(card)
-
- game.stasi_card = 0
- if (game.democrat_hand.includes(21)) {
- game.state = 'stasi_resolve_common_european_home'
- } else {
- game.state = 'play_card'
- }
-
- },
- pass () {
- log('No cards remaining. Passed')
- end_round()
- },
- card_ceh(card) {
- push_undo()
- select_card(card)
- game.stasi_card = 0
- log(`${clean_name(cards[game.played_card].name)} played with Common European Home`)
- //silent_discard(21)
- game.vm_infl_to_do = true
- game.vm_event_to_do = false
- game.state = 'resolve_opponent_event'
- },
-
- card_event(card) {
- push_undo()
- select_card(card)
- game.stasi_card = 0
- console.log('played event, game.active', game.active, 'game.view_opp_hand', game.view_opp_hand)
- log_gap(`Played C${cards[game.played_card].number} for the event`)
- if (scoring_cards.includes(game.played_card)) {game.phase = 0}
- else {game.phase = 1}
- game.return = game.active
- if (switch_events.includes(game.played_card)) {next_player()}
- game.vm_event = game.played_card
- goto_vm(game.vm_event)
- },
- card_opp_event(card) {
- push_undo()
- select_card(card)
- game.stasi_card = 0
- log_gap(`Played C${cards[game.played_card].number} for the event`)
- game.phase = 1 /*Do I still need this?*/
- game.vm_infl_to_do = true
- game.return = game.active
- game.vm_event = game.played_card
- if (auto_resolve_events.includes(game.played_card) || switch_events.includes(game.played_card)) {
- goto_vm(game.vm_event)}
- else {
- next_player()
- log(`C${game.vm_event}`)
- goto_vm(game.vm_event)
- }
- },
- card_influence(card) {
- push_undo()
- select_card(card)
- game.stasi_card = 0
- log_gap(`Played C${cards[game.played_card].number} to place SPs`)
-
-
- // Check if Common European Home played for influence
- if (game.played_card === 21) {
- if (game.active === DEM) {
- game.vp --
- log('-1 VP')
- if (check_vp()) {
- return
- }
- } else {
- game.vp ++
- log('+1 VP')
- if (check_vp()) {
- return
- }
- }
- }
- // Check if card is opponent card with event that needs to be resolved
-
- if (cards[game.played_card].playable || game.playable_cards.includes(game.played_card)) {
- if ((game.active === DEM && cards[game.played_card].side === "C" ) || (game.active === COM && cards[game.played_card].side === "D")) {
- //game.phase = 1 /*Do I need this? */
- game.vm_event_to_do = true
- }
- }
-
- // If ABHR - Set AHBR tracker to true
- if (game.persistent_events.includes(58)) {
- game.austria_hungary_border_reopened_tracker = true
- }
- game.state='add_influence'
- valid_spaces_infl()
- },
- card_tst(card) {
- push_undo()
- select_card(card)
- game.stasi_card = 0
- log_gap(`Played C${cards[game.played_card].number} to the Tiananmen Square Track`)
- game.state='tiananmen_square_attempt'
- },
- card_support_check(card) {
- push_undo()
- select_card(card)
- log_gap(`Played C${cards[game.played_card].number} for support checks`)
-
- // Check if card is opponent card with event that needs to be resolved
- /*if (game.phase === 0 && game.active === DEM && cards[game.played_card].side === "C" && game.playable_cards[game.played_card].playable === 1 || game.phase === 0 && game.active === COM && cards[game.played_card].side === "D" && game.playable_cards[game.played_card].playable === 1 ) {
- game.vm_event_to_do = true
- }*/
-
- if (cards[game.played_card].playable || game.playable_cards.includes(game.played_card)) {
- if ((game.active === DEM && cards[game.played_card].side === "C" ) || (game.active === COM && cards[game.played_card].side === "D")) {
- game.vm_event_to_do = true
- }
- }
-
- game.available_ops = 2
- game.state='support_check_prep'
- valid_spaces_sc()
- },
- card_tst_8(card) { /*Play card for ops and event */
- select_card(card)
- game.vm_event_to_do = true
- game.vm_infl_to_do = true
- game.tst_8 = true
- game.state = 'vm_tst_8'
- },
- done () {
- game.stasi_card = 0
- if (game.democrat_hand.includes(21)) {
- game.state = 'stasi_resolve_common_european_home'
- } else {
- game.state = 'play_card'
- }
- }
-}
-
-states.stasi_resolve_common_european_home = {
- inactive: 'play a card.',
- prompt () {
- view.prompt = `Do you wish to play ${clean_name(cards[game.played_card].name)} with Common European Home?`
- gen_action('yes')
- gen_action('no')
- },
- yes() {
- log(`${clean_name(cards[game.played_card].name)}} played with Common European Home`)
- silent_discard(21)
- game.vm_infl_to_do = true
- game.vm_event_to_do = false
- game.state = 'resolve_opponent_event'
- },
- no() {
- game.state = 'play_card'
- }
-}
-
-
-// ==================== SUPPORTING STATE FUNCTIONS =============================
-
-
-function add_infl(space) {
- push_undo()
- console.log('adding infl to', space)
- const clicked_space = find_space_index(space)
- console.log('clicked_space', clicked_space)
- //console.log('at start, event', game.persistent_events['austria_hungary_border_reopened'], 'ahbr', game.austria_hungary_border_reopened, 'tracker', game.austria_hungary_border_reopened_tracker)
- //log(`Added 1 influence in %${clicked_space}`)
- log_summary(`Added £ SP in %${clicked_space}`)
-
- //If AHBR - check AHBR conditions
- if (game.persistent_events.includes(58)) {
- if (spaces[clicked_space].country !== 'East_Germany'){
- game.austria_hungary_border_reopened_tracker = false
- }
- }
-
- // Check Genscher
- if (game.persistent_events.includes(63) && game.active === DEM && spaces[clicked_space].country === 'East_Germany') {
- game.available_ops--
- log_summary(`(-1 op due to C63)`)
- } else if (check_opp_control(clicked_space)) {
- game.available_ops -= 2
- //Check if Austria Hungary Border Reopened was used to place last SP in a controlled space in East Germany. If so, game.available_op will be negative
- if (game.available_ops < 0) {
- log_summary(`(Used +1 op from C58)`)
- }
- } else {
- game.available_ops--
- }
-
- // Update influence values
- if (game.active === COM) {
- game.comInfl[clicked_space]++
- } else {
- game.demInfl[clicked_space]++
- }
-
- // Check whether spaces are controlled
- check_control_change(clicked_space)
-
- // Check Austria Hungary Border Reopened is true and condition has been met
- if (game.available_ops === 0 && game.active === DEM && game.persistent_events.includes(58) && game.austria_hungary_border_reopened_tracker) {
- game.available_ops ++
- log('+1 op from C58')
- game.austria_hungary_border_reopened_tracker = false
- game.valid_spaces = game.valid_spaces.filter(n => spaces[n].country === 'East_Germany')
- }
-
- // If only 1 IP remaining, may not place in opponent controlled spaces
-
- // Check for Genscher & Austria Hungary Border Reopened
-
- if (game.available_ops === 1) {
- //console.log(`in Genscher / AHBR check, game.persistent_events['genscher']`, game.persistent_events['genscher'])
- if (game.active === DEM) {
- if (game.persistent_events.includes(63) || (game.persistent_events.includes(58) && game.austria_hungary_border_reopened_tracker)) {
- console.log('in gensher subcheck - remove non-East German controlled ')
- game.valid_spaces = game.valid_spaces.filter(n => !(check_opp_control(n) && spaces[n].country !== 'East_Germany'))
- } else {
- console.log('remove all controlled spaces')
- game.valid_spaces = game.valid_spaces.filter(n => !check_opp_control(n))
- }
- } else {
- console.log('remove all dem controlled spaces')
- game.valid_spaces = game.valid_spaces.filter(n => !check_opp_control(n))
- }
- }
-
- //Clear valid spaces if no IP remaining.
- if (game.available_ops <= 0 ) {
- game.valid_spaces = []
- }
-}
-
-function remove_infl(space) {
- push_undo()
- const clicked_space = find_space_index(space)
- //log(`Removed 1 influence from %${clicked_space}.`)
- log_summary(`Removed £ SP from %${clicked_space}.`)
-
- if (game.remove_opponent_infl === true) {
- if (game.active === COM) {
- game.demInfl[clicked_space]--
- if (game.demInfl[clicked_space] === 0) {
- game.valid_spaces = game.valid_spaces.filter(id => id !== clicked_space);
- }
- } else {
- game.comInfl[clicked_space]--
- if (game.comInfl[clicked_space] === 0) {
- game.valid_spaces = game.valid_spaces.filter(id => id !== clicked_space);
- }
- }
- check_control_change(clicked_space)
-
- } else {
- if (game.active === COM) {
- game.comInfl[clicked_space]--
- if (game.comInfl[clicked_space] === 0) {
- game.valid_spaces = game.valid_spaces.filter(id => id !== clicked_space);
- }
- } else {
- game.demInfl[clicked_space]--
- if (game.demInfl[clicked_space] === 0) {
- game.valid_spaces = game.valid_spaces.filter(id => id !== clicked_space);
- }
- }
- check_control_change(clicked_space)
- }
- game.available_ops--
-}
-
-function do_sc(space) {
- clear_undo()
- let clicked_space = find_space_index(space)
- log_gap(`Support check: %${clicked_space}`)
-
- //Check Helsinki Final Act
-
- if (game.active === COM && game.persistent_events.includes(26) && (spaces[clicked_space].socio === 5 || spaces[clicked_space].socio === 6) ) {
- log('+1 VP from C26')
- game.vp ++
- if (check_vp()) {
- game.state = 'game.over'
- console.log('after check_vp, game.state', game.state)
- return
- }
- }
- console.log('continue support check, game.state', game.state)
- // Continue with Support Check Logic
-
- let roll = Math.floor(Math.random() * 6) + 1
- log(`Rolled a ${roll}`)
- console.log('game.vm_event', game.vm_event)
- console.log('game.is_pwr_struggle', game.is_pwr_struggle)
- /*
- //Check if support check is being done with game.played_card or a subsequent card (e.g. Common European Home, Dash for the West, etc)
- if (game.vm_event > 0) {
- roll+= cards[game.vm_event].ops
- log(`+${cards[game.vm_event].ops} from card ops`)
- }
- */
- // Check for the Crowd Turns Against Ceausescu
-
- //else
- if (game.is_pwr_struggle) {
- roll += game.vm_available_ops
- log(`+${game.vm_available_ops} from Ceausescu`)
- }
-
- // Check if in Tiananmen Square Track Award
-
- else if (game.state === 'vm_tst_6_sc') {
- roll += get_tst_6_ops()
- roll += 2
- log('+2 from Tiananmen Square Track award')
- }
- else {
- //let modifier = 0
- let card_ops = get_card_ops(this_card())
-
- roll += card_ops
- log(`+${card_ops} from card ops`)
- }
-
- if (game.support_check_modifier > 0) {
- roll += game.support_check_modifier
- log(`+${game.support_check_modifier} from event`)
- }
-
- // Events which modify SC rolls
- //Tear Gas
- if (game.active === COM && game.persistent_events.includes(30) && spaces[clicked_space].socio === 6) {
- roll ++
- log('+1 from C30')
- permanently_remove(30)
- game.persistent_events = game.persistent_events.filter(n => n !== 30)
- }
- //FRG Embassies
- if (game.active === DEM && spaces[clicked_space].region === 'Eastern Europe' && game.persistent_events.includes(74)) {
- roll++
- log('+1 from C74')
- }
- //GrenzTruppen
- if (game.active === DEM && spaces[clicked_space].country === 'East_Germany' && game.persistent_events.includes(59)) {
- roll--
- log('-1 from C59')
- }
- //Stand Fast
- if ((game.active === COM && game.stand_fast === DEM && check_dem_control(clicked_space)) || (game.active === DEM && game.stand_fast === COM && check_com_control(clicked_space))){
- roll--
- log('-1 from C100')
- }
- //Elena
- if (game.active === DEM && game.persistent_events.includes(101) && spaces[clicked_space].country === 'Romania') {
- roll--
- log('-1 from C101')
- }
- //Austria Hungary Border Reopened
- if (game.active === DEM && game.persistent_events.includes(58) && game.austria_hungary_border_reopened_tracker) {
- roll++
- log(`+1 from C58`)
- }
-
- // Continue with logic - check for adjacency
-
- // Events which affect adjacency - The Wall
-
- const adj = count_adj(space)
- console.log('adj', adj)
- if (game.active === COM && game.persistent_events.includes(9) && spaces[clicked_space].country === 'East_Germany') {
- log('No adjacency for Democrats due to C9')
- log('C9 no longer in effect')
- roll += adj.com_adj
- if (adj.com_adj > 0) {
- log(`+${adj.com_adj} from adjacent control`)
- }
- game.persistent_events = game.persistent_events.filter(n => n !== 9)
-
- // Standard adjacency
- } else {
- if (adj.dem_adj > 0 || adj.com_adj > 0 ){
- if (game.active === DEM) {
- roll += adj.dem_adj
- roll -= adj.com_adj
- if (adj.dem_adj > 0) {
- log(`+${adj.dem_adj} from adjacent control`)
- }
- if (adj.com_adj > 0) {
- log(`-${adj.com_adj} from adjacent opponent control`)
- }
- } else {
- roll += adj.com_adj
- roll -= adj.dem_adj
- if (adj.com_adj > 0) {
- log(`+${adj.com_adj} from adjacent control`)
- }
- if (adj.dem_adj > 0) {
- log(`-${adj.dem_adj} from adjacent opponent control`)
- }
- }
- }
-
- }
-
- // Support check calcs
- log(`Total support check strength: ${roll}`)
- const stability = spaces[find_space_index(space)].stability
- log(`Stability is ${stability}. Defence is ${stability*2}`)
- const change_infl = Math.max(0, roll - stability*2)
- if (change_infl > 0) {
- log_msg_gap(`${change_infl} point swing`)
- let clicked_space = find_space_index(space)
- if(game.active === DEM) {
- if (change_infl > game.comInfl[clicked_space]) {
- const residual = change_infl - game.comInfl[clicked_space]
- game.comInfl[clicked_space] = 0
- game.demInfl[clicked_space] += residual
- } else {
- game.comInfl[clicked_space] -= change_infl
- }
- if (game.comInfl[clicked_space] === 0) {
- game.valid_spaces = game.valid_spaces.filter(id => id !== clicked_space)
- }
- } else {
- if (change_infl > game.demInfl[clicked_space]) {
- const residual = change_infl - game.demInfl[clicked_space]
- game.demInfl[clicked_space] = 0
- game.comInfl[clicked_space] += residual
- } else {
- game.demInfl[clicked_space] -= change_infl
- }
- if (game.demInfl[clicked_space] === 0) {
- game.valid_spaces = game.valid_spaces.filter(id => id !== clicked_space)
- }
- }
- check_control_change(clicked_space)
-
- } else {
- log_msg_gap('No change in influence')
- }
- if (game.active === COM && game.persistent_events.includes(39) && spaces[clicked_space].space_id === 66) {
- log_msg_gap('+1 VP from C39')
- game.vp++
- if (check_vp()) {
- return
- }
- }
-
- // If Austria-Hungary Border Reopened used, all future support checks must be in East Germany
- if (game.persistent_events.includes(58)){
- if (game.austria_hungary_border_reopened_tracker) {
- game.valid_spaces = game.valid_spaces.filter(n => spaces[n].country === 'East_Germany')
- }
- }
- game.selected_space = 0
-
-}
-
-
-function valid_spaces_setup() {
- game.valid_spaces = []
- let valid_spaces_set = new Set();
- console.log('in vs setup, state', game.state)
- for (let i =1 ; i < 75 ; i++) {
- space = spaces[i]
-
- if (game.state === 'com_init') {
- infl = game.demInfl[i]
-
- if (infl === 0) {
- valid_spaces_set.add(space.space_id);
- }
- } else if (game.state === 'dem_init') {
- infl = game.comInfl[i]
- if (infl === 0) {
- valid_spaces_set.add(space.space_id);
- }
- }
- }
- // Convert the set to an array before returning
- game.valid_spaces = Array.from(valid_spaces_set);
- return game.valid_spaces;
-}
-
-function valid_spaces_sc() {
- let valid_spaces_set = new Set();
- console.log('valid spaces sc, persistent events', game.persistent_events)
-
- for (let i = 1 ; i < 75; i++) {
- space = spaces[i]
-
- if (game.active === DEM) {
- infl = game.comInfl[i]
- if (infl !== 0 ) {
- valid_spaces_set.add(space.space_id);
- }
- } else {
- infl = game.demInfl[i]
- if (infl !== 0 ) {
- // Check Solidarity Legalised
- if (game.persistent_events.includes(2) && space.space_id === 14) {continue}
-
- // Check Civic Forum
- if (game.persistent_events.includes(90) && space.space_id === 30) {continue}
-
- // Check We Are the People
- if (game.persistent_events.includes(48) && space.space_id === 9) {continue}
-
- //Check for Foreign Currency Debt Burden
- if (game.persistent_events.includes(49) && space.country === game.foreign_currency_debt_burden) {continue} {
-
- valid_spaces_set.add(space.space_id);
-
- }
- }
- }
- }
-
-
- // Convert the set to an array before returning
- game.valid_spaces = Array.from(valid_spaces_set);
-
- //Check for the Crown Turns Against Ceausescu
- if (game.is_pwr_struggle && game.pwr_struggle_in === 'Romania' && game.persistent_events.includes(54)) {
- game.valid_spaces = game.valid_spaces.filter(n => spaces[n].country === 'Romania')
- }
- return game.valid_spaces;
-}
-
-function valid_spaces_support_loss() {
- let valid_spaces_set = new Set();
- for (let i = 1; i < game.demInfl.length; i++) {
- //console.log('spaces.length', game.demInfl.length, 'i', i)
- space = spaces[i]
- if (game.active === DEM) {
- infl = game.demInfl[i]
- if (infl > 0 && space.country === game.pwr_struggle_in) {
- valid_spaces_set.add(space.space_id);
- }
- } else {
- infl = game.comInfl[i]
- if (infl > 0 && space.country === game.pwr_struggle_in) {
- valid_spaces_set.add(space.space_id);
- }
- }
- }
-
- // Convert the set to an array before returning
- game.valid_spaces = Array.from(valid_spaces_set);
- return game.valid_spaces;
-}
-/*
-function valid_spaces_support_falters() {
- let valid_spaces_set = new Set();
- if (game.active === DEM) {
- for (let piece of game.pieces) {
- if (!piece) continue
- let space = spaces.find(s => s && s.space_id === piece.space_id);
- if (space && piece.comInfl > 0 && space.country === game.pwr_struggle_in) {
- valid_spaces_set.add(space.space_id);
- }
- }
- } else {
- for (let piece of game.pieces) {
- if (!piece) continue
- let space = spaces.find(s => s && s.space_id === piece.space_id);
- if (space && piece.demInfl > 0 && space.country === game.pwr_struggle_in) {
- valid_spaces_set.add(space.space_id);
- }
- }
- }
- // Convert the set to an array before returning
- game.valid_spaces = Array.from(valid_spaces_set);
- return game.valid_spaces;
-}
- */
-
-function valid_spaces_infl() {
- /*if (game.state.startsWith('vm')) {
- console.log('valid_spaces_infl called from VM')
- } else {
- console.log('valid_spaces_infl called not from VM')
- }*/
- // Check if function is called from the VM or not, take relevant ops variable
- let ops = game.state.startsWith('vm') ? game.vm_available_ops : game.available_ops;
-
- let valid_spaces_set = new Set();
- // Iterate over all spaces to find the ones with the player's influence
- for (let i = 1; i < game.demInfl.length; i++) {
- //piece = game.pieces[i]
- space = spaces[i]
-
- let player_influence = game.active === COM ? game.comInfl[i] : game.demInfl[i];
-
- // If the piece has the player's influence, add it and its adjacent spaces to the set
- if (player_influence > 0) {
- valid_spaces_set.add(space.space_id);
-
- // Check adjacency information
- let adjacent_spaces = get_adjusted_adjacency(space.space_id)
-
- for (let adj_space_id of adjacent_spaces) {
- //console.log('adj_space_id', adj_space_id)
- if (adj_space_id) {
-
- const adj_piece = spaces[adj_space_id];
- //console.log('adjacent piece name', adj_piece.name_unique)
-
- // Check if the adjacent space is controlled by the opponent
- const opponent_control = check_opp_control(adj_piece.space_id)
- //console.log('controlled?', opponent_control)
-
- //Check for Genscher. Can always place in East Germany even with 1 op
- if (game.active === DEM && adj_piece.country === 'East_Germany' && game.persistent_events.includes(63)){
- // console.log('space added with genscher')
- valid_spaces_set.add(adj_piece.space_id)
- }
-
- // Otherwise, only add the adjacent space if the available_ops >= 2 or the space is not controlled by the opponent
- if (ops >= 2 || !opponent_control) {
- valid_spaces_set.add(adj_piece.space_id)
- }
- }
- }
- }
- }
- // Convert the set to an array before returning
- game.valid_spaces = Array.from(valid_spaces_set);
- return game.valid_spaces;
-}
-
-function valid_cards(player_hand, presence) {
- const valid_cards_set= new Set();
- if (game.phase === 0) {
- for (let c of player_hand) {
- let card = power_cards.find(card => card && card.number === c);
- if (card.number === 52) {continue} // Never add tactics fails
- if (card.name === game.tactics_fails) {continue} //Cannot play the suit of Tactics Fails
- if (card.socio === 0) {
- valid_cards_set.add(card.number);
- } else if (leaders.includes(card.socio) && presence[card.socio]) {
- valid_cards_set.add(card.number);
- }
- }
- } else if (game.phase === 1) {
- for (let c of player_hand) {
- let card = power_cards.find(card => card && card.number === c);
- if (card.name === power_cards[game.played_power_card].name) {
- valid_cards_set.add(card.number);
- } else if (leaders.includes(card.socio) && presence[card.socio]) {
- valid_cards_set.add(card.number);
- } else if (card.number === 52) {valid_cards_set.add(card.number)}
- }
- }
- game.valid_cards = Array.from(valid_cards_set);
- return game.valid_cards;
-}
-
-function do_valid_cards() {
- let presence = check_presence(game.pwr_struggle_in)
- if (game.active === DEM) {
- valid_cards(game.dem_pwr_hand, presence.dem_leaders)
-
- } else {
- valid_cards(game.com_pwr_hand, presence.com_leaders)}
-}
-
-function count_adj(name_unique) {
- const space = spaces[find_space_index(name_unique)]
- let dem_adj = 0
- let com_adj = 0
-
- let adjacent_spaces = get_adjusted_adjacency(space.space_id)
-
- for (let adj_space_id of adjacent_spaces) {
- if (adj_space_id) {
- const adj_piece = spaces.find(piece => piece && piece.space_id === adj_space_id);
- console.log('adj_piece.space_id', adj_piece.space_id, 'space', space)
- if (adj_piece && adj_piece.space_id !== space.space_id) {
- if (check_dem_control(adj_piece.space_id)) {
- console.log('added DEM space', spaces[adj_piece.space_id].name)
- dem_adj++
- }
- if (check_com_control(adj_piece.space_id)) {
- console.log('added COM space', spaces[adj_piece.space_id].name)
- com_adj++
- }
- }
- }
- }
- console.log('dem_adj: ', dem_adj, 'com_adj: ', com_adj)
- return {dem_adj, com_adj}
-}
-
-/*function count_adj_worker(space_id) {
- const space = spaces[space_id]
- let dem_adj = 0
- let com_adj = 0
-
- for (let adj_space_id of space.adjacent) {
- if (adj_space_id) {
- const adj_space = spaces[adj_space_id]
- if (adj_space && adj_space.socio === 4) {
- const adj_piece = game.pieces.find(piece => piece && piece.space_id === adj_space_id );
- if (adj_piece) {
- if (adj_piece.demCtrl === 1 ) {
- dem_adj++
- }
- if (adj_piece.comCtrl === 1 ) {
- com_adj++
- }
- }
- }
- }
- }
- return {dem_adj, com_adj}
-} */
-
-function check_control(space_id) {
- //console.log('in check control, space', spaces[space_id].name_unique)
- if ( (game.comInfl[space_id] - game.demInfl[space_id]) >= spaces[space_id].stability) {
- return true;
- } else if ((game.demInfl[space_id] - game.comInfl[space_id]) >= spaces[space_id].stability) {
- //console.log('true')
- return true;
- } else {
- //console.log('false')
- return false;
- }
-}
-
-function check_opp_control(space_id) {
- if (spaces[space_id].country === 'Romania') {
- //console.log('in check opp control, space', spaces[space_id].name_unique)
- }
- if (game.active === DEM && ((game.comInfl[space_id] - game.demInfl[space_id]) >= spaces[space_id].stability)) {
- if (spaces[space_id].country === 'Romania') {
- //console.log('control true')
- }
- return true;
- } else if (game.active === COM && ((game.demInfl[space_id] - game.comInfl[space_id]) >= spaces[space_id].stability)) {
- //console.log('true')
- return true;
- } else {
- //console.log('false')
- return false;
- }
-}
-
-function check_dem_control(space_id) {
- if ((game.demInfl[space_id] - game.comInfl[space_id]) >= spaces[space_id].stability) {
- return true;
- } else {
- return false;
- }
-}
-
-function check_com_control(space_id) {
- if ((game.comInfl[space_id] - game.demInfl[space_id]) >= spaces[space_id].stability) {
- return true;
- } else {
- return false;
- }
-}
-
-function do_tst_attempt() {
- let roll = Math.floor(Math.random() * 6) + 1;
- log(`Rolled a ${roll}`);
-
- roll += game.available_ops
- log(`+${game.available_ops} from card ops`)
-
- // TIANANMEN SQUARE MODIFIERS
-
- if (game.active === DEM && game.dem_tst_attempted === 1 || game.active === COM && game.com_tst_attempted === 1) {
- roll ++;
- log('+1 modifier from previous Tiananmen Square Track attempts')
- }
- if (game.active === DEM && game.dem_tst_position >= 1 && game.com_tst_position === 0) {
- roll ++
- log('+1 from TST award')
- }
- if (game.active === COM && game.com_tst_position >= 1 && game.dem_tst_position === 0) {
- roll ++
- log('+1 from TST award')
- }
- if ((game.active === DEM && cards[game.played_card].side === 'D') || (game.active === COM && cards[game.played_card].side === 'C')) {
- roll ++;
- log('+1 for playing own card');
- }
- if (game.active === COM && game.persistent_events.includes(53)) {
- roll ++
- log('+1 from C53')
- }
- log(`Modified die roll: ${roll}`)
-
- // TIANANMEN SQUARE ATTEMPT
- game.return = game.active
- game.return_state = 'tiananmen_square_attempt_success'
- if (game.active === DEM) {
- game.dem_tst_attempted_this_turn = 1
- if (roll >= dem_tst_req[game.dem_tst_position]) {
- log(`${dem_tst_req[game.dem_tst_position]} required: success`)
- game.dem_tst_position++
- game.dem_tst_attempted = 0
-
- //Check if they have reached box 7 or 8 first
- if (game.dem_tst_position === 7 && game.com_tst_position < 7) {
- game.tst_7 = false
- }
- if (game.dem_tst_position === 8 && game.com_tst_position < 8) {
- game.tst_8 = false
- }
-
- //Check if they have caught up to box 7 or 8
- if (game.dem_tst_position >= 7 && game.com_tst_position >= 7) {
- delete game.tst_7
- }
- if (game.dem_tst_position >= 8 && game.com_tst_position >= 8) {
- delete game.tst_8
- }
-
- //Check if TST events occur
- if (game.dem_tst_position === 3 && game.com_tst_position < 3) {goto_vm(203)}
- else if (game.dem_tst_position === 4 && game.com_tst_position < 4) {goto_vm(204)}
- else {game.state = 'tiananmen_square_attempt_success'}
- } else {
- log(`${dem_tst_req[game.dem_tst_position]} required: fail`)
- game.dem_tst_attempted = 1
- game.state = 'tiananmen_square_attempt_fail'
- }
- } else {
- game.com_tst_attempted_this_turn = 1
- if (roll >= com_tst_req[game.com_tst_position]) {
- log(`${com_tst_req[game.com_tst_position]} required: success`)
- game.com_tst_position++
- game.com_tst_attempted = 0
-
- //Check if they have reached box 7 or 8 first
- if (game.dem_tst_position === 7 && game.com_tst_position < 7) {
- game.tst_7 = false
- }
- if (game.dem_tst_position === 8 && game.com_tst_position < 8) {
- game.tst_8 = false
- }
-
- //Check if they have caught up to box 7 or 8
- if (game.dem_tst_position >= 7 && game.com_tst_position >= 7) {
- delete game.tst_7
- }
- if (game.dem_tst_position >= 8 && game.com_tst_position >= 8) {
- delete game.tst_8
- }
-
- //Check if TST events occur
- if (game.com_tst_position === 3 && game.dem_tst_position < 3) {goto_vm(203)}
- else if (game.com_tst_position === 4 && game.dem_tst_position < 4) {goto_vm(204)}
- else {game.state = 'tiananmen_square_attempt_success'}
- } else {
- log(`${com_tst_req[game.com_tst_position]} required: fail`)
- game.com_tst_attempted = 1
- game.state = 'tiananmen_square_attempt_fail'
- }
- }
-}
-
-function check_presence(country) {
-
- let dem_spaces = 0;
- let com_spaces = 0;
- let dem_battlegrounds = 0;
- let com_battlegrounds = 0;
- let dem_leaders = {1: false, 4: false, 5: false, 6: false, 7: false};
- let com_leaders = {1: false, 4: false, 5: false, 6: false, 7: false};
-
-
- for (let i = 1; i < spaces.length; i++) {
- let space = spaces[i]
- if (space.country === country) {
-
- if (check_dem_control(i)) {
- dem_spaces++;
- if (space.battleground === 1) {
- dem_battlegrounds++;
- }
- if (leaders.includes(space.socio)) {
- dem_leaders[space.socio] = true;
- }
- }
- if (check_com_control(i)) {
- com_spaces++;
- if (space.battleground === 1) {
- com_battlegrounds++;
- }
- if (leaders.includes(space.socio)) {
- com_leaders[space.socio] = true;
- }
- }
- }
- }
-
- // Determine domination
- let dem_domination = dem_battlegrounds > com_battlegrounds && dem_spaces > com_spaces && dem_spaces - dem_battlegrounds > 0;
- let com_domination = com_battlegrounds > dem_battlegrounds && com_spaces > dem_spaces && com_spaces - com_battlegrounds > 0;
-
- // Determine control
- let total_battlegrounds = battlegrounds(country);
- let dem_control = dem_battlegrounds === total_battlegrounds && dem_spaces > com_spaces;
- let com_control = com_battlegrounds === total_battlegrounds && com_spaces > dem_spaces;
-
- return {
- dem_spaces: dem_spaces,
- com_spaces: com_spaces,
- dem_battlegrounds: dem_battlegrounds,
- com_battlegrounds: com_battlegrounds,
- dem_domination: dem_domination,
- com_domination: com_domination,
- dem_control: dem_control,
- com_control: com_control,
- dem_leaders: dem_leaders,
- com_leaders: com_leaders
- };
-}
-
-function battlegrounds(country) {
- let battlegrounds = 0;
- if (country === "Hungary") {
- battlegrounds = 4
- } else if (country === "Bulgaria") {
- battlegrounds = 5
- } else {
- battlegrounds = 6
- }
- return battlegrounds;
-}
-
-function take_power(country) {
-
- log(`Democrat takes power in ${game.pwr_struggle_in}`)
- game.revolutions[find_country_index(country)] = true
- game.times_held[find_country_index(country)] = 1
-
-}
-
-function retain_power(country){
- game.times_held[find_country_index(country)]++
- let vp_gain = get_value(country)*game.times_held[find_country_index(country)]
- log(`Chooses to retain power`)
- log(`-${vp_gain} VP`)
- game.vp -= vp_gain
-}
-
-function score_country(country) {
- log_h3(`Scoring: ${country}`)
-
-//Get scoring values
- let value_presence = get_value(country)
- let value_domination = value_presence*2
- let value_control
- if (country !== "Hungary") {
- value_control = value_presence*3
- } else {
- value_control = 4
- }
-//Log for scoring
-
- let dem_vp = 0
- let com_vp = 0
- //Check for presence
- let presence = check_presence(country)
- console.log('presence: ', presence)
-
- //If one side has domination or control
- if (presence.dem_control || presence.dem_domination) {
- log(`Democrat:`)
- if (presence.dem_control) {
- log(`Control: +${value_control} VP`)
- dem_vp += value_control
- }
- else {
- log(`Domination: +${value_domination} VP`)
- dem_vp += value_domination
- }
- log(`Battlegrounds: +${presence.dem_battlegrounds} VP`)
- dem_vp += presence.dem_battlegrounds
- log(`Total: +${dem_vp} VP`)
-
- log_gap('Communist:')
- if (presence.com_spaces > 0) {
- log(`Presence: -${value_presence} VP`)
- com_vp -= value_presence
- if (presence.com_battlegrounds >0) {
- log(`Battlegrounds: -${presence.com_battlegrounds} VP`)
- com_vp -= presence.com_battlegrounds
- }
- log(`Total: ${com_vp} VP`)
- } else {
- log('No presence: 0 VP')
- }
-
- }
- else if (presence.com_control || presence.com_domination) {
- log('Communist:')
- if (presence.com_control) {
- log(`Control: -${value_control} VP`)
- com_vp -= value_control
- }
- else {
- log(`Domination: -${value_domination} VP`)
- com_vp -= value_domination
- }
- log(`Battlegrounds: -${presence.com_battlegrounds} VP`)
- com_vp -= presence.com_battlegrounds
- log(`Total: ${com_vp} VP`)
-
- log_gap('Democrat:')
- if (presence.dem_spaces > 0) {
- log(`Presence: +${value_presence} VP`)
- dem_vp += value_presence
- if (presence.dem_battlegrounds > 0) {
- log(`Battlegrounds: +${presence.dem_battlegrounds} VP`)
- dem_vp += presence.dem_battlegrounds
- }
- log (`Total: +${dem_vp} VP`)
- } else {
- log('No presence: 0 VP')
- }
-
- }
-
- //Otherwise, presence and battlegrounds
- else {
- log("No domination or control")
- log_gap(`Communist:`)
- if (presence.com_spaces > 0) {
- log(`Presence: -${value_presence} VP`)
- com_vp -= value_presence
- if (presence.com_battlegrounds > 0) {
- log(`Battlegrounds: -${presence.com_battlegrounds} VP`)
- com_vp -= presence.com_battlegrounds
- } else {
- log('No battlegrounds')
- }
- log(`Total: ${com_vp} VP`)
- } else {
- log('No presence: 0 VP')
- }
- log_gap('Democrat:')
- if (presence.dem_spaces > 0) {
- log(`Presence: +${value_presence} VP`)
- dem_vp += value_presence
- if (presence.dem_battlegrounds > 0) {
- log(`Battlegrounds: +${presence.dem_battlegrounds} VP`)
- dem_vp += presence.dem_battlegrounds
- } else {
- log('No battlegrounds')
- }
- log(`Total: +${dem_vp} VP`)
- } else {
- log('No presence: 0 VP')
- }
- }
-
-
-//Calculate change VP
- /*let dem_vp = 0
- if (presence.dem_spaces > 0) {dem_vp += value_presence}
- if (presence.dem_domination) {dem_vp += value_presence}
- if (presence.dem_control && country !== "Hungary") {
- dem_vp += value_control
- }
- else if (presence.dem_control && country === "Hungary") {dem_vp += 2}
- dem_vp += presence.dem_battlegrounds
-
- let com_vp = 0
- if (presence.com_spaces > 0) {com_vp += value_presence}
- if (presence.com_domination) {com_vp += value_presence}
- if (presence.com_control && country !== "Hungary") {com_vp += value_presence}
- else if (presence.com_control && country === "Hungary") {com_vp += 2}
- com_vp += presence.com_battlegrounds */
- let change_vp = dem_vp + com_vp
- game.vp += change_vp
- if (change_vp > 0 ) {
- log_gap(`Final change VP: +${change_vp} VP`)
- } else {
- log_gap(`Final change VP: ${change_vp} VP`)
- }
-}
-
-function get_value(country) {
- let value
- if (country === "East_Germany" || country === "Poland") {value = 3}
- else if (country === "Czechoslovakia" || country === "Romania") {value = 2}
- else value = 1
- return value
-}
-
-function permanently_remove(card) {
- console.log('card:', card)
- log_msg_gap(`C${cards[card].number} permanently removed`)
- remove_from_discard(card)
-
- /*let card_index = game.strategy_discard.indexOf(card)
- if (card_index !== -1) {
- console.log('sub 1 called')
- game.strategy_discard.splice(card_index, 1)
- }*/
- card_index = game.table_cards.indexOf(card)
- if (card_index !== -1) {
- console.log('sub 2 called')
- game.table_cards.splice(card_index, 1)
- }
- game.strategy_removed.push(card)
- console.log('game.strategy_removed', game.strategy_removed)
-}
-
-function check_vp() {
- if (game.vp >= 20) {
- goto_game_over(DEM, `${DEM} won an Automatic Victory!`)
- console.log('after goto_game_over, game.state', game.state)
- return true
- } else if(game.vp <= -20) {
- goto_game_over(COM, `${COM} won an Automatic Victory!`)
- return true
- }
- return false
-}
-
-function game_over() {
- if (game.vp >= 20 || game.vp <= -20) {
- return true
- } else { return false}
-}
-
-function goto_game_over(result, victory) {
- game.state = "game_over"
- game.active = "None"
- game.result = result
- game.victory = victory
- log_h1("Game Over")
- log(game.victory)
- console.log('game over, game.state', game.state)
- return
-
-}
-
-function reset_austria_hungary_border_reopened() {
- //game.austria_hungary_border_reopened_checked = false
- game.austria_hungary_border_reopened_tracker = false
-}
-
-function end_stasi_choose_card() {
- game.round_player = COM
- game.round ++
- log_h2(`Action Round ${game.round}`)
- next_player()
- game.valid_spaces = []
- if (game.persistent_events.includes(5)) {
- log_h3('C5')
- game.state = 'general_strike'
- } else {
- game.state = 'choose_card'
- }
-}
-
-function check_reformer() {
- if (game.dem_tst_position !== game.com_tst_position) {
- if (!game.playable_cards.includes(67)) {
- game.playable_cards.push(67)
- }
- } else {
- game.playable_cards = game.playable_cards.filter(n => n !== 67)
- }
-
-}
-
-function count_scoring_cards() {
- let scoring_check
- if (game.active === DEM) {
- scoring_check = game.democrat_hand.filter(card => scoring_cards.includes(card)).length
- } else {
- scoring_check = game.communist_hand.filter(card => scoring_cards.includes(card)).length
- }
- return scoring_check
-}
-
-function select_card(card){
- game.played_card = card
- game.temp = 0
- let find_card
- if (game.active === COM) {
- find_card = game.communist_hand.indexOf(card)
- game.communist_hand.splice(find_card, 1)
- } else {
- find_card = game.democrat_hand.indexOf(card)
- game.democrat_hand.splice(find_card, 1)
- }
- game.available_ops = get_card_ops(card)
-
- //Check Ligachev
- if (game.active === DEM && game.persistent_events.includes(99) && card !== 14) {
- log('-3 VP from C99')
- game.vp -= 3
- if (check_vp()) {
- return
- }
- game.persistent_events = game.persistent_events.filter(n => n !== 99)
- }
- game.state = 'play_card'
- console.log('game.state', game.state)
-}
-
-function find_event(card) {
- return variable_events.indexOf(card)
-}
-
-function get_events(card){
- if (cards[card].side === 'D') {
- if (game.active === DEM) {gen_action('card_event', card)}
- if (game.active === COM) {gen_action('card_opp_event', card)}
- }
- else if (cards[card].side === 'C') {
- if (game.active === COM) {gen_action('card_event', card)}
- if (game.active === DEM) {gen_action('card_opp_event', card)}
- } else {
- gen_action('card_event', card)
- }
-}
-
-function get_card_ops(card) {
- let ops = 0
-
- if (card) {
- ops = cards[card].ops
- }
- if (game.persistent_events.includes(25) && game.active === COM) {
- if(game.state === 'choose_card' || game.state === 'stasi_play_card') {
- log('+1 op from C25')
- }
- ops ++
- }
- if (game.persistent_events.includes(50) && game.active === DEM) {
- if(game.state === 'choose_card' || game.state === 'stasi_play_card' || game.state === 'vm_laszlo_tokes') {
- log('+1 op from C50')
- }
- ops ++
- }
-
- if ((game.active === DEM && game.dem_tst_position >= 2 && game.com_tst_position <= 1 && cards[card].ops === 1) || (game.active === COM && game.com_tst_position >=2 && game.dem_tst_position <= 1 && cards[card].ops === 1)) {
- if(game.state === 'choose_card' || game.state === 'stasi_play_card') {
- log('+1 op from Tiananmen Square Track')
- }
- ops ++
- }
-
- if ((game.active === DEM && game.prudence && game.prudence.DEM !== 0)) {
- if(game.state === 'choose_card' || game.state === 'stasi_play_card' || game.state === 'vm_laszlo_tokes') {
- if (ops > 2) {
- log(`${pluralize(game.prudence.DEM,'op')} from C8`)
- } else {
- if (ops > 1) {
- log(`-1 op from C8`)
- }
- }
- }
- ops += game.prudence.DEM
-
- if (ops < 1) {
- ops = 1
- }
- }
-
- if (game.active === COM && game.prudence && game.prudence.COM < 0) {
- if(game.state === 'choose_card') {
- if (ops > 2) {
- log(`${pluralize(game.prudence.COM,'op')} from C8`)
- } else if (ops > 1) {
- log(`-1 op from C8`)
- }
- }
- ops += game.prudence.COM
- if (ops < 1) {
- ops = 1
- }
- } return ops
-}
-
-function get_tst_6_ops() {
- let ops = 0
-
- if (game.persistent_events.includes(25) && game.active === COM) {
- log('+1 op from C25')
- ops ++
- }
- if (game.persistent_events.includes(50) && game.active === DEM) {
- log('+1 op from C50')
- ops ++
- }
-
- if ((game.active === DEM && game.prudence && game.prudence.DEM !== 0)) {
- if (ops > 0) {
- log(`${pluralize(game.prudence.DEM,'op')} from C8`)
- } else {
- log(`-1 op from C8`)
- }
-
- ops += game.prudence.DEM
-
- if (ops < -1) {
- ops = -1
- }
- }
-
- if (game.active === COM && game.prudence && game.prudence.COM < 0) {
-
- if (ops > 0) {
- log(`${pluralize(game.prudence.COM,'op')} from C8`)
- } else {
- log(`-1 op from C8`)
- }
-
- ops += game.prudence.COM
- if (ops < -1) {
- ops = -1
- }
- }
- return ops
-}
-
-
-// =========== MOVING THROUGH TURNS ============
-
-function end_round() {
- //Check if the game is over!
- if (game.state === 'game_over') {
- console.log('in end')
- return}
-
- //Check if the card has been removed or played to table, and if a card has been not been played. If not, discard.
- if (!game.strategy_removed.includes(game.played_card) && !game.table_cards.includes(game.played_card) && game.played_card > 0) {
- game.strategy_discard.push(game.played_card)
- }
-
- //Reset
- game.played_card = 0
- game.temp = 0
- game.vm_event = 0
- game.phase = 0
- game.remove_opponent_infl = false
- game.is_pwr_struggle = false
- game.vm_infl_to_do = false /*Can get rid of this and use game.return_state? */
- game.vm_event_to_do = false
- game.vm_active_country = ''
- game.return_state = ''
- game.discard = false
- game.return = ''
- game.valid_cards = []
- game.valid_spaces = []
- check_common_european_home()
- //game.playable_cards[find_event(21)] = true
- reset_austria_hungary_border_reopened() /*This should be redundant! */
-
-
- // Check for duplicate card entries
- let card_check
- if (game.samizdat_card > 0) {
- card_check = [...game.strategy_deck, ...game.strategy_discard, ...game.strategy_removed, ...game.table_cards, ...game.communist_hand, ... game.democrat_hand, game.samizdat_card];
- } else {
- card_check = [...game.strategy_deck, ...game.strategy_discard, ...game.strategy_removed, ...game.table_cards, ...game.communist_hand, ... game.democrat_hand];
- }
-
- function check_duplicates(array) {
- return new Set(array).size !== array.length;
- }
-
- function find_duplicates(array) {
- const duplicates = array.filter((item, index) => array.indexOf(item) !== index);
- return [...new Set(duplicates)];
- }
-
- console.log('game.strategy_deck', game.strategy_deck, 'game.strategy_discard', game.strategy_discard, 'game.strategy_removed', game.strategy_removed, 'game.table_cards', game.table_cards, 'game.communist_hand', game.communist_hand, 'game.democrat_hand', game.democrat_hand)
-
- if (check_duplicates(card_check)) {
- const duplicates = find_duplicates(card_check)
- console.log('discard', game.strategy_discard, 'removed', game.strategy_removed, 'game.table_cards', game.table_cards, 'com hand', game.communist_hand, 'dem hand', game.democrat_hand)
- throw new Error(`Duplicate cards detected: ${duplicates.join(', ')}`)
- }
- console.log('cards in game', card_check.length)
- card_check = card_check.sort((a, b) => a - b)
- console.log('cards in game', card_check)
- if (game.turn <= 3) {
- if (card_check.length !== 40) {
- throw new Error(`Wrong number of cards: ${card_check.length}`)
- }
- } else if (game.turn <=7) {
- if (card_check.length !== 81) {
- throw new Error(`Wrong number of cards: ${card_check.length}`)
- }
- } else if (card_check.length !== 110) {
- throw new Error(`Wrong number of cards: ${card_check.length}`)
- }
-
-
-
- console.log('game.dem_tst_position ', game.dem_tst_position , 'game.com_tst_position ', game.com_tst_position )
- //Check if the Reformer is playable
- check_reformer()
-
- // Check if last round and if so resolve end turn events
- if (game.round_player === DEM && game.round === 7) {
- if(game.persistent_events.includes(15)) {
- if (game.active !== COM) {
- next_player()
- }
- game.state = 'honecker'
- return
- }
- else if (game.dem_tst_position >= 6 && game.com_tst_position <= 5) {
- log_h2('Tiananmen Square Track Award')
- if (game.active !== DEM) {
- next_player()
- }
- game.return = game.active
- clear_undo()
- game.return_state = 'end_turn_4_5_4'
- goto_vm(206)
- return
- } else if (game.com_tst_position >= 6 && game.dem_tst_position <= 5) {
- log_h2('Tiananmen Square Track Award')
- if (game.active !== COM) {
- next_player()
- }
- game.return = game.active
- clear_undo()
- game.return_state = 'end_turn_4_5_4'
- goto_vm(206)
- return
- }
- else {
- clear_undo()
- game.state = 'end_turn_4_5_4'
- return
- }
- }
-
- // Resolve end action round
- //Stasi check
- if(game.round_player === COM && game.persistent_events.includes(13)) {
- game.round_player = DEM
- if (game.active !== DEM) {
- next_player()
- } else {
- log_h3('Democratic Action Round')
- log_h3('C13')
- }
- if (game.democrat_hand.includes(game.stasi_card)) {
- game.state = 'stasi_play_card'
- } else {
- game.stasi_card = 0
- game.state = 'choose_card'
- }
- return
- }
- //Check if in extra Action Round
- else if (game.round_player === COM && game.round === 8) {
- clear_undo()
- game.state = 'end_turn_4_5_4'
- return
- }
- //Normal round end
- else if (game.round_player===COM) {
- game.round_player = DEM
- if (game.active !== DEM) {
- next_player()
- } else {
- log_h3('Democratic Action Round')
- }
- game.state = 'choose_card'
- return
- }
- if (game.round_player === DEM) {
- console.log('checking stasi', game.persistent_events.includes(13))
- if(game.persistent_events.includes(13)) {
- console.log('stasi sub function')
- if (game.active !== DEM) {
- next_player()
- }
- game.state = 'stasi_end_round'
- return
- } else if(game.round_player === DEM && game.persistent_events.includes(5)){
- game.state = 'general_strike'
- game.round ++
- log_h2(`Action Round ${game.round}`)
- game.round_player = COM
- if (game.active !== COM) {
- next_player()
- }
- log_h3('C5')
- return
- } else {
- game.state = 'choose_card'
- game.round_player = COM
- game.round ++
- log_h2(`Action Round ${game.round}`)
- if (game.active !== COM) {
- next_player()
- }
- }
- }
- //game.state = 'choose_card' Does this do anything any more?
-}
-
-/*
-function end_turn(){
- /*End Turn sequence
- TST support check
- Verify held cards
- New Year's Eve Party
- Advance Turn Marker
-
-// CHECK FOR OPTIONAL SUPPORT CHECK
- if (game.dem_tst_position >=6 && game.com_tst_position <= 5) {
- if (game.active !== DEM) {
- next_player_()
- }
- game.state = 'tst_support_check'
- }
- if (game.com_tst_position >=6 && game.dem_tst_position <= 5) {
- if (game.active !== COM) {
- next_player_()
- }
- game.state = 'tst_support_check'
- }
-
-
-//CHECK HELD CARDS
-
-} */
-
-function new_turn() {
- clear_undo()
- game.turn ++
- game.round = 1
- game.valid_spaces=[]
- game.active = COM
- game.round_player = COM
- game.dem_tst_attempted_this_turn = 0
- game.com_tst_attempted_this_turn = 0
- if (game.tst_7) {game.tst_7 = false}
- if (game.tst_8) {game.tst_8 = false}
-
- //Remove events that only last one turn
- game.persistent_events = game.persistent_events.filter(n => n !== 25) /*Perestroika*/
- game.persistent_events = game.persistent_events.filter(n => n !== 50) /*Sinatra Doctrine*/
- game.persistent_events = game.persistent_events.filter(n => n !== 13) /*Stasi*/
- game.persistent_events = game.persistent_events.filter(n => n !== 15) /*Honecker*/
- delete game.prudence
- delete game.stasi_card
-
- //Austria Hungary Border Reopened
- if (game.persistent_events.includes(58)) {
- game.persistent_events = game.persistent_events.filter(n => n !== 58)
- delete game.austria_hungary_border_reopened_tracker
- log(`C58 no longer in effect`)
- //permanently_remove(58)
- }
- //Elena
- if (game.persistent_events.includes(101)) {
- game.persistent_events = game.persistent_events.filter(n => n !== 101)
- log(`C101 no longer in effect`)
- //permanently_remove(101)
- }
- //GrenzTruppen
- if (game.persistent_events.includes(59)) {
- game.persistent_events = game.persistent_events.filter(n => n !== 59)
- log(`C59 no longer in effect`)
- //permanently_remove(59)
- }
- //Foreign Currency Debt Burden
- if (game.persistent_events.includes(49)) {
- game.persistent_events = game.persistent_events.filter(n => n !== 49)
- delete game.foreign_currency_debt_burden
- log(`C49 no longer in effect`)
- //permanently_remove(49)
- }
- //FRG Embassies
- if (game.persistent_events.includes(74)) {
- game.persistent_events = game.persistent_events.filter(n => n !== 74)
- log(`C74 no longer in effect`)
- discard_from_table(74)
- permanently_remove(74)
- }
- //Genscher
- if (game.persistent_events.includes(63)) {
- game.persistent_events = game.persistent_events.filter(n => n !== 63)
- log(`C63 no longer in effect`)
- discard_from_table(63)
- permanently_remove(63)
- }
- //Stand Fast
- if (game.persistent_events.includes(100)) {
- game.persistent_events = game.persistent_events.filter(n => n !== 100)
- delete game.stand_fast
- log(`C100 no longer in effect`)
- //permanently_remove(100)
- }
-
- if (game.samizdat_card > 0 ) {
- game.democrat_hand.push(game.samizdat_card)
- delete game.samizdat_card
- }
-
- log_h1("Turn " + game.turn)
-
- if (game.turn === 4) {
- add_midyear()
- }
- if (game.turn === 8) {
- add_lateyear()
- }
- if (game.turn > 1) {
- if (game.persistent_events.includes(65)) {
- game.com_hand_limit = 7
- log('Communist draws 7 cards due to C65')
- //permanently_remove(65)
- game.persistent_events = game.persistent_events.filter(n => n !== 65)
- }
- console.log('deck', game.strategy_deck)
- console.log('game.com_hand_limit', game.com_hand_limit, 'communist hand before draw', game.communist_hand)
- draw_cards(game.strategy_deck, game.democrat_hand, game.communist_hand, game.dem_hand_limit, game.com_hand_limit)
- game.com_hand_limit = 8
- console.log('communist hand after draw', game.communist_hand)
-
- }
-
- //Check if TST effects need to be resolved
- if (game.dem_tst_position >=5 && game.com_tst_position <= 4) {
- log_h2('Tiananmen Square Track award')
- if(game.active !== DEM) { next_player() }
- for (let card of game.democrat_hand) {
- if (scoring_cards.includes(card)) continue
- game.valid_cards.push(card)
- }
- game.state = 'tst_goddess' /* Goddess only name of Democrat bonus, not Communist*/
- return
- }
- else if (game.com_tst_position >=5 && game.dem_tst_position <= 4) {
- log_h2('Tiananmen Square Track award')
- if(game.active !== COM) { next_player() }
- for (let card of game.communist_hand) {
- if (scoring_cards.includes(card)) continue
- game.valid_cards.push(card)
- }
- game.state = 'tst_goddess'
- } else {
- log_h2("Action Round " + game.round)
- log_side()
- //console.log('in start new AR call, game.active', game.active)
- if (game.persistent_events.includes(5)) {
- log_h3('C5')
- game.state = 'general_strike'
- }
- else {
- game.state = 'choose_card'
- }
- }
-}
-
-function next_player() {
- clear_undo()
- //console.log('next player called')
- if (game.active === DEM)
- game.active = COM
- else
- game.active = DEM
-
- log_side()
-}
-
-function change_player() {
- clear_undo()
- //console.log('next player called')
- if (game.active === DEM)
- game.active = COM
- else
- game.active = DEM
-}
-
-function find_space_index(name_unique) {
- return spaces.findIndex(space => space && space.name_unique === name_unique)
-}
-
-function find_country_index(country) {
- return countries.indexOf(country)
-}
-
-function draw_deck(deck) {
- return deck.filter(card => card && card.period === 1).map(card => card.number)
-}
-
-function draw_cards(deck, democrat_hand, communist_hand, dem_hand_limit, com_hand_limit) {
- //console.log('game.valid_cards at start of draw cards: ', game.valid_cards)
- let turn = 'communist'; // Start with the communist player
- //console.log('game.strategy_deck', game.strategy_deck)
- console.log('deck', deck, 'democrat_hand', democrat_hand, 'communist_hand', communist_hand, 'dem_hand_limit', dem_hand_limit, 'com_hand_limit', com_hand_limit)
- while (democrat_hand.length < dem_hand_limit || communist_hand.length < com_hand_limit) {
- //console.log('deck.length: ', deck.length)
- //console.log('discard.length', game.strategy_discard )
- if (deck.length === 0) {
- log_h3('--- Reshuffle ---')
-
- deck.push(...game.strategy_discard)
- game.strategy_discard = []
- }
-
- else if (turn === 'communist' && communist_hand.length < com_hand_limit) {
- communist_hand.push(draw_card(deck));
- //console.log('game.valid_cards after communist draw: ', JSON.stringify(game.valid_cards));
- turn = 'democrat';
- } else if(turn === 'communist' && communist_hand.length === com_hand_limit) {
- turn = 'democrat';
- }
- else if (turn === 'democrat' && democrat_hand.length < dem_hand_limit) {
- democrat_hand.push(draw_card(deck));
- //console.log('democrat_hand: ', democrat_hand)
-
- //console.log('game.valid_cards after democrat draw: ', JSON.stringify(game.valid_cards));
- turn = 'communist';
- }
- else if (turn === 'democrat' && democrat_hand.length === dem_hand_limit) {
- turn = 'communist';
- }
- }
-
- clear_undo()
-}
-
-function draw_card(deck) {
- //console.log('draw card called with:', deck)
- //console.log('game.strategy_deck before', game.strategy_deck)
- if (deck.length === 0) {
- log_h3('--- Reshuffle ---')
-
- deck.push(...game.strategy_discard)
- game.strategy_discard = []
- }
- const randomIndex = Math.floor(Math.random() * deck.length)
- //console.log('card chosen:', randomIndex)
- //console.log('game.strategy_deck after', game.strategy_deck)
- return deck.splice(randomIndex, 1)[0];
-}
-
-function discard(card) {
- //console.log('in discard(card)')
- let find_card
- if (!game.is_pwr_struggle) {
- if (game.active === COM) {
- find_card = game.communist_hand.indexOf(card)
- game.communist_hand.splice(find_card, 1)
- } else {
- find_card = game.democrat_hand.indexOf(card)
- game.democrat_hand.splice(find_card, 1)
- }
- game.strategy_discard.push(card)
- log(`Discarded C${cards[card].number}`)
-
- } else if (game.is_pwr_struggle) {
- if (game.active === COM) {
- find_card = game.com_pwr_hand.indexOf(card);
- game.com_pwr_hand.splice(find_card, 1);
- } else {
- find_card = game.dem_pwr_hand.indexOf(card);
- game.dem_pwr_hand.splice(find_card, 1);
- }
- game.power_struggle_discard.push(card)
- //log(`Discarded P${power_cards[card].number}`)
- }
-}
-function silent_discard(card) {
- //console.log('in discard(card)')
- let find_card
- if (!game.is_pwr_struggle) {
- if (game.active === COM) {
- find_card = game.communist_hand.indexOf(card)
- game.communist_hand.splice(find_card, 1)
- } else {
- find_card = game.democrat_hand.indexOf(card)
- game.democrat_hand.splice(find_card, 1)
- }
- game.strategy_discard.push(card)
-
- } else if (game.is_pwr_struggle) {
- if (game.active === COM) {
- find_card = game.com_pwr_hand.indexOf(card);
- game.com_pwr_hand.splice(find_card, 1);
- } else {
- find_card = game.dem_pwr_hand.indexOf(card);
- game.dem_pwr_hand.splice(find_card, 1);
- }
- game.power_struggle_discard.push(card)
- }
-}
-
-function remove_from_discard(card) {
- let card_index = game.strategy_discard.indexOf(card)
- if (card_index !== -1) {
- game.strategy_discard.splice(card_index, 1)
- }
-}
-
-function discard_card(hand) {
- //let find_card
- let card = Math.floor(Math.random()*hand.length)
- let discarded_card = hand.splice(card, 1)[0]
- if (game.is_pwr_struggle) {
- if (numberless_cards.includes(discarded_card)) {
- log_gap(`Discarded: P${discarded_card}`)
- } else {
- log_gap(`Discarded: P${discarded_card} V${power_cards[discarded_card].value}`)
- }
- } else {
- log(`Discarded C${cards[discarded_card].number}`)
- game.strategy_discard.push(discarded_card)
- }
- return discarded_card
-}
-
-function discard_from_table(card) {
- find_card = game.table_cards.indexOf(card)
- game.table_cards.splice(find_card, 1)
- game.strategy_discard.push(card)
-}
-
-
-function add_midyear() {
- const mid_year = cards.filter(card => card && card.period === 2).map(card => card.number);
- game.strategy_deck.push(...mid_year);
- log_h3('Mid-year cards added to draw deck')
-}
-
-
-function add_lateyear() {
- const late_year = cards.filter(card => card && card.period === 3).map(card => card.number)
- game.strategy_deck.push(...late_year)
- log_h3('Late-year cards added to draw deck')
-}
-
-function reset_power() {
- game.power_struggle_deck = []
- game.power_struggle_discard = []
- game.dem_pwr_hand = []
- game.com_pwr_hand = []
- game.phase = 1
- game.raised_stakes_round = 0
- game.raised_stakes = 0
- game.played_power_card = 0
- game.tactics_fails = ''
- game.view_opp_hand = false
-
- if (game.persistent_events.includes(72)){
- permanently_remove(72)
- game.table_cards = game.table_cards.filter(card => card !== 72)
- game.persistent_events = game.persistent_events.filter(n => n !== 72)
- }
- if (game.persistent_events.includes(62)) {
- permanently_remove(62)
- game.table_cards = game.table_cards.filter(card => card !== 62)
- game.persistent_events = game.persistent_events.filter(n => n !== 62)
- }
- if (game.persistent_events.includes(54) && game.pwr_struggle_in === 'Romania'){
- permanently_remove(54)
- //game.table_cards = game.table_cards.filter(card => card !== 54)
-
- }
- if (game.pwr_struggle_in === 'Romania' && game.persistent_events.includes(70)){
- //permanently_remove(70)
- //game.table_cards = game.table_cards.filter(card => card !== 70)
- game.persistent_events = game.persistent_events.filter(n => n !== 70)
- }
-}
-
-function check_control_change(space_id) {
- /*game.pieces[space_id].demCtrl = 0
- game.pieces[space_id].comCtrl = 0
-
- if ((game.demInfl[space_id] - game.comInfl[space_id]) >= game.pieces[space_id].stability) {
- game.pieces[space_id].demCtrl = 1
- }
- if ((game.comInfl[space_id] - game.demInfl[space_id]) >= game.pieces[space_id].stability) {
- game.pieces[space_id].comCtrl = 1
- }*/
-
- // Check if the Tyrant is Gone has been fulfilled
- console.log('check control change_player, game.the_tyrant_is_gone', game.the_tyrant_is_gone)
- //console.log('dem control', check_dem_control(game.the_tyrant_is_gone))
- if (game.the_tyrant_is_gone > 0 && check_dem_control(game.the_tyrant_is_gone)) {
- console.log('in tyrant')
- log('+2 VP from C97')
- game.vp += 2
- if (check_vp()) {
- return
- }
- game.persistent_events = game.persistent_events.filter(n => n !== 97)
- delete game.the_tyrant_is_gone
- }
-}
-
-function check_systematization() {
- // Check for Systematization - may not use this space
- if (game.systematization > 0) {
- game.valid_spaces = game.valid_spaces.filter(n => n !== game.systematization)
- }
-}
-
-function check_common_european_home() {
- if (!game.playable_cards.includes(21)) {
- game.playable_cards.push(21)
- }
-}
-
-function this_card() {
- return game.vm_event > 0 ? game.vm_event : game.played_card
-}
-/*
-function get_ops(card) {
- let ops = cards[card].ops
- if (game.active === COM) {
- //Check TST op bonus
- if (ops === 1 && game.com_tst_position >=2 && game.dem_tst_position <=1) {
- ops++
- }
- //Events that influence ops
- if (game.persistent_events.includes(25)) {
- ops++
- }
- if (game.prudence.COM && game.prudence.COM <0) {
- ops += game.prudence.COM
- }
-
- } else {
- //Check TST op bonus
- if (ops === 1 && game.dem_tst_position >=2 && game.com_tst_position <=1) {
- ops++
- }
- //Events that influence ops
- if (game.persistent_events.includes(50)) {
- ops++
- }
- if (game.prudence.DEM && game.prudence.DEM <0) {
- ops += game.prudence.DEM
- }
- }
- //Ops can never be less than one
- if (ops <1) { ops = 1 }
- return ops
-}
- */
-
-const pluralize = (count, noun, suffix = 's') =>
- `${count} ${noun}${Math.abs(count) !== 1 ? suffix : ''}`
-
-function clean_name(str) {
- if (str && str.slice(-1) === '*') {
- return str.slice(0, -1)
- } else {
- return str;
- }
-}
-
-function country_name(country) {
- return country.replace(/_/g, ' ')
-}
-
-// ======== LOG FUNCTIONS =============
-
-function log(msg) {
- game.log.push(msg)
-}
-
-function log_br() {
- if (game.log.length > 0 && game.log[game.log.length - 1] !== "")
- game.log.push("")
-}
-
-function logi(msg) {
- game.log.push(">" + msg)
-}
-
-function log_h1(msg) {
- log_br()
- log(".h1 " + msg)
- log_br()
-}
-
-function log_h2(msg) {
- log_br()
- log(".h2 " + msg)
- log_br()
-}
-
-function log_h3(msg) {
- log_br()
- log(".h3 " + msg)
-}
-
-function log_gap(msg) {
- log_br()
- game.log.push(msg)
-}
-
-function log_msg_gap(msg) {
- game.log.push(msg)
- log_br()
-}
-
-
-function log_side() {
- log_br()
- if (game.active === DEM)
- log(".h2d " + game.active)
- else
- log(".h2c " + game.active)
- log_br()
-}
-
-function log_sep() {
- log(".hr")
-}
-
-function log_action(msg) {
- log_br()
- log(msg)
-}
-
-// ============= SUMMARY FUNCTIONS =============
-
-function push_summary() {
- if (game.summary)
- throw "TOO MANY SUMMARIES"
- game.summary = []
-}
-
-function log_summary(msg) {
-
- if (msg.startsWith('Added') || msg.startsWith('Removed')) {
- for (let item of game.summary) {
- if (item[1] === msg) {
- item[0]++
- return
- }
- }
- }
- game.summary.push([1, msg])
-}
-
-function pop_summary() {
- console.log('summary', game.summary)
- if (game.summary.length > 0) {
- for (let [n, msg] of game.summary) {
- if (n > 1) {
- log(msg.replace("£ SP", `${n} SPs`));
- } else {
- log(msg.replace("£ SP", `${n} SP`));
- }
- }
- }
- game.summary = []
-}
-
-function log_summary_place(p) {
- let from = piece_space(p)
- if (from !== AVAILABLE)
- log_summary("% " + piece_name(p) + " from S" + from)
- else
- log_summary("% " + piece_name(p))
-}
-
-function log_summary_move_to_from(p, to) {
- log_summary("% " + piece_name(p) + " to S" + to + " from S" + piece_space(p))
-}
-
-function log_summary_remove(p) {
- log_summary("Removed % " + piece_name(p))
-}
-
-function log_summary_activated(p) {
- log_summary("Activated % " + piece_faction_name(p))
-}
-
-// ============ UNDO FUNCTIONS ==================
-
-function clear_undo() {
- if (game.undo.length > 0)
- game.undo = []
-}
-
-function push_undo() {
- let copy = {}
- for (let k in game) {
- let v = game[k]
- if (k === "undo")
- continue
- else if (k === "log")
- v = v.length
- else if (typeof v === "object" && v !== null)
- v = object_copy(v)
- copy[k] = v
- }
- game.undo.push(copy)
-}
-
-function pop_undo() {
- let save_log = game.log
- let save_undo = game.undo
- game = save_undo.pop()
- save_log.length = game.log
- game.log = save_log
- game.undo = save_undo
-}
-
-// Fast deep copy for objects without cycles
-function object_copy(original) {
- if (Array.isArray(original)) {
- let n = original.length
- let copy = new Array(n)
- for (let i = 0; i < n; ++i) {
- let v = original[i]
- if (typeof v === "object" && v !== null)
- copy[i] = object_copy(v)
- else
- copy[i] = v
- }
- return copy
- } else {
- let copy = {}
- for (let i in original) {
- let v = original[i]
- if (typeof v === "object" && v !== null)
- copy[i] = object_copy(v)
- else
- copy[i] = v
- }
- return copy
- }
-}
-
-
-/* =================== VM FUNCTIONS ========================== */
-
-function goto_vm(proc) {
- let old_vm = game.vm;
-
- game.state = "vm";
- game.vm = {
- prompt: 0,
- fp: proc,
- ip: 0,
- };
-
- if (old_vm) {
- game.vm.return_vm = old_vm;
- }
-
- vm_exec();
-}
-
-function vm_exec() {
- vm_inst(0)();
-}
-
-function vm_inst(a) {
- console.log('game.vm.fp', game.vm.fp, 'game.vm.ip', game.vm.ip)
- return CODE[game.vm.fp][game.vm.ip][a]
-}
-
-function vm_next() {
- game.vm.ip++;
- console.log('vm_next called, game.vm.ip', game.vm.ip)
- vm_exec();
-}
-
-function vm_operand(a) {
- let x = CODE[game.vm.fp][game.vm.ip][a]
- if (a > 0 && typeof x === "function")
- return x()
- return x
-}
-
-function vm_assert_argcount(n) {
- const argcount = CODE[game.vm.fp][game.vm.ip].length - 1
- if (argcount !== n)
- throw Error(`ASSERT Invalid number of arguments on event ${game.vm.fp}: ${argcount} instead of ${n}`)
-}
-
-function vm_log() {
- log(vm_operand(1));
- vm_next();
-}
-
-function vm_if() {
- console.log('game.temp', game.temp)
- console.log('vm_operand(1)', vm_operand(1))
- if (!vm_operand(1)) {
- let balance = 1
- while (balance > 0) {
- ++game.vm.ip
- switch (vm_operand(0)) {
- case vm_if:
- ++balance
- break
- case vm_endif:
- --balance
- break
- case vm_else:
- if (balance === 1)
- --balance
- break
- }
- if (game.vm.ip < 0 || game.vm.ip > CODE[game.vm.fp].length)
- throw "ERROR"
- }
- }
- vm_next()
-}
-
-function vm_else() {
- vm_goto(vm_endif, vm_if, 1, 1)
-}
-
-function vm_endif() {
- vm_next()
-}
-
-function vm_goto_step(step) {
- console.log('vm_goto_step called, target:', step)
- console.log('game.vm.ip', game.vp.ip)
- for (let i = game.vm.ip; i < CODE[game.vm.fp].length; i++) {
- console.log('i', i)
- console.log('step', CODE[game.vm.fp][i][0])
- if (CODE[game.vm.fp][i][0] === step) {
- game.vm.ip = i;
- vm_exec();
- return;
- }
- }
-
- console.log("ERROR: Target operation not found in the current procedure.");
-}
-
-
-function vm_goto(op, nop, dir, step) {
- console.log('vm_inst(0)', vm_inst(0), op, nop)
- console.log('vm_inst(0)', vm_inst(1), op, nop)
- let balance = 1
- while (balance > 0) {
- game.vm.ip += dir
- if (vm_inst(0) === op)
- --balance
- if (vm_inst(0) === nop)
- ++balance
- if (game.vm.ip < 0 || game.vm.ip > CODE[game.vm.fp].length)
- throw "ERROR"
- }
- game.vm.ip += step
- vm_exec()
-}
-
-function event_prompt(str) {
- //console.log('event_prompt called with', str)
- if (typeof str === "undefined")
- str = CODE[game.vm.fp][game.vm.prompt][1]
- if (typeof str === "function")
- str = str()
- //console.log('str:', str)
- if (!str) {
- str = ""
- }
- return str
-}
-
-function vm_prompt() {
- if (game.vm.prompt)
- game.vm._prompt = game.vm.prompt
- game.vm.prompt = game.vm.ip
- vm_next()
-}
-
-function pop_vm_prompt() {
- if (game.vm._prompt) {
- game.vm.prompt = game.vm._prompt
- delete game.vm._prompt
- } else {
- game.vm.prompt = 0
- }
-}
-
-function vm_return() {
-
- //Remove temporary vm variables
- delete game.support_check_modifier
- delete game.vm_max_infl
- delete game.vm_influence_added
- delete game.communist_hand_red
-
- game.vm_event = 0 /*Reset to 0 now that event has been completed. Hopefully this doesn't cause issues! */
- if (game.persistent_events.includes(58)) {
- reset_austria_hungary_border_reopened()
- }
-
- //game.view_opp_hand = false
- console.log('in vm_return, game.return:', game.return, 'game.return_state:', game.return_state, 'game.vm_infl_to_do', game.vm_infl_to_do, 'game.vm_event_to_do', game.vm_event_to_do)
- /*if (!game.vm_infl_to_do && !game.vm_event_to_do) {
- if (game.round_player !== game.active) {
- change_player()
- log_h2('End of Action Round')
- }
- end_round()
- return
- } /*Go direct to end round if card fully resolved */
- if (game.return !== game.active) {
- next_player()}
- if (game.return_state === 'power_struggle') {
- do_valid_cards()
- }
- if (game.return_state && game.return_state !== '') {
- game.state = game.return_state
- console.log( 'game.state', game.state)
- }
- else if (game.vm_infl_to_do) {game.state = 'resolve_opponent_event'} /*Can use game.return state for this? */
- else {game.state = "play_card"}
-}
-
-/* ================== VM ACTIONS =========================== */
-
-function vm_opp_hand_false() {
- game.view_opp_hand = false
- vm_next()
-}
-
-function vm_valid_spaces() {
- let space_1 = vm_operand(1)
- let space_2 = vm_operand(2)
- let space_3 = vm_operand(3)
- let space_4 = vm_operand(4)
- let space_5 = vm_operand(5)
- let space_6 = vm_operand(6)
- game.valid_spaces = [space_1, space_2, space_3, space_4, space_5, space_6]
- game.valid_spaces = game.valid_spaces.filter( n => n )
-
- // Check for Systematization - may not use this space
- check_systematization()
-
- vm_next()
-}
-
-function vm_valid_spaces_opponent () {
- let valid_spaces = []
- for (let i = 1; i < spaces.length; i++) {
- let space = spaces[i]
-
- if (game.active === DEM) {
- let infl = game.comInfl[i]
- if (infl > 0) {
- valid_spaces.push(space.space_id)
- }
- } else {
- infl = game.demInfl[i]
- if (infl > 0) {
- valid_spaces.push(space.space_id)
- }
- }
- }
- game.valid_spaces = valid_spaces
- console.log('game.valid_spaces', game.valid_spaces)
- vm_next()
-}
-
-function vm_valid_spaces_socio () {
- let valid_spaces = []
- for (let i = 1; i < spaces.length; i++) {
- let space = spaces[i]
-
- if (space.socio === vm_operand(1)) {
- valid_spaces.push(space.space_id)
- }
- }
- game.valid_spaces = valid_spaces
-
- // Check for Systematization - may not use this space
- if (game.systematization && game.systematization > 0) {
- game.valid_spaces = game.valid_spaces.filter(n => n !== game.systematization)
- }
- vm_next()
-}
-
-function vm_valid_spaces_opponent_socio () {
- let valid_spaces = []
- for (let i = 1; i < spaces.length; i++) {
- let space = spaces[i]
-
- if (game.active === DEM) {
- let infl = game.comInfl[i]
- if (infl > 0 && space.socio === vm_operand(1)) {
- valid_spaces.push(space.space_id)
- }
- } else {
- let infl = game.demInfl[i]
- if (infl > 0 && space.socio === vm_operand(1)) {
- valid_spaces.push(space.space_id)
- }
- }
- }
- game.valid_spaces = valid_spaces
- // Check for Systematization - may not use this space
- if (game.systematization && game.systematization > 0) {
- game.valid_spaces = game.valid_spaces.filter(n => n !== game.systematization)
- }
- vm_next()
-}
-
-function vm_valid_spaces_country () {
- let country
- if (vm_operand(1)) {country = vm_operand(1)}
- else {country = game.vm_active_country}
- for (let space of spaces) {
- if (!space) continue
- if (space.country === country) {
- game.valid_spaces.push(space.space_id);
- }
- }
- // Check for Systematization - may not use this space
- if (game.systematization && game.systematization > 0) {
- game.valid_spaces = game.valid_spaces.filter(n => n !== game.systematization)
- }
- vm_next()
-}
-
-function vm_valid_spaces_sc () {
- valid_spaces_sc()
- vm_next()
-}
-
-function vm_valid_spaces_country_opp () {
- let country = ''
-
- if (vm_operand(1)) {
- country = vm_operand(1) }
- else {
- country = game.vm_active_country
- }
- for (let space of spaces) {
- if (!space) continue
- if (game.active === DEM) {
- if (space.country === country && game.comInfl[space.space_id] >0) {
- game.valid_spaces.push(space.space_id);
- }
- } else {
- if (space.country === country && game.demInfl[space.space_id]>0) {
- game.valid_spaces.push(space.space_id);
- }
- }
- }
- vm_next()
-}
-
-function vm_valid_spaces_country_sc () {
- let valid_spaces = []
- let country = ''
- console.log('in vm_valid_spaces_country_sc')
- if (vm_operand(1)) {
- country = vm_operand(1) }
- else {
- country = game.vm_active_country
- }
- for (let space of spaces) {
- if (!space) continue
- if (game.active === DEM) {
- if (space.country === country && game.comInfl[space.space_id] >0) {
- valid_spaces.push(space.space_id);
- }
- } else {
- if (space.country === country && game.demInfl[space.space_id] >0) {
- //Check Solidarity Legalised
- if (game.persistent_events.includes(2) && space.space_id === 14) {continue}
-
- //Check Civic Forum
- if (game.persistent_events.includes(90) && space.space_id === 30) {continue}
-
- //Check We are the People
- if (game.persistent_events.includes(48) && space.space_id === 9) {continue}
- valid_spaces.push(space.space_id);
-
- //Check Foreign Currency Debt Burden
- if (game.persistent_events.includes(49) && space.country === game.foreign_currency_debt_burden) {continue}
- }
- }
- }
- game.valid_spaces = valid_spaces
-
- //Check for Foreign Currency Debt Burden
- /*if (game.persistent_events.includes(49) && game.active === COM) {
- game.valid_spaces = game.valid_spaces.filter(n => spaces[n].country !== game.foreign_currency_debt_burden)
- }*/
- vm_next()
-}
-
-function vm_valid_spaces_country_socio_2() {
- for (let space of spaces) {
- if (!space) continue
- if (space.space_id === game.systematization) continue
- if ((space.country === vm_operand(1) && space.socio === vm_operand(2)) || (space.country === vm_operand(1) && space.socio === vm_operand(3))) {
- game.valid_spaces.push(space.space_id);
- }
- }
- vm_next()
-}
-
-function vm_valid_spaces_region_socio() {
- let valid_spaces = []
- for (let space of spaces) {
- if (!space) continue
- if (space.space_id === game.systematization) continue
- if (space.region === vm_operand(1) && space.socio === vm_operand(2)) {
- valid_spaces.push(space.space_id);
- }
- }
- game.valid_spaces = valid_spaces
- vm_next()
-}
-
-function vm_valid_spaces_region_opp() {
- let valid_spaces = []
- for (let space of spaces) {
- if (!space) continue
- let s = space.space_id
- if ((game.active === DEM && space.region === vm_operand(1) && game.comInfl[s] > 0 ) || (game.active === COM && space.region === vm_operand(1) && game.demInfl[s] > 0 )) {
- valid_spaces.push(space.space_id);
- }
- }
- game.valid_spaces = valid_spaces
- vm_next()
-}
-
-function vm_valid_spaces_solidarity_legalised() {
- let valid_spaces = []
- for (let i = 1; i < spaces.length; i++) {
- let space = spaces[i]
- let uncontrolled = (!check_control(i) && !check_opp_control(i))
- if ((space.country === 'Poland' && uncontrolled && space.socio === 3) || (space.country === 'Poland' && uncontrolled && space.socio === 4)) {
- valid_spaces.push(space.space_id);
- }
- }
- game.valid_spaces = valid_spaces
- vm_next()
-}
-
-function vm_active_country () {
- game.valid_spaces = game.valid_spaces.filter(space_id => {
- let space = spaces.find(s => s && s.space_id === space_id);
- return space && space.country === game.vm_active_country;
- });
- vm_next()
-}
-
-function vm_take_control_prep() {
- game.vm_available_ops = vm_operand(1)
- game.state = 'vm_take_control'
- console.log('in vm_take_control_prep game.state', game.state)
-}
-
-function vm_take_control(space) {
- let clicked_space = find_space_index(space)
- if (game.active === DEM) {
- let current_infl = game.demInfl[clicked_space]
- let opponent_infl = game.comInfl[clicked_space]
- let stability = spaces[clicked_space].stability
-
- if ((current_infl - opponent_infl) < stability) {
- game.demInfl[clicked_space] += stability - current_infl + opponent_infl
- //game.pieces[clicked_space].demCtrl = 1
- //game.pieces[clicked_space].comCtrl = 0
- }
- } else if (game.active === COM) {
- let current_infl = game.comInfl[clicked_space]
- let opponent_infl = game.demInfl[clicked_space]
- let stability = spaces[clicked_space].stability
-
- if ((current_infl - opponent_infl) < stability) {
- game.comInfl[clicked_space] += stability - current_infl + opponent_infl
- //game.pieces[clicked_space].comCtrl = 1
- //game.pieces[clicked_space].demCtrl = 0
- }
- }
- game.valid_spaces = game.valid_spaces.filter(id => id !== clicked_space)
- log(`Took control of %${clicked_space}`)
-}
-
-
-function vm_do_add_infl(space) {
- push_undo()
- console.log('in vm_do_add_infl, space', space, 'ops', game.vm_available_ops, 'ahbr tracker', game.austria_hungary_border_reopened_tracker, 'ahbr in events', game.persistent_events.includes(58))
- const clicked_space = find_space_index(space)
-
- //log(`Added 1 influence in %${clicked_space}.`)
-
- log_summary(`Added £ SP in %${clicked_space}.`)
-
- //If AHBR - check AHBR condition
- if (game.persistent_events.includes(58)) {
- if (spaces[clicked_space].country !== 'East_Germany'){
- game.austria_hungary_border_reopened_tracker = false
- }
- }
-
- // Check Genscher
- if (game.persistent_events.includes(63) && game.active === DEM && spaces[clicked_space].country === 'East_Germany') {
- game.vm_available_ops--
- log_summary(`(-1 op due to C63)`)
- } else if (check_opp_control(clicked_space)) {
- game.vm_available_ops -= 2
- //Check if Austria Hungary Border Reopened was used to place last SP in a controlled space in East Germany. If so, game.vm_available_op will be negative
- if (game.vm_available_ops < 0) {
- log_summary(`(Used +1 op from C58)`)
- }
- } else {
- game.vm_available_ops--
- }
-
- // Update influence values
- if (game.active === COM) {
- game.comInfl[clicked_space]++
- } else {
- game.demInfl[clicked_space]++
- }
-
- // Check whether spaces are controlled
- check_control_change(clicked_space)
-
- console.log('before check, ahbr in events', game.persistent_events.includes(58), 'tracker', game.austria_hungary_border_reopened_tracker)
- // Check Austria Hungary Border Reopened is true and condition has been met
- if (game.vm_available_ops === 0 && game.active === DEM && game.persistent_events.includes(58) && game.austria_hungary_border_reopened_tracker) {
- console.log('in award extra op')
- game.vm_available_ops ++
- log('+1 Op from C58')
- game.austria_hungary_border_reopened_tracker = false
- game.valid_spaces = game.valid_spaces.filter(n => spaces[n].country === 'East_Germany')
- }
-
- // If only 1 IP remaining, may not place in opponent controlled spaces
-
- // Check for Genscher & Austria Hungary Border Reopened
-
- if (game.vm_available_ops === 1) {
-
- if (game.active === DEM) {
- //Check Genscher and AHBR
- if (game.persistent_events.includes(63) || (game.persistent_events.includes(58) && game.austria_hungary_border_reopened_tracker)) {
- console.log('in gensher subcheck - remove non-East German controlled ')
- game.valid_spaces = game.valid_spaces.filter(n => !(check_com_control(n) && spaces[n].country !== 'East_Germany'))
- } else {
- console.log('remove all controlled spaces')
- game.valid_spaces = game.valid_spaces.filter(n => !check_com_control(n))
- }
- } else {
- game.valid_spaces = game.valid_spaces.filter(n => !check_dem_control(n))
- }
- }
-
- //Clear valid spaces if no IP remaining.
- if (game.vm_available_ops <= 0 ) {
- game.valid_spaces = []
- }
-}
-
-function vm_do_add_infl_free(space) {
- push_undo()
- const clicked_space = find_space_index(space)
- //log(`Added 1 influence in %${clicked_space}.`)
-
- log_summary(`Added £ SP in %${clicked_space}.`)
-
- // Update influence values
- if (game.active === COM) {
- game.comInfl[clicked_space]++
- } else {
- game.demInfl[clicked_space]++
- }
- game.vm_available_ops--
- // Check whether spaces are controlled
- check_control_change(clicked_space)
-
-
- //console.log('game pieces:', game.pieces[clicked_space])
-}
-
-function vm_add_infl() {
- if (vm_operand(1)) {game.vm_available_ops = vm_operand(1)}
- game.state = 'vm_add_infl'
-}
-
-function vm_add_infl_free() {
- if (vm_operand(1)) {game.vm_available_ops = vm_operand(1)}
- game.state = 'vm_add_infl_free'
-}
-
-function vm_add_x_infl() {
- game.vm_available_ops = vm_operand(1)
- game.state = 'vm_add_x_infl'
-}
-
-function vm_do_add_x_infl(space) {
- push_undo()
- const clicked_space = find_space_index(space)
- log(`Added ${game.vm_available_ops} SPs in %${clicked_space}.`)
-
-
- if (game.active === COM) {
- game.comInfl[clicked_space] += game.vm_available_ops
- } else {
- game.demInfl[clicked_space] += game.vm_available_ops
- }
- check_control_change(clicked_space)
- game.vm_available_ops = 0
- game.valid_spaces = []
-}
-
-function vm_add_limited_infl() {
- game.vm_available_ops = vm_operand(1)
- game.vm_max_infl = vm_operand(2)
- game.state = 'vm_add_limited_infl'
-}
-
-function vm_do_add_limited_infl(space, max_infl) {
- push_undo()
- const clicked_space = find_space_index(space)
- //log(`Added 1 influence in %${clicked_space}.`)
-
- log_summary(`Added £ SP in %${clicked_space}.`)
- game.vm_available_ops --
-
- if (!game.vm_influence_added) {
- game.vm_influence_added = {};
- }
-
- if (!game.vm_influence_added[clicked_space]) {
- game.vm_influence_added[clicked_space] = 0;
- }
-
- if (game.active === COM) {
- game.comInfl[clicked_space] ++
- } else {
- game.demInfl[clicked_space] ++
- }
-
- game.vm_influence_added[clicked_space] ++
-
- //console.log('valid_spaces before update', game.valid_spaces)
- //console.log('influence added:', game.vm_influence_added[clicked_space], 'max infl', max_infl)
- if (game.vm_influence_added[clicked_space] === max_infl) {
- game.valid_spaces = game.valid_spaces.filter(id => id !== clicked_space);
- }
- check_control_change(clicked_space)
- if (game.vm_available_ops === 0) {game.valid_spaces = [] }
-}
-
-function vm_remove_infl() {
- game.vm_available_ops = vm_operand(1)
- game.state = 'vm_remove_infl'
-}
-
-function vm_remove_opp_infl() {
- game.vm_available_ops = vm_operand(1)
- game.remove_opponent_infl = true
- game.state = 'vm_remove_infl'
-}
-
-function vm_remove_x_opp_infl() {
- game.vm_available_ops = vm_operand(1)
- game.remove_opponent_infl = true
- game.state = 'vm_remove_x_infl'
-}
-
-function vm_do_remove_infl(space) {
- push_undo()
- const clicked_space = find_space_index(space)
- //log(`Removed 1 influence from %${clicked_space}.`)
- log_summary(`Removed £ SP from %${clicked_space}.`)
-
- if (!game.vm_influence_added) {
- game.vm_influence_added = {};
- }
-
- if (!game.vm_influence_added[clicked_space]) {
- game.vm_influence_added[clicked_space] = 0;
- }
- if (game.remove_opponent_infl === true) {
- if (game.active === COM) {
- game.demInfl[clicked_space]--
- if (game.demInfl[clicked_space] === 0) {
- game.valid_spaces = game.valid_spaces.filter(id => id !== clicked_space);
- }
- } else {
- game.comInfl[clicked_space]--
- if (game.comInfl[clicked_space] === 0) {
- game.valid_spaces = game.valid_spaces.filter(id => id !== clicked_space);
- }
- }
-
-
- } else {
- if (game.active === COM) {
- game.comInfl[clicked_space]--
- if (game.comInfl[clicked_space] === 0) {
- game.valid_spaces = game.valid_spaces.filter(id => id !== clicked_space);
- }
- } else {
- game.demInfl[clicked_space]--
- if (game.demInfl[clicked_space] === 0) {
- game.valid_spaces = game.valid_spaces.filter(id => id !== clicked_space);
- }
- }
- }
- check_control_change(clicked_space)
- game.vm_influence_added[clicked_space]++
- game.vm_available_ops--
- if (game.vm_available_ops===0) {game.valid_spaces = []}
-}
-
-function vm_do_remove_x_infl(space) {
- push_undo()
- const clicked_space = find_space_index(space)
-
- if (game.remove_opponent_infl) {
- if (game.active === COM) {
- if (game.demInfl[clicked_space] >= game.vm_available_ops) {
- game.demInfl[clicked_space] -= game.vm_available_ops
- } else {
- game.vm_available_ops = game.demInfl[clicked_space]
- game.demInfl[clicked_space] -= game.vm_available_ops
- }
- } else {
- if (game.comInfl[clicked_space] >= game.vm_available_ops) {
- game.comInfl[clicked_space] -= game.vm_available_ops
- } else {
- game.vm_available_ops = game.comInfl[clicked_space]
- game.comInfl[clicked_space] -= game.vm_available_ops
- }
- }
- } else {
- if (game.active === COM) {
- if (game.comInfl[clicked_space] >= game.vm_available_ops) {
- game.comInfl[clicked_space] -= game.vm_available_ops
- } else {
- game.vm_available_ops = game.comInfl[clicked_space]
- game.comInfl[clicked_space] -= game.vm_available_ops
- }
- } else {
- if (game.demInfl[clicked_space] >= game.vm_available_ops) {
- game.demInfl[clicked_space] -= game.vm_available_ops
- } else {
- game.vm_available_ops = game.demInfl[clicked_space]
- game.demInfl[clicked_space] -= game.vm_available_ops
- }
- }
- }
-
- log(`Removed ${game.vm_available_ops} SPs from %${clicked_space}`)
- check_control_change(clicked_space)
-
- game.vm_available_ops = 0
- game.valid_spaces = []
-}
-
-function vm_remove_limited_opp_infl() {
- game.vm_available_ops = vm_operand(1)
- game.vm_max_infl = vm_operand(2)
- game.remove_opponent_infl = true
- game.state = 'vm_remove_limited_infl'
-}
-
-function vm_do_remove_limited_infl(space, max_infl) {
- push_undo()
- const clicked_space = find_space_index(space)
- log(`Removed SP from %${clicked_space}.`)
- game.vm_available_ops --
-
-
- if (!game.vm_influence_added) {
- game.vm_influence_added = {};
- }
-
- if (!game.vm_influence_added[clicked_space]) {
- game.vm_influence_added[clicked_space] = 0;
- }
-
- if (game.active === COM) {
- game.demInfl[clicked_space] --
- if (game.demInfl[clicked_space] === 0) {
- game.valid_spaces = game.valid_spaces.filter(id => id !== clicked_space)
- }
- } else {
- game.comInfl[clicked_space] --
- if (game.comInfl[clicked_space] === 0) {
- game.valid_spaces = game.valid_spaces.filter(id => id !== clicked_space)
- }
- }
-
- game.vm_influence_added[clicked_space] ++
-
- if (game.vm_influence_added[clicked_space] === max_infl) {
- game.valid_spaces = game.valid_spaces.filter(id => id !== clicked_space);
- }
-
- check_control_change(clicked_space)
- if (game.vm_available_ops === 0) {game.valid_spaces = []}
-}
-
-function vm_remove_all_infl() {
- game.vm_available_ops = vm_operand(1)
- game.state = 'vm_remove_all_infl'
-}
-
-function vm_do_remove_all_infl(space) {
- push_undo()
- const clicked_space = find_space_index(space)
- log(`Removed all SP from %${clicked_space}.`)
-
- if (game.remove_opponent_infl === true) {
- if (game.active === COM) {
- game.demInfl[clicked_space] = 0
- } else {
- game.comInfl[clicked_space] = 0
- }
- check_control_change(clicked_space)
-
- } else {
- if (game.active === COM) {
- game.comInfl[clicked_space] = 0
- } else {
- game.demInfl[clicked_space] = 0
- }
- check_control_change(clicked_space)
- }
- game.vm_available_ops --
- game.valid_spaces = game.valid_spaces.filter(id => id !== clicked_space)
-}
-
-function vm_replace_all_infl(space_id) {
- if (game.active === DEM) {
- game.demInfl[space_id] += game.comInfl[space_id]
- game.comInfl[space_id] = 0
- } else {
- game.comInfl[space_id] += game.demInfl[space_id]
- game.demInfl[space_id] = 0
- }
- check_control_change(space_id)
-}
-
-function vm_1_support_check() {
- game.vm_available_ops = 1
- game.state = 'vm_1_support_check_prep'
-}
-
-function vm_support_check() {
- game.vm_available_ops = vm_operand(1)
- game.state = 'vm_support_check_prep'
-}
-
-function vm_support_check_modified() {
- game.vm_available_ops = vm_operand(1)
- game.support_check_modifier = vm_operand(2)
- game.state = 'vm_support_check_prep'
-}
-
-function vm_switch_infl(space){
- push_undo()
- let clicked_space = find_space_index(space)
- game.demInfl[clicked_space] -= game.vm_available_ops
- game.comInfl[clicked_space] += game.vm_available_ops
- log(`Replaced ${pluralize(game.vm_available_ops,'SP')} in ${spaces[clicked_space].name_unique}`)
- game.vm_available_ops = 0
- check_control_change(clicked_space)
-}
-
-/* ===================== EVENT SPECIFIC FUNCTIONS ========== */
-
-function vm_40th_anniversary_celebration() {
- if (game.vp < 0 ) {game.vm_available_ops = 4}
- else {game.vm_available_ops = 2}
- vm_next()
-}
-
-function vm_40th_anniversary_celebration_vp() {
- game.vp --
- log('-1VP')
- if (check_vp()) {
- return
- }
- vm_next()
-}
-
-function vm_adamec() {
- game.state = 'vm_adamec'
-}
-
-function vm_army_backs_revolution() {
- game.persistent_events = game.persistent_events.filter(n => n !== 70)
- game.playable_cards = game.playable_cards.filter(n => n !== 70)
- /*if (game.table_cards.includes(70)) {
- permanently_remove(70)
- }*/
- vm_next()
-}
-
-function vm_austria_hungary_border_reopened() {
- game.persistent_events.push(58)
- permanently_remove(58)
- game.austria_hungary_border_reopened_tracker = false
- //game.table_cards.push(58)
- //remove_from_discard(58)
- vm_next()
-}
-
-function vm_betrayal() {
- if (game.demInfl[58] > 0 ) { game.valid_spaces.push(58) }
- if (game.demInfl[65] >0 ) { game.valid_spaces.push(65) }
- game.vm_available_ops = Math.max(game.demInfl[58], game.demInfl[65])
- game.state = 'vm_switch_infl'
-}
-
-function vm_breakaway_baltic_republics() {
- log('+5 VP')
- game.vp += 5
- game.stability++
- if (check_vp()) {
- return
- }
- game.playable_cards.push(109)
- game.playable_cards = game.playable_cards.filter(n => n !== 14)
- if (!check_dem_control(56) && game.systematization !== 56) {game.valid_spaces.push(56)}
- if (!check_dem_control(70)) {game.valid_spaces.push(70)}
- vm_next()
-}
-
-function vm_brought_in_for_questioning() {
- if (game.active === COM) {
- game.active = DEM
- }
- //game.return = game.active
- console.log('in bifg, game.return', game.return)
- game.phase = 0
- game.state = 'vm_brought_in_for_questioning'
-}
-
-function vm_bulgarian_turks_expelled(){
- game.remove_opponent_infl = true
- game.vp -= 2
- log('-2VP')
- if (check_vp()) {
- return
- }
- if (game.demInfl[70] > 0) {game.valid_spaces = [70]}
- vm_next()
-}
-
-function vm_ceausescu() {
- let adj_cluj = false
- if (game.demInfl[50] > 0 ) {adj_cluj = true}
- if (game.demInfl[54] > 0 ) {adj_cluj = true}
- if (game.demInfl[58] > 0 ) {adj_cluj = true}
- if (game.demInfl[61] > 0 ) {adj_cluj = true}
-
- if (adj_cluj && game.comInfl[61]>0) {
- game.valid_spaces = [61]
- game.vm_available_ops = 1
- //next_player()
- game.remove_opponent_infl = false
- game.state = 'vm_remove_infl'
- }
- else {vm_next()}
-}
-
-function vm_central_committee_reshuffle() {
- game.state = 'vm_central_committee_reshuffle'
-}
-
-function vm_civic_forum() {
- log('+1 VP')
- game.vp++
- if (check_vp()) {
- return
- }
- game.persistent_events.push(90)
- if (check_dem_control(31)) {
- vm_next()
- } else {
- permanently_remove(90)
- vm_return()
- }
-}
-
-function vm_common_european_home() {
- let valid_cards = [];
- for (let c of cards) {
- //if (c === null) {continue}
- if (game.active === DEM) {
- if (c && c.side === 'C') {
- valid_cards.push(c.number)
- }
- } else {
- if (c && c.side === 'D') {
- valid_cards.push(c.number)
- }
- }
- }
- game.valid_cards = valid_cards
- game.state = 'vm_common_european_home_choose'
-}
-
-function vm_dash_for_the_west() {
- game.valid_cards = []
- for (let c of game.strategy_discard) {
- if (cards[c].side === 'D' && cards[c].remove === 1 && (cards[c].playable || game.playable_cards.includes(c))) {
- game.valid_cards.push(c)
- }
- }
- game.state = 'vm_dash_for_the_west'
-}
-
-function vm_deutsche_marks() {
- let max_value = 1;
- for (let c of game.democrat_hand) {
- if (cards[c].ops > max_value) {
- max_value = cards[c].ops
- }
- }
- let valid_cards = [];
- for (let c of game.democrat_hand) {
- if (cards[c].ops === max_value) {
- valid_cards.push(c);
- }
- }
- game.valid_cards = valid_cards
- game.state = 'vm_deutsche_marks_prep'
-}
-
-function vm_domino_theory() {
- game.discard = true
- for (let card of game.strategy_discard) {
- if (scoring_cards.includes(card)) {game.valid_cards.push(card) }
- }
- game.phase = 0
- game.state = 'vm_play_event_from_discard'
-}
-
-function vm_eco_glasnost() {
- game.persistent_events.push(39)
- permanently_remove(39)
- vm_next()
-}
-
-function vm_elena(){
- game.persistent_events.push(101)
- permanently_remove(101)
- //game.table_cards.push(101)
- //remove_from_discard(101)
- vm_next()
-}
-
-function vm_eliminate(space_id) {
- log(`Eliminated %${space_id}`)
- const adjacent_spaces = spaces[space_id].adjacent.filter(Number.isInteger);
-
- //console.log('adjacency before: Iasi', game.pieces[53].adjacent, 'Ploesti:', game.pieces[59].adjacent, 'Bucharesti:', game.pieces[61].adjacent)
-
- // Remove clicked_space from the adjacency lists of its adjacent spaces
- /* adjacent_spaces.forEach(s => {
- game.pieces[s].adjacent = spaces[s].adjacent.filter(id => id !== space_id);
- });
-
- //console.log('adjacency after: Iasi', game.pieces[53].adjacent, 'Ploesti:', game.pieces[59].adjacent, 'Bucharesti:', game.pieces[61].adjacent)
-
- // Connect adjacent spaces to each other
- // No longer used - spaces done dynamically
-/*
- for (let i = 0; i < adjacent_spaces.length; i++) {
- for (let j = i + 1; j < adjacent_spaces.length; j++) {
- console.log(' checking i,', spaces[adjacent_spaces[i]].name, 'j', spaces[adjacent_spaces[j]].name)
- if (!game.pieces[adjacent_spaces[i]].adjacent.includes(adjacent_spaces[j])) {
- game.pieces[adjacent_spaces[i]].adjacent.push(adjacent_spaces[j]);
- }
- if (!game.pieces[adjacent_spaces[j]].adjacent.includes(adjacent_spaces[i])) {
- game.pieces[adjacent_spaces[j]].adjacent.push(adjacent_spaces[i]);
- }
- }
- }
-
- console.log('adjacency after addition: Iasi', game.pieces[53].adjacent, 'Ploesti:', game.pieces[59].adjacent, 'Bucharesti:', game.pieces[61].adjacent)
- // Clear the adjacency list of the clicked space
- game.pieces[space_id].adjacent = [];
-*/
- // Eliminate the democrat influence and move the communist influence to Bucuresti
- game.demInfl[space_id] = 0
- game.comInfl[61] += game.comInfl[space_id]
- if (game.comInfl[space_id] > 0 ) {
- log(`${game.comInfl[space_id]} Communist SP relocated to Bucuresti`)
- }
- game.comInfl[space_id] = 0
-
- //Update control in the eliminated space and in Bucuresti
- check_control_change(space_id)
- check_control_change(61)
-
-}
-
-function get_adjusted_adjacency(space_id) {
- let adjacent_spaces = spaces[space_id].adjacent;
- if (adjacent_spaces.includes(game.systematization)) {
- //console.log('in get adjusted adjacency, systemization',game.systematization)
- //console.log('adjacent_spaces', adjacent_spaces)
- }
- if (game.systematization !== 0) {
- //console.log('in systematization check')
- let eliminated_space_id = game.systematization;
-
- return adjacent_spaces.map(adj_space_id => {
- if (adj_space_id === eliminated_space_id) {
- // Replace the eliminated space with its adjacencies
- //console.log('in map check, return', spaces[eliminated_space_id].adjacent)
- return spaces[eliminated_space_id].adjacent;
- }
- //console.log('2nd check, return', adj_space_id)
- return adj_space_id;
- }).flat(); // Flatten in case the eliminated space has multiple adjacencies
- }
- //console.log('final adjacent spaces', adjacent_spaces)
- return adjacent_spaces;
-}
-
-function vm_exit_visas() {
- game.state = 'vm_exit_visas'
-}
-
-function vm_foreign_currency_debt_burden() {
- log('+1VP')
- game.vp++
- if (check_vp()) {
- return
- }
- //game.table_cards.push(49)
- //remove_from_discard(49)
- game.persistent_events.push(49)
- game.state = 'vm_foreign_currency_debt_burden'
-}
-
-function vm_foreign_television() {
- for (let i = 1 ; i < spaces.length; i++) {
- if (i === 12) {continue} /*Does not apply to Dresden*/
- if (game.comInfl[i] > 0 ) {
- game.valid_spaces.push(i)
- }
- }
- vm_next()
-}
-function vm_frg_embassies() {
- game.persistent_events.push(74)
- game.table_cards.push(74)
- remove_from_discard(74)
- log('C74 in effect')
- vm_next()
-}
-
-function vm_general_strike() {
- game.persistent_events.push(5)
- game.table_cards.push(5)
- remove_from_discard(5)
- log('C5 in effect')
- vm_next()
-}
-
-function vm_genscher() {
- game.persistent_events.push(63)
- game.table_cards.push(63)
- remove_from_discard(63)
- log(`C63 in effect`)
- vm_next()
-}
-
-function vm_goodbye_lenin() {
- game.view_opp_hand = true
- game.communist_hand_red = []
- // Select Red cards to show
- for (let card of game.communist_hand) {
- console.log('checking card ', card, 'red', cards[card].red)
- if (cards[card].red) {
- game.communist_hand_red.push(card)
- }
- }
- //Check if these cards are playabl
- for (let card of game.communist_hand_red) {
- if (cards[card].playable || game.playable_cards.includes(card)) {
- game.valid_cards.push(card)
- }
- }
- game.state = 'vm_goodbye_lenin'
-}
-
-function vm_government_resigns() {
- for (let i = 1; i < spaces.length; i++) {
- let space = spaces[i]
- if (space.socio === 1 && game.comInfl[i] > 0 && !check_control(i)) {
- game.valid_spaces.push(i)
- }
- }
- game.remove_opponent_infl = true
- vm_next()
-}
-
-function vm_grenztruppen() {
- console.log('in grenztruppen - player active:', game.active)
- game.persistent_events.push(59)
- permanently_remove(59)
- //game.table_cards.push(59)
- //remove_from_discard(59)
- vm_next()
-}
-
-function vm_heal_our_bleeding_wounds() {
- let change_vp = 0
- if (game.turn <= 3) {change_vp = -3 }
- else if (game.turn <= 7) {change_vp = -1}
- else change_vp = 3
- if (change_vp >0) {
- log(`+${change_vp} VP`)
- } else {
- log(`-${change_vp} VP`)
- }
- game.vp += change_vp
- if (check_vp()) {
- return
- }
- vm_next()
-}
-
-function vm_helsinki_final_act() {
- game.persistent_events.push(26)
- vm_next()
-}
-
-function vm_honecker() {
- game.persistent_events.push(15)
- game.valid_cards = []
- for (let c of game.strategy_discard) {
- if (scoring_cards.includes(c)) {
- continue}
- else {
- game.valid_cards.push(c)
- }
- }
- game.discard = true
- game.state = 'vm_honecker'
-}
-
-function vm_inflationary_currency() {
- game.state = 'vm_inflationary_currency'
-}
-
-function vm_inflationary_currency_discard() {
- // This function starts with the player who is playing Inflationary Currency for the Event
- // Switch player and check the hand of their opponent to see if the have cards with ops > 3 to discard
- next_player()
- if (game.active === COM) {
- for (let card of game.communist_hand){
- if (get_card_ops(card) >= 3) {
- game.valid_cards.push(card)
- }
- }
- } else {
- for (let card of game.democrat_hand){
- if (get_cards_ops(card) >= 3) {
- game.valid_cards.push(card)
- }
- }
- }
- game.state = 'vm_inflationary_currency_discard'
-}
-
-function vm_kiss_of_death() {
- game.state = 'vm_kiss_of_death'
-}
-
-function vm_klaus_and_komarek() {
- if (game.comInfl[29] > 0 ) {game.valid_spaces = [29]}
- vm_next()
-}
-
-function vm_kohl_proposes_reunification() {
- log('+2 VP')
- game.vp += 2
- if (check_vp()) {
- return
- }
- if (game.persistent_events.includes(86)) {
- game.vm_event = 87
- game.state = 'vm_common_european_home_play'
- } else {
- permanently_remove(87)
- vm_return()
- }
-
-}
-
-function vm_kremlin_coup() {
- log('-3 VP')
- game.vp -= 3
- if (check_vp()) {
- return
- }
- game.support_check_modifier = 1
- //countries = ['Poland', 'Hungary', 'East_Germany', 'Bulgaria', 'Czechoslovakia', 'Romania']
- //revolutions: {'East_Germany': false, 'Poland': false, 'Czechoslovakia': false, 'Hungary': false, 'Romania': false, 'Bulgaria': false}
- game.temp = []
- countries.forEach(country => {
- if (!game.revolutions[find_country_index(country)]) {
- game.temp.push(country)
- }
- })
- console.log('game.temp', game.temp)
- game.state = 'vm_kremlin_coup_choose_country'
-}
-
-function vm_laszlo_tokes() {
- game.persistent_events.push(73)
- game.playable_cards.push(107)
- game.state = 'vm_laszlo_tokes'
-}
-
-function vm_legacy_of_martial_law() {
- game.vm_available_ops = 1
- game.state = 'vm_switch_infl'
-}
-
-function vm_legacy_of_1968() {
- for (let i = 1; i < spaces.length; i++) {
- let space = spaces[i]
- if ((!check_com_control(i) && space.country === 'Czechoslovakia')) {
- game.valid_spaces.push(space.space_id);
- }
- }
- vm_next()
-}
-
-function vm_li_peng() {
- game.persistent_events.push(53)
- //game.table_cards.push(53)
- remove_from_discard(53)
- vm_next()
-}
-
-function vm_ligachev() {
- game.persistent_events.push(99)
- vm_next()
-}
-
-function vm_malta_summit() {
- game.state = 'vm_malta_summit'
-}
-
-function vm_massacre_in_timisoara() {
- game.persistent_events = game.persistent_events.filter(n => n !== 73)
- vm_next()
-}
-
-function vm_modrow() {
- game.playable_cards.push(15)
- game.state = 'vm_modrow'
-}
-
-function vm_nagy_reburied(){
- if (game.comInfl[43] > 0) {
- game.valid_spaces.push(43)
- }
- vm_next()
-}
-
-function vm_national_salvation_front() {
- game.persistent_events.push(102)
- game.table_cards.push(102)
- remove_from_discard(102)
- vm_next()
-}
-
-function vm_nepotism() {
- game.state = 'vm_nepotism'
-}
-
-function vm_new_years_eve_party() {
- game.state = 'vm_new_years_eve_party'
-}
-
-function vm_nomenklatura() {
- game.state = 'vm_nomenklatura'
-}
-
-function vm_normalisation() {
- if (game.demInfl[27] >0) {game.valid_spaces.push(27)}
- if (game.demInfl[29] > 0) {game.valid_spaces.push(29)}
- game.remove_opponent_infl = true
- vm_next()
-}
-
-function vm_peasant_parties_revolt() {
- game.persistent_events.push(72)
- log_msg_gap('C72 in effect')
- game.table_cards.push(72)
- remove_from_discard(72)
- vm_next()
-}
-
-function vm_perestroika() {
- game.persistent_events.push(25)
- log_msg_gap('C25 in effect')
- permanently_remove(25)
- vm_next()
-}
-
-function vm_poszgay() {
- let valid_spaces = []
- for (let space of spaces) {
- if (space && space.country === 'Hungary' && !check_dem_control(space.space_id)) {
- valid_spaces.push(space.space_id);
- }
- }
- game.valid_spaces = valid_spaces
- vm_next()
-}
-
-function vm_power_struggle() {
- console.log('in vm_power_struggle. game.vm_event', game.vm_event, 'game.active', game.active, 'game.view_opp_hand', game.view_opp_hand)
- game.is_pwr_struggle = true
-
- /* TO DELETE?
- //Check if Power Struggle is because of an event
- */
-
- if (game.vm_event > 0) {
- console.log('vm_power_struggle, in game.vm_event check')
- game.pwr_struggle_in = countries[scoring_cards.indexOf(game.vm_event)]
- log_h2(`C${game.vm_event}`)
- }
-/*
- //Otherwise set Power Struggle country normally
- else {
- console.log('vm_power_struggle, country set normally')
- game.pwr_struggle_in = countries[scoring_cards.indexOf(game.played_card)]
- log_h2(`C${game.played_card}`)
- }*/
-
-
- //Check for Securitate
- if (game.pwr_struggle_in === 'Romania' && game.persistent_events.includes(70)) {
- console.log('in Securitate subcheck')
- log('C70: Democrat reveals Power Struggle cards')
- game.view_opp_hand = true
- }
- log_h2('Deal Cards')
- game.state = 'draw_power_cards'
- console.log('game.state',game.state)
-}
-
-function vm_presidential_visit() {
- game.persistent_events.push(65)
- //game.table_cards.push(65)
- //remove_from_discard(65)
- log_msg_gap('C65 in effect')
- vm_next()
-}
-
-function vm_prudence() {
- if (!game.prudence) {
- game.prudence = {DEM: 0, COM: 0}
- }
- if (game.active === DEM) {
- game.prudence.COM --
- log(`${game.prudence.COM} to Communist ops this turn`)
- } else {
- game.prudence.DEM --
- log(`${game.prudence.DEM} to Democrat ops this turn`)}
- vm_next()
-}
-
-function vm_public_against_violence() {
- game.valid_spaces = []
- if (game.comInfl[34] > 0 ) {game.valid_spaces.push(34)}
- vm_next()
-}
-
-function vm_reformer_rehabilitated () {
- permanently_remove(67)
- game.discard = true
- for (let card of game.strategy_discard) {
- if (card === game.played_card) continue
- if (game.table_cards.includes(card)) continue
- if (scoring_cards.includes(card)) continue
-
- game.valid_cards.push(card)
- }
- game.state = 'vm_play_event_from_discard'
-}
-
-function vm_roundtable_talks() {
- game.persistent_events.push(17)
- game.table_cards.push(17)
- remove_from_discard(17)
- log_msg_gap('C17 in effect')
- vm_next()
-}
-
-function vm_sajudis_check() {
- if (!check_dem_control(56)) {
- game.valid_spaces.push(56)
- }
- if (!check_dem_control(70)) {
- game.valid_spaces.push(70)
- }
- vm_next()
-}
-
-function vm_sajudis() {
- game.playable_cards.push(81)
- game.stability++
- log('+1 VP')
- game.vp++
- if (check_vp()) {
- return
- }
- vm_next()
-}
-
-function vm_samizdat() {
- game.state = 'vm_samizdat'
-}
-
-function vm_securitate() {
- game.persistent_events.push(70)
- permanently_remove(70)
- //game.table_cards.push(70)
- vm_next()
-}
-
-function vm_shock_therapy() {
- game.state = 'vm_shock_therapy'
-}
-
-function vm_social_democratic_platform_adopted() {
- game.state = 'vm_social_democratic_platform_adopted'
-}
-
-function vm_solidarity_legalised() {
- log_msg_gap(`C2 in effect`)
- game.playable_cards.push(3)
- game.persistent_events.push(2)
- console.log('game.persistent_events', game.persistent_events)
- vm_next()
-}
-
-function vm_st_nicholas_church () {
- game.persistent_events.push(24)
- game.playable_cards.push(61)
- permanently_remove(24)
- vm_next()
-}
-
-function vm_stasi() {
- log_msg_gap('C13 in effect')
- game.persistent_events.push(13)
- vm_next()
-}
-
-function vm_stand_fast() {
- game.persistent_events.push(100)
- if (game.active === DEM) {
- game.stand_fast = DEM
- } else {game.stand_fast = COM}
- //game.table_cards.push(100)
- vm_next()
-}
-
-function vm_systematization() {
- game.state = 'vm_systematization'
-}
-
-function vm_tank_column() {
- if (game.active === DEM) {
- game.dem_tst_position++
- game.dem_tst_attempted = 0
- } else {
- game.com_tst_position++
- game.com_tst_attempted = 0
- }
- vm_next()
-}
-
-function vm_tear_gas () {
- game.persistent_events.push(30)
- game.table_cards.push(30)
- remove_from_discard(30)
- log_msg_gap('C30 in effect')
- vm_next()
-}
-
-function vm_the_baltic_way() {
- game.playable_cards.push(84)
- game.stability++
- if (!check_dem_control(56) && game.systematization !== 56) {game.valid_spaces.push(56)}
- if (!check_dem_control(70) && game.systematization !== 70) {game.valid_spaces.push(70)}
- log('+3 VP')
- game.vp += 3
- if (check_vp()) {
- return
- }
- console.log('game.state', game.state)
- vm_next()
-}
-
-function vm_the_chinese_solution() {
- game.state = 'vm_the_chinese_solution'
-}
-
-function vm_the_crowd_turns_against_ceausescu() {
- game.table_cards.push(54)
- remove_from_discard(54)
- game.playable_cards.push(97)
- vm_next()
-}
-
-function vm_the_monday_demonstrations() {
- if (!check_dem_control(6)) {game.valid_spaces.push(6)}
- if (!check_dem_control(9)) {game.valid_spaces.push(9)}
- vm_next()
-}
-
-function vm_the_sinatra_doctrine() {
- game.persistent_events.push(50)
- log_msg_gap('C50 in effect')
- vm_next()
-}
-
-function vm_the_third_way() {
- log('-2VP')
- vm_next()
-}
-
-function vm_the_tyrant_is_gone() {
- game.valid_spaces = []
- for (let i = 1; i < spaces.length; i++) {
- let space = spaces[i]
- if (game.demInfl[i] === 0 && space.country === 'Romania') {
- if (space.space_id === game.systematization) {continue}
- game.valid_spaces.push(space.space_id)
- }
- }
- /*game.playable_cards[10].playable = 0
- game.playable_cards[41].playable = 0
- game.playable_cards[101].playable = 0
- game.playable_cards[107].playable = 0*/
- console.log('game.vm_event', game.vm_event, 'game.played_card', game.played_card)
- game.state = 'vm_the_tyrant_is_gone'
-}
-
-
-function vm_the_tyrant_is_gone_prep() {
- game.table_cards.push(97)
- remove_from_discard(97)
- vm_next()
-}
-
-function vm_the_wall () {
- game.persistent_events.push(9)
- //game.strategy_removed.push(9)
- //game.table_cards.push(9)
- log_msg_gap('C9 in effect')
- vm_next()
-}
-
-function vm_the_wall_must_go() {
- game.the_wall_must_go = {}
- game.the_wall_must_go['dem_wins'] = 0
- game.the_wall_must_go['com_wins'] = 0
- game.the_wall_must_go['dem_roll'] = 0
- game.the_wall_must_go['com_roll'] = 0
- game.state = 'vm_the_wall_must_go'
-}
-
-function vm_warsaw_pact_summit() {
- game.warsaw_pact_summit = true /*What does this do? */
- game.state = 'vm_warsaw_pact_summit'
-}
-
-function vm_we_are_the_people() {
- if (game.demInfl[6] > 0) {game.valid_spaces = [6]}
- game.persistent_events.push(48)
- if (!game.vm_influence_added) {
- game.vm_influence_added = {};
- }
- game.vm_influence_added[6] = 0
- game.vm_available_ops = 4
- game.state = 'vm_we_are_the_people_remove'
-}
-
-function vm_workers_revolt() {
- if (game.active === DEM) {
- for (let space of spaces) {
- if (!space) continue
- let country = space.country
- if (!game.revolutions[find_country_index(country)] && game.comInfl[space.space_id] > 0 && space.socio === 4) {
- game.valid_spaces.push(space.space_id);
- }
- }
- } else {
- for (let space of spaces) {
- if (!space) continue
- let country = space.country
- if (game.revolutions[find_country_index(country)] && game.demInfl[space.space_id] > 0 && space.socio === 4) {
- game.valid_spaces.push(space.space_id);
- }
- }
- }
- game.state = 'vm_workers_revolt'
-}
-
-function vm_yakovlev_counsels_gorbachev() {
- game.persistent_events.push(62)
- log_msg_gap('C62 in effect')
- game.table_cards.push(62)
- remove_from_discard(62)
- vm_next()
-}
-
-function vm_permanently_remove () {
- // Check if the event is being played as the result of another card, e.g. Dash for the West, is a card which should be removed, and which hasn't already been removed!
- if (game.vm_event !== 0 && cards[game.vm_event].remove === 1 && !game.strategy_removed.includes(game.vm_event)) {
- permanently_remove(game.vm_event)
- }
- if (cards[game.played_card].remove ===1 && !game.strategy_removed.includes(game.played_card)) {
- permanently_remove(game.played_card)
- } /*This means the card that called the event being played is also removed if relevant. Think this makes sense */
- vm_next()
-}
-
-function discarded_card() {
- return game.temp > 0
-}
-
-// =================== TIANANMEN SQUARE TRACK FUNCTIONS ====================
-
-function vm_tst_3() {
- log_gap('Tiananmen Square Track award')
- game.state = 'vm_tst_3_prep'
-}
-
-function vm_tst_4() {
- log_gap('Tiananmen Square Track award')
- game.vm_available_ops = 2
- game.remove_opponent_infl = true
- game.state = 'vm_tst_4'
-}
-function vm_tst_6() {
- log_h3('Tiananmen Square Track award')
- game.vm_available_ops = 1
- game.temp = 1 //Set temp to 1, so that Card 1 is called during the support check, which has 2 ops
- game.state = 'vm_tst_6'
-}
-
-function vm_tst_8() {
- game.state = 'vm_goodbye_lenin_ops' // Use this to resolve ops.
-}
-
-// ==================== POWER STRUGGLE FUNCTIONS ======================
-
-function vm_scare_tactics() {
- game.vm_active_country = game.pwr_struggle_in
- vm_next()
-}
-function vm_support_surges() {
- game.state = 'vm_support_surges'
-}
-
-function vm_support_falters() {
- game.vm_available_ops = 2
- game.return === game.active
- game.state = 'vm_support_falters'
-}
-
-function vm_kremlin_coup_elite() {
- game.valid_spaces=[]
- elite_spaces.forEach(space => {
- if (spaces[space].country === game.vm_active_country && !check_com_control(space)) {
- game.valid_spaces.push(space);
- }
- })
- game.state = 'vm_kremlin_coup_take_control'
-}
-
-/* ================== VM STATES ============================== */
-
-states.vm_take_control = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt () {
- console.log('game.vm_available_ops', game.vm_available_ops)
- if (game.vm_available_ops > 0 && game.valid_spaces.length === 0) {
- view.prompt = `${clean_name(cards[this_card()].name)}: all spaces controlled. Continue.`
- gen_action('done')
- } else if (game.vm_available_ops > 0 ) {
- view.prompt = `${clean_name(cards[this_card()].name)}: take control of ${event_prompt()}.`
- for (let space_id of game.valid_spaces) {
- gen_action_infl(spaces[space_id].name_unique);
- }
- } else {
- view.prompt = `${clean_name(cards[this_card()].name)}. Take control: done.`
- gen_action('done')
- }
- },
- infl(space) {
- push_undo()
- vm_take_control(space)
- game.vm_available_ops--
- if (game.vm_available_ops === 0) {
- vm_next()
- }
- },
- done() {
- vm_next()
- }
-}
-
-states.vm_add_infl = {
- inactive: 'add Support Points.',
- prompt () {
- console.log('in vm add infl')
- if (game.vm_available_ops > 0 && game.valid_spaces.length === 0 ) {
- view.prompt = 'No available spaces remaining. Add SPs: done.'
- gen_action('done')
- }
- else if (game.vm_available_ops > 0 ) {
- view.prompt = `${clean_name(cards[this_card()].name)}: add ${pluralize(game.vm_available_ops,'SP')}${event_prompt()}.`
-
- for (let space_id of game.valid_spaces) {
- gen_action_infl(spaces[space_id].name_unique)
- }
- } else {
- view.prompt = 'Add SP: done.'
- gen_action('done')
- }
- },
- infl(space) {
- vm_do_add_infl(space)
- },
- done () {
- if (game.summary.length > 0) {
- pop_summary()
- log_br()
- }
-
- game.vm_event_done = true
- vm_next()
- }
-}
-
-states.vm_add_infl_free = {
- get inactive() {
- return `resolve ${clean_name(cards[this_card()].name)}: add SPs.`
- },
- prompt () {
- if (game.vm_available_ops > 0 && game.valid_spaces.length === 0 ) {
- view.prompt = 'No available spaces remaining. Add SPs: done.'
- gen_action('done')
- }
- else if (game.vm_available_ops > 0 ) {
- view.prompt = `${clean_name(cards[this_card()].name)}: add ${game.vm_available_ops} SPs to ${event_prompt()}.`
-
- for (let space_id of game.valid_spaces) {
- gen_action_infl(spaces[space_id].name_unique);
- }
- } else {
- view.prompt = `${clean_name(cards[this_card()].name)}. Add influence: done.`
- gen_action('done')
- }
- },
- infl(space) {
- vm_do_add_infl_free(space)
- /*if (game.vm_available_ops === 0 ) {
-
- }*/
- },
- done () {
- game.valid_spaces = []
- game.vm_event_done = true
- if (game.summary.length > 0) {
- pop_summary()
- log_br()
- }
- vm_next()
- }
-}
-
-states.vm_add_x_infl = {
- get inactive() {
- return `resolve ${clean_name(cards[this_card()].name)}: add Support Points.`
- },
-// inactive: `resolve ${cards[this_card()].name}: add influence.`,
- prompt () {
- if (game.vm_available_ops > 0 ) {
- view.prompt = `${clean_name(cards[this_card()].name)}: Add ${game.vm_available_ops} SPs to ${event_prompt()}.`
-
- for (let space_id of game.valid_spaces) {
- gen_action_infl(spaces[space_id].name_unique)
- }
- } else {
- view.prompt = `${clean_name(cards[this_card()].name)}. Add influence: done.`
- gen_action('done')
- }
- },
- infl(space) {
- push_undo()
- vm_do_add_x_infl(space)
- //game.vm_event_done = true
- //vm_next()
- },
- done () {
- game.vm_event_done = true
- vm_next()
- }
-}
-
-states.vm_add_limited_infl = {
- get inactive() {
- return `resolve ${clean_name(cards[this_card()].name)}: add Support Points.`
- },
- prompt () {
- if (game.vm_available_ops > 0 && game.valid_spaces.length > 0) {
- if (game.vm_max_infl === 1) {
- view.prompt = `${clean_name(cards[this_card()].name)}: add ${pluralize(game.vm_max_infl,'SP')} ${event_prompt()}.`
- }
- else {
- view.prompt = `${clean_name(cards[this_card()].name)}: add ${pluralize(game.vm_available_ops,'SP')} to ${event_prompt()}.`
- }
- for (let space_id of game.valid_spaces) {
- gen_action_infl(spaces[space_id].name_unique);
- }
- } else {
- view.prompt = `${clean_name(cards[this_card()].name)}. Add SPs: done.`
- gen_action('done')
- }
- },
- infl(space) {
- vm_do_add_limited_infl(space, game.vm_max_infl)
- /*if (game.vm_available_ops === 0 || game.valid_spaces.length === 0) {
- game.vm_event_done = true
- if (game.summary.length > 0) {
- pop_summary()
- log_br()
- }
- vm_next()
- }*/
- /*if (game.vm_available_ops === 0 || game.valid_spaces.length === 0 ) {
- if (game.summary.length > 0) {
- pop_summary()
- log_br()
- }
- game.vm_event_done = true
- vm_next()
- }*/
- },
- done () {
- if (game.summary.length > 0) {
- pop_summary()
- log_br()
- }
- game.vm_event_done = true
- vm_next()
- }
-}
-
-states.vm_remove_infl = {
- inactive: 'remove Support Points.',
- prompt () {
- // Keep this so that there is an undo option in, e.g., Scare Tactics
- if (game.valid_spaces.length === 0 && game.vm_available_ops > 0) {
- view.prompt = `${clean_name(cards[this_card()].name)}: no further SPs to remove.`
- gen_action('done')
- return
- }
- if (game.vm_available_ops === 0 ) {
- view.prompt = `${clean_name(cards[this_card()].name)}. Remove SPs: done.`
- gen_action('done')
- return
- }
- if (game.remove_opponent_infl) {
- view.prompt = `${clean_name(cards[this_card()].name)}: remove ${pluralize(game.vm_available_ops, 'opponent SP')}${event_prompt()}.`
- }
- else {
- view.prompt = `${clean_name(cards[this_card()].name)}: remove ${pluralize(game.vm_available_ops,'SP')}${event_prompt()}.`
- }
- for (let space_id of game.valid_spaces) {
- gen_action_infl(spaces[space_id].name_unique);
- }
- },
- infl(space) {
- push_undo()
- vm_do_remove_infl(space)
- const clicked_space = find_space_index(space)
- game.vm_active_country = spaces[clicked_space].country
- /*if (game.vm_available_ops === 0 || game.valid_spaces.length === 0) {
- vm_next()
- }*/
- },
- done() {
- if (game.summary.length > 0) {
- pop_summary()
- log_br()
- }
- vm_next()
- }
-}
-
-
-states.vm_remove_x_infl = {
- get inactive() {
- return `resolve ${clean_name(cards[this_card()].name)}: remove SP from ${event_prompt()}.`
- },
- prompt () {
- if (game.valid_spaces.length === 0 && game.vm_available_ops > 0) {
- view.prompt = `${clean_name(cards[this_card()].name)}: no SPs to remove.`
- gen_action('done')
- } else if (game.vm_available_ops > 0) {
-
- view.prompt = `${clean_name(cards[this_card()].name)}: remove ${pluralize(game.vm_available_ops,'SP')} from ${event_prompt()}.`
-
- for (let space_id of game.valid_spaces) {
- gen_action_infl(spaces[space_id].name_unique);
- }
- } else {
- view.prompt = `${clean_name(cards[this_card()].name)}. Remove influence: done.`
- gen_action('done')
- }
- },
- infl(space) {
- vm_do_remove_x_infl(space)
- /*game.vm_event_done = true
- vm_next()*/
- },
- done () {
- game.vm_event_done = true
- vm_next()
- }
-}
-
-states.vm_remove_limited_infl = {
- inactive: 'remove SP.',
- prompt () {
- if (game.vm_available_ops > 0 && game.valid_spaces.length > 0) {
- view.prompt = `${clean_name(cards[this_card()].name)}: remove ${game.vm_available_ops} SP${event_prompt()}, no more than ${game.vm_max_infl} per space.`
-
- for (let space_id of game.valid_spaces) {
- gen_action_infl(spaces[space_id].name_unique);
- }
- } else if (game.valid_spaces.length === 0) {
- view.prompt = `${clean_name(cards[this_card()].name)}: no further SP to remove.`
- gen_action('done')
- }
- },
- infl(space) {
- vm_do_remove_limited_infl(space, game.vm_max_infl)
- /*if (game.vm_available_ops === 0) {
- game.vm_event_done = true
- } */
- },
- done () {
- game.vm_event_done = true
- if (game.summary.length > 0) {
- pop_summary()
- log_br()
- }
- vm_next()
- }
-}
-
-states.vm_remove_all_infl = {
- inactive: 'remove Support Points',
- prompt () {
- if (game.valid_spaces.length === 0 && game.vm_available_ops > 0) {
- view.prompt = `${clean_name(cards[this_card()].name)}: no SPs to remove.`
- gen_action('done')
- } else if (game.vm_available_ops > 0) {
- view.prompt = `${clean_name(cards[this_card()].name)}: remove all SPs from ${event_prompt()}.`
- for (let space_id of game.valid_spaces) {
- gen_action_infl(spaces[space_id].name_unique);
- }
- } else {
- view.prompt = `${clean_name(cards[this_card()].name)}. Remove SPs: done.`
- gen_action('done')
- }
- },
- infl(space) {
- vm_do_remove_all_infl(space)
- const clicked_space = find_space_index(space)
- game.vm_active_country = spaces[clicked_space].country
- /*if (game.vm_available_ops === 0 || game.valid_spaces.length === 0) {
- vm_next()
- }*/
- },
- done() {
- vm_next()
- }
-}
-
-states.vm_support_check_prep = {
- inactive: 'do support checks.',
- prompt () {
- console.log('in states.vm_support_check_prep, game.vm_available_ops: ', game.vm_available_ops)
- if (game.vm_available_ops === 0) {
- view.prompt = `${clean_name(cards[this_card()].name)}. Support check: done.`
- gen_action('done')
- } else if (game.valid_spaces.length === 0) {
- view.prompt = `${clean_name(cards[this_card()].name)}: no valid targets for support check.`
- gen_action('done')
- } else {
- if (game.vm_available_ops > 0) {
- view.prompt = `${clean_name(cards[this_card()].name)}: ${event_prompt()}. ${pluralize(game.vm_available_ops, 'support check')} remaining.`
- }
- for (let space_id of game.valid_spaces) {
- if (!space_id) continue
- gen_action_sc(spaces[space_id].name_unique);
- }
- }
- },
- sc(space) {
- push_undo()
- game.selected_space = find_space_index(space)
-
- // Check for Austria-Hungary Border Reopened - check on first support check only
- //First check for Monday Demonstrations - support checks will always be in East Germany
- if (game.vm_event === 61 && game.persistent_events.includes(58)) {
- game.austria_hungary_border_reopened_tracker = true
- game.state = 'vm_do_support_check'
- return
- }
-
- //Then check Austria-Hungary Border Reopened normally
- //console.log('game.austria_hungary_border_reopened_checked', game.austria_hungary_border_reopened_checked)
- if (game.persistent_events.includes(58)) {
- if (game.active === DEM && game.vm_available_ops > 1) {
- if (spaces[game.selected_space].country === 'East_Germany' && game.persistent_events.includes(58) && game.active === DEM) {
- game.state = 'vm_austria_hungary_border_reopened_check'
- return
- }
- //game.state = 'do_support_check'
- } /*else { */
- }
- game.state = 'vm_do_support_check'
- },
- done () {
- game.vm_available_ops = 0
- vm_next ()
- }
-}
-
-states.vm_ceh_support_check_prep = {
- inactive: 'do support checks.',
- prompt () {
- if (game.vm_available_ops === 0) {
- view.prompt = 'Support checks: done.'
- gen_action('done')
- //return
- }
- if (game.vm_available_ops > 0) {
- view.prompt = `Select a space. ${pluralize(game.vm_available_ops, 'support check')} remaining.`
-
- for (let space_id of game.valid_spaces) {
- gen_action_sc(spaces[space_id].name_unique)
- }
- }
- },
- sc(space) {
- push_undo()
- game.selected_space = find_space_index(space)
-
- //Then check Austria-Hungary Border Reopened normally
- //console.log('game.austria_hungary_border_reopened_checked', game.austria_hungary_border_reopened_checked)
- if (game.persistent_events.includes(58)) {
- if (game.active === DEM && game.vm_available_ops > 1) {
- console.log('in ahb check, country, ', spaces[game.selected_space].country, 'ahb', game.persistent_events.includes(58))
- if (spaces[game.selected_space].country === 'East_Germany' && game.persistent_events.includes(58) && game.active === DEM) {
- game.state = 'vm_austria_hungary_border_reopened_check'
- return
- }
- //game.state = 'do_support_check'
- } /*else { */
- }
- game.state = 'vm_ceh_do_support_check'
- },
- done () {
- vm_next ()
- }
-}
-
-
-states.vm_ceh_do_support_check = {
- inactive: 'do support checks.',
- prompt () {
- view.prompt = `Support check: ${spaces[game.selected_space].name_unique}. Roll a die.`
- gen_action('roll')
- },
- roll() {
- clear_undo()
- do_sc(spaces[game.selected_space].name_unique)
-
- game.vm_available_ops--
- if (game.vm_available_ops === 0) {
- game.valid_spaces = []
- }
- game.state = 'vm_ceh_support_check_prep'
- return
- }
-}
-
-states.vm_austria_hungary_border_reopened_check = {
- inactive: 'decide Austria-Hungary Border Reopened',
- prompt() {
- view.prompt = 'Austria-Hungary Border Reopened: will all support checks be in East Germany?'
- gen_action('yes')
- gen_action('no')
- },
- yes() {
- game.austria_hungary_border_reopened_tracker = true
- game.state = 'vm_do_support_check'
- },
- no() {
- game.state = 'vm_do_support_check'
- }
-}
-
-states.vm_1_support_check_prep = {
- inactive: 'do support checks.',
- prompt () {
- if (game.vm_available_ops === 0) {
- view.prompt = `${clean_name(cards[this_card()].name)}. Support check: done.`
- gen_action('done')
- } else if (game.valid_spaces.length === 0) {
- view.prompt = `${clean_name(cards[this_card()].name)}: no valid targets for support check.`
- gen_action('done')
- } else {
- view.prompt = `${clean_name(cards[this_card()].name)}: ${event_prompt()}.`
-
- for (let space_id of game.valid_spaces) {
- if (!space_id) continue
- gen_action_sc(spaces[space_id].name_unique);
- }
- }
- },
- sc(space) {
- push_undo()
- game.selected_space = find_space_index(space)
- game.state = 'vm_do_support_check'
- },
- done () {
- game.vm_available_ops = 0
- vm_next ()
- }
-}
-
-states.vm_do_support_check = {
- inactive: 'do support checks.',
- prompt () {
- view.prompt = `Support check: ${spaces[game.selected_space].name_unique}. Roll a die.`
- gen_action('roll')
- },
- roll() {
- clear_undo()
- do_sc(spaces[game.selected_space].name_unique)
- game.vm_available_ops--
- if (game.vm_available_ops === 0) {
- game.valid_spaces = []
- }
- game.state = 'vm_support_check_prep'
- return
- }
-}
-
-states.vm_tiananmen_square_attempt = {
- inactive: 'do Tiananmen Square',
- prompt () {
- if (game.active === DEM && game.dem_tst_attempted_this_turn > 0 || game.active === COM && game.com_tst_attempted_this_turn > 0) {
- view.prompt = 'Tiananmen Square Track attempt: done.'
- gen_action('done')
- return
- }
- view.prompt = 'Roll a die'
- gen_action('roll')
- },
- roll() {
- clear_undo()
- do_tst_attempt ()
- },
- done () {
- vm_next()
- }
-}
-
-//================================== EVENT SPECIFIC STATES ======================================
-
-states.vm_adamec = {
- get inactive() {
- return `resolve ${clean_name(cards[88].name)}.`
- },
- prompt() {
- view.prompt = 'Adamec: roll a die.'
- gen_action('roll')
- },
- roll() {
- clear_undo()
- let roll = Math.floor(Math.random() * 6) + 1
- log(`Rolled a ${roll}`)
- let worker_spaces = spaces.filter(space => space && space.country === 'Czechoslovakia' && space.socio === 4 && check_dem_control(space.space_id)).length
- if (worker_spaces > 0) {
- log(`-${worker_spaces} from Democrat controlled worker spaces`)
- roll -= worker_spaces
- }
- log(`Modified roll: ${roll}`)
- if (roll > 2) {
- log('Adamec succeeds')
- vm_next()
- return
- }
- log('Adamec fails: 3 or more required')
- permanently_remove(88)
- vm_return()
- }
-}
-
-states.vm_brought_in_for_questioning = {
- inactive: 'discard a card.',
- prompt() {
- if (game.phase === 1) {
- view.prompt = 'Discard a card: done.'
- gen_action('done')
- } else if (game.democrat_hand.length === 0) {
- view.prompt = 'Brought in for Questioning. No cards to discard.'
- gen_action('pass')
- } else {
- view.prompt = 'Brought in for Questioning: you must discard a random card.'
- gen_action('discard')
- }
- },
- discard() {
- game.vm_event = discard_card(game.democrat_hand)
- game.phase = 1
- if (cards[game.vm_event].side === 'C' && (cards[game.vm_event].playable || game.playable_cards.includes(game.vm_event))) {
- //game.return = game.active
- if (!game.vm_infl_to_do) {
- if(game.round_player === DEM) {
- game.return = COM
- } else {
- game.return = DEM
- }
- }
- console.log('BIFQ discard: game.return', game.return)
- if (!auto_resolve_events.includes(game.vm_event) && !switch_events.includes(game.vm_event)) {
- next_player()
- }
- goto_vm(game.vm_event)
- } else {
- game.return = DEM
- }
- },
- pass() {
- log('No cards to discard')
- vm_return()
- },
- done() {
- vm_return()
- }
-}
-
-states.vm_central_committee_reshuffle = {
- get inactive() {
- return `resolve ${clean_name(cards[57].name)}.`
- },
- prompt() {
- view.prompt = 'Choose a country to add SP.'
- if (!game.revolutions[0]) {gen_action('poland')}
- if (!game.revolutions[1]) {gen_action('hungary')}
- if (!game.revolutions[2]) {gen_action('east_germany')}
- if (!game.revolutions[3]) {gen_action('bulgaria')}
- if (!game.revolutions[4]) {gen_action('czechoslovakia')}
- if (!game.revolutions[5]) {gen_action('romania')}
- },
- east_germany() {
- game.vm_active_country = "East_Germany"
- log(`Chose ${country_name(game.vm_active_country)}`)
- game.valid_spaces = [1,2,3,4,5,6,7,8,9,10,11,12]
- vm_next()
- },
- poland() {
- game.vm_active_country = "Poland"
- log(`Chose ${country_name(game.vm_active_country)}`)
- game.valid_spaces = [13,14,15,16,17,18,19,20,21,22,23,24,25,26]
- vm_next()
- },
- czechoslovakia() {
- game.vm_active_country = "Czechoslovakia"
- log(`Chose ${country_name(game.vm_active_country)}`)
- game.valid_spaces = [27,28,29,30,31,32,33,34,35,36,37]
- vm_next()
- },
- hungary() {
- game.vm_active_country = "Hungary"
- log(`Chose ${country_name(game.vm_active_country)}`)
- game.valid_spaces = [38,39,40,41,42,43,44,45,46,47,48,49]
- vm_next()
- },
- romania() {
- game.vm_active_country = "Romania"
- log(`Chose ${country_name(game.vm_active_country)}`)
- game.valid_spaces = [50,51,52,53,54,55,56,57,58,59,60,61,62,63]
- game.valid_spaces = game.valid_spaces.filter(space => space !== game.systematization)
- vm_next()
- },
- bulgaria () {
- game.vm_active_country = "Bulgaria"
- log(`Chose ${country_name(game.vm_active_country)}`)
- game.valid_spaces = [64,65,66,67,68,69,70,71,72,73,74,75]
- vm_next()
- },
-
-}
-
-states.vm_common_european_home_choose = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- view.prompt = `Common European Home: play an opponent's card, event does not occur.`
- for (let card of game.valid_cards) {
- gen_action_card(card)
- }
- },
- card(card) {
- push_undo()
- log(`Played with C${cards[card].number}`)
- game.valid_cards = []
- silent_discard(card)
- game.vm_event = card
- game.state = 'vm_common_european_home_play'
- }
-}
-
-states.vm_common_european_home_play = {
- get inactive() {
- return `resolve ${clean_name(cards[this_card()].name)}.`
- },
- prompt() {
- view.prompt = `Play ${clean_name(cards[this_card()].name)} for:`
- gen_action('influence')
- gen_action('support_check')
- if (game.active === DEM && game.vm_event === 87 ) {
- return /*Special condition if card is actually Kohl Proposes Reunification*/
- }
- if (game.active === DEM && game.dem_tst_attempted_this_turn === 0 || game.active === COM && game.com_tst_attempted_this_turn === 0) {
- gen_action('tst')
- }
- },
- influence(){
- push_undo()
- game.vm_available_ops = cards[game.vm_event].ops
- valid_spaces_infl()
- // If ABHR - Set AHBR tracker to true
- if (game.persistent_events.includes(58)) {
- game.austria_hungary_border_reopened_tracker = true
- }
- game.state = 'vm_add_infl'
- },
- support_check() {
- push_undo()
- game.vm_available_ops = 2
- game.state = 'vm_ceh_support_check_prep'
- valid_spaces_sc()
- },
- tst() {
- game.state = 'vm_tiananmen_square_attempt'
- }
-}
-
-states.vm_dash_for_the_west = {
- get inactive() {
- return `resolve ${clean_name(cards[36].name)}.`
- },
- prompt() {
- /* if (game.phase === 1) {*/
- view.prompt = 'Dash for the West: roll a die'
- gen_action('roll')
- /*} else {
- view.prompt = 'Dash for the West: roll a die. Done.'
- gen_action('done')
- }*/
- },
- roll() {
- clear_undo()
- let roll = Math.floor(Math.random() * 6) + 1
- log(`Rolled a ${roll}`)
- let com_control = check_presence('East_Germany').com_spaces
-
- if (roll > com_control) {
- log(`Success. More than the ${com_control} Communist controlled spaces in East Germany`)
- log('+1 VP')
- game.vp++
- if (check_vp()) {
- return
- }
- game.discard = true
- game.state = 'vm_play_event_from_discard'
- } else {
- log(`Fail: more than a ${com_control} required`)
- //game.phase++
- vm_next()
- }
- },/*
- done() {
- vm_next()
- }*/
-}
-
-states.vm_play_event_from_discard = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- if (game.valid_cards.length === 0) {
- view.prompt = `${clean_name(cards[this_card()].name)}: no valid cards in discard.`
- gen_action('pass')
- } else if (game.temp === 0) {
- view.prompt = `${event_prompt()}.`
- for (let card of game.valid_cards) {
- gen_action('pass')
- gen_action_card(card)
- }
- } else {
- view.prompt = 'Choose a card: done.'
- gen_action('done')
- }
- },
- card(card) {
- push_undo()
- log(`Chose C${cards[card].number}`)
- game.vm_event = card
- game.vm_available_ops = cards[card].ops
- game.discard = false
- //game.return = game.active Does turning this off cause problems?
- console.log('card:', card)
- if (switch_events.includes(card)) {next_player()}
- goto_vm(card)
- },
- pass(){
- push_undo()
- if (game.valid_cards.length === 0) {
- log('No valid cards to choose')
- } else{
- log('Did not choose a card')
- }
- vm_next()
- },
- done(){
- game.discard = false
- vm_next()
- }
-}
-
-states.vm_deutsche_marks_prep = {
- inactive: 'choose a card.',
- prompt() {
- if (game.valid_cards.length === 0) {
- view.prompt = 'Deutsche Marks: no cards to give.'
- gen_action('pass')
- } else {
- view.prompt = 'Deutsche Marks: choose a card to give.'
- for (let card of game.valid_cards) {
- gen_action_card(card)
- }
- }
- },
- card(card) {
- push_undo()
- log(`Gave C${cards[card].number}`)
- game.valid_cards = []
- silent_discard(card)
- //next_player()
- game.state = 'vm_deutsche_marks_confirm'
- game.vm_event = card
- },
- pass() {
- vm_next()
- }
-}
-
-states.vm_deutsche_marks_confirm = {
- inactive: 'choose a card.',
- prompt() {
- view.prompt = `Deutsche Marks: gave ${cards[game.vm_event].name}.`
- gen_action('done')
- },
- done() {
- next_player()
- game.state = 'vm_deutsche_marks'
- }
-}
-
-states.vm_deutsche_marks = {
- get inactive() {
- return `resolve ${clean_name(cards[20].name)}.`
- },
- prompt() {
- if(cards[game.vm_event].side === 'C' && (cards[game.vm_event].playable || game.playable_cards.includes(game.vm_event))) {
- view.prompt = `Deutsche Marks: you must play ${clean_name(cards[this_card()].name)} for the event.`
- gen_action('event')
- } else {
- view.prompt = `Deutsche Marks: play ${clean_name(cards[this_card()].name)} for:`
- gen_action('influence')
- gen_action('support_check')
- if (game.com_tst_attempted_this_turn === 0) {
- gen_action('tst')
- }
- }
- },
- event() {
- log(`Played C${cards[game.vm_event].number} for the event`)
- console.log('game.active', game.active)
- if (!game.vm_infl_to_do) {
- game.return = game.active
- }
- console.log('DM Event played, game.return', game.return)
- goto_vm(game.vm_event)
- },
- influence() {
- push_undo()
- log(`Played C${cards[game.vm_event].number} to place SPs`)
- game.vm_available_ops = get_card_ops(game.vm_event)
-
- /*cards[game.vm_event].ops
- if (game.persistent_events.includes(25)) {game.vm_available_ops++ }
- if (game.prudence.COM && game.prudence.COM < 0 ) {
- game.vm_available_ops += game.prudence.COM
- }*/
- valid_spaces_infl()
- game.state = 'vm_add_infl'
- },
- support_check() {
- push_undo()
- log_gap(`Played C${cards[game.vm_event].number} for support checks`)
- game.vm_available_ops = 2
- game.state='vm_support_check_prep'
- valid_spaces_sc()
- },
- tst() {
- push_undo()
- log_gap(`Played C${cards[game.vm_event].number} to the Tiananmen Square Track`)
- game.state='vm_tiananmen_square_attempt'
- }
-}
-
-states.vm_exit_visas = {
- get inactive() {
- return `resolve ${clean_name(cards[75].name)}.`
- },
- prompt() {
- view.prompt = 'Exit Visas: you may discard cards from your hand and draw replacements.'
- for (let card of game.democrat_hand) {
- gen_action_card(card)
- }
- if (game.temp === 0) {
- gen_action('pass')
- } else {
- gen_action('done')
- }
- },
- card(card){
- push_undo()
- discard(card)
- game.temp++
- },
- pass() {
- push_undo()
- game.state = 'vm_exit_visas_finish'
- },
- done() {
- push_undo()
- game.state = 'vm_exit_visas_finish'
- }
-}
-
-states.vm_exit_visas_finish = {
- get inactive() {
- return `resolve ${clean_name(cards[75].name)}.`
- },
- prompt() {
- if (game.temp > 0 ) {
- view.prompt = 'Draw replacement cards.'
- gen_action('draw')
- } else {
- view.prompt = 'Exit Visas: done.'
- gen_action('done')
- }
- },
- draw() {
- clear_undo()
- draw_cards(game.strategy_deck, game.democrat_hand, game.communist_hand, game.democrat_hand.length + game.temp, game.communist_hand.length)
- game.temp = 0
- },
- done() {
- vm_next()
- }
-}
-
-states.vm_foreign_currency_debt_burden = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- view.prompt = 'Choose a country. The Communist may not make support checks there for the rest of the turn.'
- gen_action('east_germany')
- gen_action('poland')
- gen_action('czechoslovakia')
- gen_action('hungary')
- gen_action('bulgaria')
- },
- east_germany() {
- push_undo()
- game.foreign_currency_debt_burden = 'East_Germany'
- log('Selected East Germany')
- vm_next()
- },
- poland() {
- push_undo()
- game.foreign_currency_debt_burden = 'Poland'
- log('Selected Poland')
- vm_next()
- },
- czechoslovakia() {
- push_undo()
- game.foreign_currency_debt_burden = 'Czechoslovakia'
- log('Selected Czechoslovakia')
- vm_next()
- },
- hungary() {
- push_undo()
- game.foreign_currency_debt_burden = 'Hungary'
- log('Selected Hungary')
- vm_next()
- },
- bulgaria() {
- push_undo()
- game.foreign_currency_debt_burden = 'Bulgaria'
- log('Selected Bulgaria')
- vm_next()
- }
-}
-
-states.vm_goodbye_lenin = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- console.log('in vm_goodbye lenin')
- if (game.valid_cards.length > 0 ) {
- view.prompt = 'Choose a card to play for the event, or play Goodbye Lenin for operations'
- for (let card of game.valid_cards) {
- gen_action_card(card)
- gen_action('ops')
- }
- } else {
- view.prompt = 'Communist has no valid cards. Play Goodbye Lenin for operations.'
- gen_action('ops')
- }
- },
- card(card) {
- push_undo()
- log(`Chose to play C${card} for the event`)
- let card_index = game.communist_hand.indexOf(card)
- game.communist_hand.splice(card_index, 1)
- game.vm_event = card
- game.view_opp_hand = false
- goto_vm(card)
- },
- ops() {
- log('C46 played for operations')
- game.view_opp_hand = false
- game.state = 'vm_goodbye_lenin_ops'
- }
-}
-
-states.vm_goodbye_lenin_ops = {
- get inactive() {
- return `resolve ${clean_name(cards[this_card()].name)}.`
- },
- prompt() {
- view.prompt = `Play ${clean_name(cards[this_card()].name)} for:`
- gen_action('influence')
- gen_action('support_check')
- if ((game.active === DEM && game.dem_tst_attempted_this_turn === 0 ) || (game.active === COM && game.com_tst_attempted_this_turn === 0 )) {
- gen_action('tst')
- }
- },
- influence(){
- push_undo()
- game.vm_available_ops = get_card_ops(this_card())
- /*if (game.persistent_events.includes(50)) {
- log(`+1 from C50`)
- game.vm_available_ops++
- }*/
- console.log('goodbye lenin: influence selected')
- valid_spaces_infl()
-
- // If ABHR - Set AHBR tracker to true
- if (game.persistent_events.includes(58)) {
- game.austria_hungary_border_reopened_tracker = true
- }
- game.state = 'vm_add_infl'
- },
- support_check() {
- push_undo()
- game.vm_available_ops = 2
- game.state = 'vm_support_check_prep'
- valid_spaces_sc()
- },
- tst() {
- game.state = 'vm_tiananmen_square_attempt'
- }
-}
-
-states.vm_honecker = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- if (game.valid_cards.length === 0 && game.temp === 0) {
- view.prompt = 'Honecker: no valid cards to choose.'
- gen_action('done')
- } else
- if (game.temp === 0) {view.prompt = 'Honecker: choose a card to add to your hand.'
- for (let card of game.valid_cards) {
- gen_action_card(card)
- gen_action('pass')
- }
- } else {
- view.prompt = 'Honecker. Choose a card: done.'
- gen_action('done')
- }
- },
- card(card) {
- push_undo()
- game.valid_cards = []
- log(`Took C${cards[card].number} into hand`)
- game.temp = card
- let card_index = game.strategy_discard.indexOf(card)
- game.strategy_discard.splice(card_index, 1)
- game.communist_hand.push(card)
- console.log('removed after honecker', game.strategy_removed)
- },
- pass(){
- log('Did not take a card')
- vm_next()
- },
- done(){
- if (game.temp === 0) {
- log('Did not take a card')
- }
- game.discard = false
- vm_next()
- }
-
-}
-
-states.vm_inflationary_currency = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- console.log('game.revolutions', game.revolutions, 'length', game.revolutions.length)
- if (game.revolutions.every(n => n === false)) {
- view.prompt = 'Inflationary Currency: no countries to choose.'
- gen_action('pass')
- } else {
- view.prompt = 'Inflationary Currency: choose a country where your opponent has power.'
- if (game.active === DEM) {
- if (!game.revolutions[0]) {gen_action('poland')}
- if (!game.revolutions[1]) {gen_action('hungary')}
- if (!game.revolutions[2]) {gen_action('east_germany')}
- if (!game.revolutions[3]) {gen_action('bulgaria')}
- if (!game.revolutions[4]) {gen_action('czechoslovakia')}
- if (!game.revolutions[5]) {gen_action('romania')}
- } else {
- if (game.revolutions[0]) {gen_action('poland')}
- if (game.revolutions[1]) {gen_action('hungary')}
- if (game.revolutions[2]) {gen_action('east_germany')}
- if (game.revolutions[3]) {gen_action('bulgaria')}
- if (game.revolutions[4]) {gen_action('czechoslovakia')}
- if (game.revolutions[5]) {gen_action('romania')}
- }
- }
- },
- east_germany() {
- push_undo()
- game.vm_active_country = 'East_Germany'
- log(`Chose ${country_name(game.vm_active_country)}`)
- vm_next()
- },
- poland() {
- push_undo()
- game.vm_active_country = 'Poland'
- log(`Chose ${country_name(game.vm_active_country)}`)
- vm_next()
- },
- czechoslovakia() {
- push_undo()
- game.vm_active_country = 'Czechoslovakia'
- log(`Chose ${country_name(game.vm_active_country)}`)
- vm_next()
- },
- hungary() {
- push_undo()
- game.vm_active_country = 'Hungary'
- log(`Chose ${country_name(game.vm_active_country)}`)
- vm_next()
- },
- romania() {
- push_undo()
- game.vm_active_country = 'Romania'
- log(`Chose ${country_name(game.vm_active_country)}`)
- vm_next()
- },
- bulgaria () {
- push_undo()
- game.vm_active_country = 'Bulgaria'
- log(`Chose ${country_name(game.vm_active_country)}`)
- vm_next()
- },
- pass() {
- log('Passed')
- vm_return()
- }
-}
-
-states.vm_inflationary_currency_discard = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- if (game.valid_cards.length === 0 ) {
- view.prompt = 'Inflationary Currency: no valid cards to discard. You must pass.'
- gen_action('pass')
- } else if (game.temp === 0 ) {
- view.prompt = 'Inflationary Currency: you may discard a 3 op or higher value card to cancel the support check.'
- gen_action('pass')
- for (let card of game.valid_cards) {
- gen_action_card(card)
- }
- } else {
- view.prompt = 'Discard a card: done.'
- gen_action('done')
- }
- },
- card(card) {
- push_undo()
- discard(card)
- game.temp = card
- },
- pass() {
- log('Did not discard')
- next_player()
- game.vm_available_ops = 1
- vm_next()
- //game.state = 'vm_support_check_prep'
- },
- done() {
- if (!game.vm_infl_to_do) {
- if(game.round_player === DEM) {
- game.return = COM
- } else {
- game.return = DEM
- }
- }
- vm_next()
- }
-}
-
-
-states.vm_kiss_of_death = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- if (game.communist_hand.length === 0) {
- view.prompt = 'Kiss of Death. No cards to discard.'
- gen_action('pass')
- } else {
- view.prompt = 'Kiss of Death: you must randomly discard a card.'
- gen_action('discard')
- }
- },
- discard() {
- game.vm_event = discard_card(game.communist_hand)
- next_player()
- game.state = 'vm_kiss_of_death_finish'
- },
- pass() {
- log('No card to discard')
- vm_next()
- }
-}
-
-states.vm_kiss_of_death_finish = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- console.log('game.vm_event', game.vm_event)
- if (game.vm_event > 0 && game.vm_event !== 21 && (cards[game.vm_event].side === 'D' || cards[game.vm_event].side === 'N')) {
- view.prompt = `Play ${clean_name(cards[game.vm_event].name)} for the event.`
- console.log('kiss of death before event button: game.stategy_discard', game.strategy_discard)
- gen_action('event')
- } else {
- view.prompt = 'Event does not occur.'
- gen_action('done')
- }
- },
- event() {
- //game.return = game.active
- console.log('kiss of death event section, discard', game.strategy_discard)
- // Remove game.vm_event from the discard
- //game.strategy_discard = game.strategy_discard.filter(n => n !== game.vm_event)
- console.log('kiss of death event section 2, discard', game.strategy_discard)
-
- goto_vm(game.vm_event)
- },
- done() {
- vm_next()
- }
-}
-
-states.vm_kremlin_coup_choose_country = {
- get inactive() {
- return `resolve ${clean_name(cards[this_card()].name)}.`
- },
- prompt() {
- if (game.temp.length > 0) {
- view.prompt = 'Kremlin Coup! Select a country where the Communist retains power.'
- for (let country of countries) {
- console.log(`checking`, country)
- if (game.temp.includes(country)) {
- console.log('country in game.temp')
- gen_action(`${country.toLowerCase()}`)
- }
- }
- } else {
- view.prompt = 'Kremlin Coup! There are no countries where the Communist retains power.'
- gen_action('done')
- }
- },
- east_germany() {
- push_undo()
- game.vm_active_country = 'East_Germany'
- game.temp = game.temp.filter(country => country !== game.vm_active_country)
- log(`${country_name(game.vm_active_country)}:`)
- vm_kremlin_coup_elite()
- },
- poland() {
- push_undo()
- game.vm_active_country = 'Poland'
- log(`${country_name(game.vm_active_country)}:`)
- game.temp = game.temp.filter(country => country !== game.vm_active_country)
- vm_kremlin_coup_elite()
- },
- czechoslovakia() {
- push_undo()
- game.vm_active_country = 'Czechoslovakia'
- log(`${country_name(game.vm_active_country)}:`)
- game.temp = game.temp.filter(country => country !== game.vm_active_country)
- vm_kremlin_coup_elite()
- },
- hungary() {
- push_undo()
- game.vm_active_country = 'Hungary'
- log(`${country_name(game.vm_active_country)}:`)
- game.temp = game.temp.filter(country => country !== game.vm_active_country)
- vm_kremlin_coup_elite()
- },
- romania() {
- push_undo()
- game.vm_active_country = 'Romania'
- log(`${country_name(game.vm_active_country)}:`)
- game.temp = game.temp.filter(country => country !== game.vm_active_country)
- vm_kremlin_coup_elite()
- },
- bulgaria () {
- push_undo()
- game.vm_active_country = 'Bulgaria'
- log(`${country_name(game.vm_active_country)}:`)
- game.temp = game.temp.filter(country => country !== game.vm_active_country)
- vm_kremlin_coup_elite()
- },
- done() {
- game.temp = 0
- vm_next()
- }
-}
-
-states.vm_kremlin_coup_take_control = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- if (game.valid_spaces.length === 0){
- view.prompt = `Kremlin Coup! ${country_name(game.vm_active_country)}'s Elite space is already controlled.`
- gen_action('done')
- } else {
- view.prompt = `Kremlin Coup! Take control of the Elite space in ${country_name(game.vm_active_country)}.`
- for (let space_id of game.valid_spaces) {
- gen_action_infl(spaces[space_id].name_unique);
- }
- }
- },
- infl(space) {
- vm_take_control(space)
- if (game.vm_active_country === 'East_Germany') {game.selected_space = 3 }
- if (game.vm_active_country === 'Poland') {game.selected_space = 17}
- if (game.vm_active_country === 'Czechoslovakia') {game.selected_space = 29}
- if (game.vm_active_country === 'Hungary') {game.selected_space = 45}
- if (game.vm_active_country === 'Romania') {game.selected_space = 61}
- if (game.vm_active_country === 'Bulgaria') {game.selected_space = 68}
- game.state = 'vm_kremlin_coup_sc_prep'
- },
- done() {
- if (game.vm_active_country === 'East_Germany') {game.selected_space = 3 }
- if (game.vm_active_country === 'Poland') {game.selected_space = 17}
- if (game.vm_active_country === 'Czechoslovakia') {game.selected_space = 29}
- if (game.vm_active_country === 'Hungary') {game.selected_space = 45}
- if (game.vm_active_country === 'Romania') {game.selected_space = 61}
- if (game.vm_active_country === 'Bulgaria') {game.selected_space = 68}
- game.state = 'vm_kremlin_coup_sc_prep'
- }
-}
-
-states.vm_kremlin_coup_sc_prep = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- view.prompt = `Kremlin Coup! Conduct a support check in ${game.vm_active_country}'s Bureaucratic space.`
- gen_action_sc(spaces[game.selected_space].name_unique);
- },
- sc(space) {
- //game.selected_space = find_space_index(space)
- game.state = 'vm_kremlin_coup_sc'
- }
-}
-
-states.vm_kremlin_coup_sc = {
- inactive: 'do support checks',
- prompt () {
- view.prompt = `Support check: ${spaces[game.selected_space].name_unique}. Roll a die.`
- gen_action('roll')
- },
- roll() {
- clear_undo()
- do_sc(spaces[game.selected_space].name_unique)
- if (game.temp.length > 0 ){
- game.state = 'vm_kremlin_coup_choose_country'
- } else {
- game.state = 'vm_kremlin_coup_end'
- }
- }
-}
-
-states.vm_kremlin_coup_end = {
- get inactive() {
- return `resolve ${clean_name(cards[this_card()].name)}.`
- },
- prompt() {
- view.prompt = `${clean_name(cards[this_card()].name)}: done.`
- gen_action('done')
- },
- done() {
- vm_next()
- }
-}
-
-states.vm_laszlo_tokes = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- view.prompt = `Laszlo Tokes. Choose to:`
- gen_action('influence')
- gen_action('support_check')
- },
- influence(){
- push_undo()
- game.vm_available_ops = get_card_ops(73)
- valid_spaces_infl()
- game.valid_spaces = game.valid_spaces.filter(space_id => spaces[space_id].country === 'Romania')
- game.phase = 3
- vm_next()
- //game.state = 'vm_add_infl'
- },
- support_check() {
- push_undo()
- game.vm_available_ops = 2
- //game.state = 'vm_support_check_prep'
- valid_spaces_sc()
- game.valid_spaces = game.valid_spaces.filter(space_id => spaces[space_id].country === 'Romania')
- vm_next()
- }
-}
-
-states.vm_switch_infl = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- if (game.valid_spaces.length === 0) {
- view.prompt = `${clean_name(cards[this_card()].name)}: No SPs to remove.`
- gen_action('pass')
- } else {
- /*if (game.vm_available_ops > 0 ) {*/
- view.prompt = `${clean_name(cards[game.played_card].name)}: ${event_prompt()}.`
- for (let space_id of game.valid_spaces) {
- gen_action_infl(spaces[space_id].name_unique);
- }
- } /*else {
- view.prompt = 'Influence replaced.'
- gen_action('done')
- }*/
- },
- infl(space) {
- push_undo()
- vm_switch_infl(space)
- if (game.vm_available_ops === 0) {
- game.valid_spaces = []
- }
- vm_next()
- },
- pass() {
- vm_next()
- }
- /*done() {
- vm_next()
- }*/
-}
-
-states.vm_malta_summit = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- /*if (game.phase === 1) {*/
- view.prompt = 'Malta Summit: roll a die.'
- gen_action('roll')
- /*} else {
- view.prompt = 'Done.'
- gen_action('done')
- }*/
- },
- roll() {
- clear_undo()
- let roll = Math.floor(Math.random() * 6) + 1
- log(`Rolled a ${roll}`)
- if (game.stability > 0) {
- log(`+${game.stability} from USSR Stability Track`)
- log(`Modified roll: ${roll + game.stability}`)
- }
- if (roll + game.stability > 3) {
- log('Summit successful')
- game.vp += 3
- log('+3 VP')
- if (check_vp()) {
- return
- }
- if (game.comInfl[12] > 0 ) {game.valid_spaces.push(12)}
- if (game.comInfl[15] > 0 ) {game.valid_spaces.push(15)}
- if (game.comInfl[27] > 0 ) {game.valid_spaces.push(27)}
- if (game.comInfl[43] > 0 ) {game.valid_spaces.push(43)}
- if (game.comInfl[51] > 0 ) {game.valid_spaces.push(51)}
- if (game.comInfl[69] > 0 ) {game.valid_spaces.push(69)}
- //game.vm_available_ops = 5
- game.remove_opponent_infl = true
- vm_next()
- }
- else {
- log('Summit failed. Required 4 or more')
- //game.phase++
- vm_goto_step(vm_permanently_remove)
- }
- },
- /*done() {
- vm_next()
- }*/
-}
-
-states.vm_modrow = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- view.prompt = `Modrow: roll a die.`
- gen_action('roll')
- },
- roll(){
- clear_undo()
- let roll = Math.floor(Math.random() * 6) + 1
- let dem_spaces = spaces.filter(space => space && space.country === 'East_Germany' && check_dem_control(space.space_id)).length
- if (roll > dem_spaces) {
- log(`Rolled a ${roll}`)
- log(`Success. More than the ${dem_spaces} Democratically controlled spaces`)
- vm_next()
- } else {
- log(`Rolled a ${roll}`)
- log(`Fail. More than ${dem_spaces} required`)
- permanently_remove(83)
- vm_return()
- }
- }
-}
-
-states.vm_nepotism = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- //if (game.phase === 1 ) {
- view.prompt = 'Nepotism: roll a die.'
- gen_action('roll')
- /*} else {
- view.prompt = 'Roll a die: done.'
- gen_action('done')
- }*/
- },
- roll() {
- clear_undo()
- let roll = Math.floor(Math.random() * 6) + 1
- if (roll < 3) {
- log(`Rolled a ${roll}: adds 4 SPs`)
- game.vm_available_ops = 4}
- else if (roll < 5 ) {
- log(`Rolled a ${roll}: adds 3 SPs`)
- game.vm_available_ops = 3}
- else {
- log(`Rolled a ${roll}: adds 1 SP`)
- game.vm_available_ops = 1}
- //game.phase = 2
- vm_next()
- },
- /*done() {
- vm_next()
- }*/
-}
-
-states.vm_new_years_eve_party = {
- get inactive() {
- return `resolve ${clean_name(cards[104].name)}.`
- },
- prompt() {
- view.prompt = 'Choose whether the game ends at the end of this turn.'
- gen_action('end')
- gen_action('continue')
- },
- end() {
- push_undo()
- game.persistent_events.push(104)
- log('Chooses to end the game. There will be no final scoring')
- let power = game.revolutions.filter(value => value === false).length
- if (power > 3) {
- log(`Communist holds power in ${power} countries. -3 VP`)
- game.vp -= 3
- } else {
- log(`Communist holds power in ${power} countries. +3 VP`)
- game.vp += 3
- }
- if (check_vp()) {
- return
- }
- //game.table_cards.push(104)
- permanently_remove(104)
- vm_next()
- },
- continue() {
- log('Chooses to continue')
- permanently_remove(104)
- vm_next()
- }
-}
-
-states.vm_nomenklatura = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- view.prompt = 'Nomenklatura: choose to remove all Democratic SPs from Elite spaces or add 3 SPs to any Elite space(s).'
- gen_action('remove')
- gen_action('add')
- },
- remove() {
- push_undo()
- game.valid_spaces = []
- for (let i = 1; i < spaces.length; i++) {
- let space = spaces[i]
-
- if (space.socio === 1 && game.demInfl[i] > 0) {
- game.valid_spaces.push(space.space_id)
- }
- }
- game.vm_available_ops = game.valid_spaces.length
- game.remove_opponent_infl = true
- game.state = 'vm_nomenklatura_remove'
- },
- add() {
- push_undo()
- game.valid_spaces = []
- for (let space of spaces) {
- if (!space) continue
- if (space.socio === 1) {
- game.valid_spaces.push(space.space_id)
- }
- }
- game.vm_available_ops = 3
- game.state = 'vm_nomenklatura_add'
- }
-}
-
-states.vm_nomenklatura_remove = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- if (game.vm_available_ops === 0 || game.valid_spaces.length === 0 ) {
- view.prompt = 'Remove SPs: done.'
- gen_action('done')
- } else {
- view.prompt = 'Nomenklatura: remove all Democratic SPs from Elite spaces.'
-
- for (let space_id of game.valid_spaces) {
- gen_action_infl(spaces[space_id].name_unique);
- }
- }
- },
- infl(space) {
- push_undo()
- vm_do_remove_all_infl(space)
- if (game.vm_available_ops === 0) {
- vm_next()
- }
- },
- done() {
- vm_next()
- }
-}
-
-states.vm_nomenklatura_add = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- if (game.vm_available_ops === 0 || game.valid_spaces.length === 0 ) {
- view.prompt = 'Add SPs: done.'
- gen_action('done')
- } else {
- view.prompt = `Nomenklatura: add 3 SPs to any Elite space(s). ${pluralize(game.vm_available_ops, 'SP')} remaining.`
- for (let space_id of game.valid_spaces) {
- gen_action_infl(spaces[space_id].name_unique);
- }
- }
- },
- infl(space) {
- push_undo()
- vm_do_add_infl_free(space)
- if (game.vm_available_ops === 0 ) {game.valid_spaces = []}
- },
- done() {
- if (game.summary.length > 0) {
- pop_summary()
- log_br()
- }
- vm_next()
- }
-}
-
-states.vm_samizdat = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- view.prompt = 'Samizdat: you may set aside a card from your hand and draw a replacement.'
- for (let card of game.democrat_hand) {
- gen_action_card(card)
- }
- gen_action('pass')
- },
- card(card) {
- push_undo()
- game.samizdat_card = card
- game.democrat_hand = game.democrat_hand.filter(c => c !== card)
- log('Set aside a card')
- game.state = 'vm_samizdat_finish'
- },
- pass() {
- //if (game.samizdat_card > 0) {game.state = 'vm_samizdat_finish'}
- /*else { */
- log('Did not set aside a card')
- vm_next()
- //}
- }
-}
-
-states.vm_samizdat_finish = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- /*if (game.phase ) {
- view.prompt = 'Samizdat: done.'
- gen_action('done')
- } else {*/
- view.prompt = 'Draw a replacement card.'
- gen_action('draw')
- //}
- },
- draw() {
- clear_undo()
- game.democrat_hand.push(draw_card(game.strategy_deck))
- vm_next()
- //game.phase ++
- },
- /*done() {
- vm_next()
- }*/
-}
-
-states.vm_shock_therapy = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- if (game.vm_active_country === '' ) {
- view.prompt = 'Shock Therapy: choose a country where you hold Power:'
- if (game.revolutions[0]) {gen_action('poland')}
- if (game.revolutions[1]) {gen_action('hungary')}
- if (game.revolutions[2]) {gen_action('east_germany')}
- if (game.revolutions[3]) {gen_action('bulgaria')}
- if (game.revolutions[4]) {gen_action('czechoslovakia')}
- if (game.revolutions[5]) {gen_action('romania')}
- } else if (game.phase === 2) {
- view.prompt = 'Shock Therapy: done.'
- gen_action('done')
- } else {
- view.prompt = 'Shock Therapy: roll a die.'
- gen_action('roll')
- }
- },
- east_germany() {
- push_undo()
- game.vm_active_country = 'East_Germany'
- log(`Chose ${country_name(game.vm_active_country)}`)
- },
- poland() {
- push_undo()
- game.vm_active_country = 'Poland'
- log(`Chose ${country_name(game.vm_active_country)}`)
- },
- czechoslovakia() {
- push_undo()
- game.vm_active_country = 'Czechoslovakia'
- log(`Chose ${country_name(game.vm_active_country)}`)
- },
- hungary() {
- push_undo()
- game.vm_active_country = 'Hungary'
- log(`Chose ${country_name(game.vm_active_country)}`)
- },
- romania() {
- push_undo()
- game.vm_active_country = 'Romania'
- log(`Chose ${country_name(game.vm_active_country)}`)
- },
- bulgaria () {
- push_undo()
- game.vm_active_country = 'Bulgaria'
- log(`Chose ${country_name(game.vm_active_country)}`)
- },
- roll() {
- clear_undo()
- let roll = Math.floor(Math.random() * 6) + 1
- let worker_farmer = 0
- for (let space of spaces) {
- if (space && space.country === game.vm_active_country && check_com_control(space.space_id) && (space.socio === 3 || space.socio === 4)) {
- worker_farmer++
- }
- }
- log(`Rolled a ${roll}`)
- log(`-${worker_farmer} from Communist controlled Worker and Farmer spaces`)
- log(`Modified roll: ${roll - worker_farmer}`)
- if ((roll - worker_farmer) > 2) {
- log('C93 is successful. +3 VP')
- vm_next()
- } else {
- log('C93 is unsuccessful. Required 3 or more')
- game.phase++
- }
- },
- done() {
- permanently_remove(93)
- vm_return()
- }
-}
-
-states.vm_social_democratic_platform_adopted = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- view.prompt = 'Select a country where the Democrat holds Power.'
- if (game.revolutions[0]) {gen_action('poland')}
- if (game.revolutions[1]) {gen_action('hungary')}
- if (game.revolutions[2]) {gen_action('east_germany')}
- if (game.revolutions[3]) {gen_action('bulgaria')}
- if (game.revolutions[4]) {gen_action('czechoslovakia')}
- if (game.revolutions[5]) {gen_action('romania')}
- },
- east_germany() {
- push_undo()
- game.vm_active_country = 'East_Germany'
- log(`Selected ${country_name(game.vm_active_country)}`)
- vm_next()
- },
- poland() {
- push_undo()
- game.vm_active_country = 'Poland'
- log(`Selected ${country_name(game.vm_active_country)}`)
- vm_next()},
- czechoslovakia() {
- push_undo()
- game.vm_active_country = 'Czechoslovakia'
- log(`Selected ${country_name(game.vm_active_country)}`)
- vm_next()},
- hungary() {
- push_undo()
- game.vm_active_country = 'Hungary'
- log(`Selected ${country_name(game.vm_active_country)}`)
- vm_next()
- },
- romania() {
- push_undo()
- game.vm_active_country = 'Romania'
- log(`Selected ${country_name(game.vm_active_country)}`)
- vm_next()
- },
- bulgaria () {
- push_undo()
- game.vm_active_country = 'Bulgaria'
- log(`Selected ${country_name(game.vm_active_country)}`)
- vm_next()}
-}
-
-states.vm_systematization = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- /*if (game.systematization === 0) { */
- view.prompt = 'Systematization: eliminate a space in Romania.'
- for (let space_id of game.valid_spaces) {
- gen_action_infl(spaces[space_id].name_unique);
- }
- /*} else {
- view.prompt = 'Systematization: done.'
- gen_action('done')
- }*/
- },
- infl(space) {
- push_undo()
- vm_eliminate(find_space_index(space))
- game.valid_spaces = []
- game.systematization = find_space_index(space)
- game.persistent_events.push(69)
- vm_next()
- },
-/* done() {
- vm_next()
- } */
-}
-
-states.vm_the_chinese_solution = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- view.prompt = 'You may give up 3 VP to conduct support checks in a country where you hold power.'
- if (!game.revolutions[0]) {gen_action('poland')}
- if (!game.revolutions[1]) {gen_action('hungary')}
- if (!game.revolutions[2]) {gen_action('east_germany')}
- if (!game.revolutions[3]) {gen_action('bulgaria')}
- if (!game.revolutions[4]) {gen_action('czechoslovakia')}
- if (!game.revolutions[5]) {gen_action('romania')}
- gen_action('pass')
- },
- east_germany() {
- push_undo()
- game.vm_active_country = 'East_Germany'
- log(`Chose ${country_name(game.vm_active_country)}`)
- log('+3 VP')
- game.vp += 3
- if (check_vp()) {
- return
- }
- vm_next()
- },
- poland() {
- push_undo()
- game.vm_active_country = 'Poland'
- log(`Chose ${country_name(game.vm_active_country)}`)
- log('+3 VP')
- game.vp += 3
- if (check_vp()) {
- return
- }
- vm_next()
- },
- czechoslovakia() {
- push_undo()
- game.vm_active_country = 'Czechoslovakia'
- log(`Chose ${country_name(game.vm_active_country)}`)
- log('+3 VP')
- game.vp += 3
- if (check_vp()) {
- return
- }
- vm_next()
- },
- hungary() {
- push_undo()
- game.vm_active_country = 'Hungary'
- log(`Chose ${country_name(game.vm_active_country)}`)
- log('+3 VP')
- game.vp += 3
- if (check_vp()) {
- return
- }
- vm_next()
- },
- romania() {
- push_undo()
- game.vm_active_country = 'Romania'
- log(`Chose ${country_name(game.vm_active_country)}`)
- log('+3 VP')
- game.vp += 3
- if (check_vp()) {
- return
- }
- vm_next()
- },
- bulgaria () {
- push_undo()
- game.vm_active_country = 'Bulgaria'
- log(`Chose ${country_name(game.vm_active_country)}`)
- log('+3 VP')
- game.vp += 3
- if (check_vp()) {
- return
- }
- vm_next()
- },
- pass() {
- permanently_remove(96)
- vm_return()
- }
-}
-
-states.vm_the_tyrant_is_gone = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- if (!game.the_tyrant_is_gone) {
- view.prompt = 'The Tyrant is Gone: Select a space in Romania for the Ceausescus to flee to.'
- for (let space_id of game.valid_spaces) {
- if (!space_id) continue
- gen_action_infl(spaces[space_id].name_unique);
- }
- } else {
- view.prompt = 'Select a space: done.'
- gen_action('done')
- }
- },
- infl(space) {
- push_undo()
- log(`The Ceausescus flee to %${find_space_index(space)}`)
- game.the_tyrant_is_gone = find_space_index(space)
- game.persistent_events.push(97)
- },
- done () {
- vm_next()
- }
-}
-
-states.vm_the_wall_must_go = {
- get inactive() {
- return `resolve ${clean_name(cards[this_card()].name)}.`
- },
- prompt() {
- if (game.the_wall_must_go['dem_wins'] === 2 || game.the_wall_must_go['com_wins'] === 2) {
- view.prompt = 'The Wall Must Go! Done.'
- gen_action('done')
- } else {
- view.prompt = ('The Wall Must Go! Roll a die.')
- gen_action('roll')
- }
- },
- roll() {
- clear_undo()
- let attempt = game.the_wall_must_go['dem_wins'] + game.the_wall_must_go['com_wins']
- if (game.the_wall_must_go['dem_roll'] === 0 && game.the_wall_must_go['com_roll'] === 0) {
- log_h3(`Round ${attempt+1}`)
- }
-
- let roll = Math.floor(Math.random() * 6) + 1
- log(`Rolled a ${roll}`)
- if (game.active === DEM) {
- let controlled_spaces = spaces.filter(space => space && space.country === 'East_Germany' && check_dem_control(space.space_id)).length
- if (controlled_spaces > 0) {
- log(`+${controlled_spaces} from controlled spaces in East Germany`)
- log(`Modified roll: ${roll + controlled_spaces}`)
- roll += controlled_spaces
- }
- game.the_wall_must_go['dem_roll'] = roll
- } else {
- let controlled_spaces = spaces.filter(space => space && space.country === 'East_Germany' && check_com_control(space.space_id)).length
- if (controlled_spaces > 0) {
- log(`+${controlled_spaces} from controlled spaces in East Germany`)
- log(`Modified roll: ${roll + controlled_spaces}`)
- roll += controlled_spaces
- }
- game.the_wall_must_go['com_roll'] = roll
-
- }
- if (game.the_wall_must_go['dem_roll'] > 0 && game.the_wall_must_go['com_roll'] > 0) {
- if (game.the_wall_must_go['dem_roll'] > game.the_wall_must_go['com_roll'] ) {
- log('Democrat wins')
- game.the_wall_must_go['dem_wins']++
- } else if (game.the_wall_must_go['dem_roll'] === game.the_wall_must_go['com_roll'] ) {
- log('Tie. Re-roll')
- } else {
- log('Communist wins')
- game.the_wall_must_go['com_wins']++
- }
-
- log(`Democrat: ${game.the_wall_must_go['dem_wins']}, Communist: ${game.the_wall_must_go['com_wins']}`)
- }
- if (game.the_wall_must_go['dem_wins'] === 2) {
- log('The Democrat wins C86')
- return
- }
- if (game.the_wall_must_go['com_wins'] === 2) {
- log('The Communist wins C86')
- return
- }
- if (game.the_wall_must_go['dem_roll'] === 0 || game.the_wall_must_go['com_roll'] === 0) {
- next_player()
- } else {
- game.the_wall_must_go['dem_roll'] = 0
- game.the_wall_must_go['com_roll'] = 0
- }
- },
- done() {
- if (game.the_wall_must_go['dem_wins'] === 2) {
- game.persistent_events.push(86)
- log('+3 VP')
- game.vp += 3
- if (check_vp()) {
- return
- }
- for (let i = 1; i < spaces.length; i++) {
- let space = spaces[i]
- if (space.country === 'East_Germany' && game.comInfl[i] > 0){
- game.valid_spaces.push(space.space_id)
- }
- }
- if (!game.vm_infl_to_do) {
- if (game.round_player === DEM) {
- game.return = COM
- } else {
- game.return = DEM
- }
- }
- if (game.active === DEM) {next_player()}
- vm_next ()
- } else {
- permanently_remove(86)
- delete game.the_wall_must_go
- vm_return()
- }
- }
-}
-
-states.vm_warsaw_pact_summit = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- view.prompt = 'Choose to play for support checks or place SPs.'
- gen_action('influence')
- gen_action('support_check')
- },
- influence(){
- push_undo()
- for (let i = 1; i < spaces.length; i++) {
- let space = spaces[i]
- if (game.demInfl[i] === 0) {
- game.valid_spaces.push(space.space_id);
- }
- }
- game.vm_available_ops = 4
- game.phase = 3
- //game.state = 'vm_add_infl'
- vm_next()
- },
- support_check(){
- push_undo()
- for (let i = 1; i < spaces.length; i++) {
- let space = spaces[i]
- if (game.demInfl[i] > 0 && (space.socio === 5 || space.socio === 6)) {
- game.valid_spaces.push(space.space_id)
- }
- }
- game.vm_available_ops = 2
- //game.state = 'vm_support_check_prep'
- console.log('game.phase',game.phase)
- vm_next()
- }
-}
-
-states.vm_we_are_the_people_remove = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- if (game.demInfl[6] === 0) {
- view.prompt = '"We are the People!": no SPs to remove.'
- gen_action('done')
- } else if (game.vm_available_ops > 0 ) {
- view.prompt = '"We are the People!": remove up to 4 SPs from the Lutherian Church.'
- gen_action('done')
- for (let space_id of game.valid_spaces) {
- gen_action_infl(spaces[space_id].name_unique);
- }
- } else {
- view.prompt = 'Remove SPs: done.'
- gen_action('done')
- }
- },
- infl(space) {
- vm_do_remove_infl(space)
- },
- done() {
- if (game.summary.length > 0) {
- pop_summary()
- log_br()
- }
- if (!game.vm_influence_added[6]) {
- log('No SPs removed')
- vm_next()
- } else {
- game.valid_spaces = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
- game.state = 'vm_we_are_the_people_add'
- }
- }
-}
-states.vm_we_are_the_people_add = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- if (!game.vm_influence_added[6]) {
- view.prompt = '"We are the People!": done.'
- gen_action('done')
- return
- }
-
- view.prompt = `"We are the People!": you must add the ${pluralize(game.vm_influence_added[6],'SP')} to spaces in Germany.`
- gen_action('done')
- for (let space_id of game.valid_spaces) {
- gen_action_infl(spaces[space_id].name_unique);
- }
- },
- infl(space) {
- push_undo()
- vm_do_add_infl_free(space)
- game.vm_influence_added[6]--
- if (game.vm_influence_added[6] === 0 ) {game.valid_spaces = []}
- },
- done() {
- if (game.summary.length > 0) {
- pop_summary()
- log_br()
- }
- vm_next()
- }
-}
-
-states.vm_workers_revolt = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- view.prompt = 'Workers Revolt: select a Worker Space in a country your opponent has power.'
- for (let space_id of game.valid_spaces) {
- gen_action_infl(spaces[space_id].name_unique)
- }
- },
- infl(space) {
- game.selected_space = find_space_index(space)
- log(`Chose %${game.selected_space}`)
- game.state = 'vm_workers_revolt_finish'
- }
-}
-
-
-states.vm_workers_revolt_finish = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- if (game.selected_space > 0) {
- view.prompt = `Target: ${spaces[game.selected_space].name_unique}. Roll a die.`
- gen_action('roll')
- } else {
- view.prompt = 'Workers Revolt: done.'
- gen_action('done')
- }
-
- },
- roll() {
- clear_undo()
- let roll = Math.floor(Math.random() * 6) + 1
- log(`Rolled a ${roll}`)
- let adj = count_adj(spaces[game.selected_space].name_unique)
- if (game.active === DEM) {
- log(`-${adj.com_adj} from opponent controlled spaces`)
- roll -= adj.com_adj
- } else {
- log(`-${adj.dem_adj} from opponent controlled spaces`)
- roll -= adj.dem_adj
- }
- log(`Modified roll: ${roll}`)
- if (roll >= 4) {
- log('Workers Revolt successful')
- vm_replace_all_infl(game.temp)
- } else {log('Workers Revolt fails. Required 4 or more')}
- game.selected_space = 0
- },
- done() {
- vm_next()
- }
-}
-
-// ==================== TIANANMEN SQUARE TRACK STATES =====================
-
-states.vm_tst_3_prep = {
- inactive: 'resolve Tiananmen Square Track award.',
- prompt() {
- view.prompt = 'Tiananmen Square Track award: draw 3 cards.'
- gen_action('draw')
- },
- draw() {
- if (game.active === DEM) {
- game.temp = game.democrat_hand.length
- draw_cards(game.strategy_deck, game.democrat_hand, game.communist_hand, game.democrat_hand.length + 3, game.communist_hand.length)
- game.valid_cards = [game.democrat_hand[game.temp], game.democrat_hand[game.temp + 1], game.democrat_hand[game.temp + 2]]
- } else {
- game.temp = game.communist_hand.length
- draw_cards(game.strategy_deck, game.democrat_hand, game.communist_hand, game.democrat_hand.length, game.communist_hand.length + 3)
- game.valid_cards = [game.communist_hand[game.temp], game.communist_hand[game.temp + 1], game.communist_hand[game.temp + 2]]
- }
- game.temp = 0
- game.state = 'vm_tst_3'
- }
-}
-
-states.vm_tst_3 = {
- inactive: 'resolve Tiananmen Square Track bonus.',
- prompt() {
- if (game.temp < 2) {
- view.prompt = `Discard 2 of the drawn cards`
- for (let card of game.valid_cards) {
- gen_action_card(card)
- }
- } else {
- view.prompt = 'Discard cards: done.'
- gen_action('done')
- }
- },
- card(card) {
- push_undo()
- discard(card)
- game.temp ++
- if (game.temp === 2) {
- game.valid_cards = []
- }
- },
- done() {
- vm_next()
- }
-}
-
-states.vm_tst_4 = {
- inactive: 'remove SPs',
- prompt () {
- if (game.vm_available_ops === 0 || game.valid_spaces.length === 0) {
- view.prompt = 'Remove SPs: done.'
- gen_action('done')
- return
- }
- view.prompt = 'Tiananmen Square Track award: select a space to remove SPs'
-
- for (let space_id of game.valid_spaces) {
- gen_action_infl(spaces[space_id].name_unique);
- }
- },
- infl(space) {
- vm_do_remove_infl(space)
- },
- done() {
- if (game.summary.length > 0) {
- pop_summary()
- log_br()
- }
- vm_next()
- }
-}
-
-states.vm_tst_6 = {
- inactive: 'make their free support check.',
- prompt() {
- if (game.vm_available_ops === 0) {
- view.prompt = 'Tiananmen Square Track award support check: done.'
- gen_action('done')
- return
- } else {
- view.prompt = 'Tiananmen Square Track award: you have a free 2 Ops support check.'
- for (let space_id of game.valid_spaces) {
- if (space_id) {
- gen_action_sc(spaces[space_id].name_unique);
- }
- }
- }
- },
- sc(space) {
- push_undo()
- game.selected_space = find_space_index(space)
- if (game.active === DEM && game.persistent_events.includes(58) && spaces[space].country === "East_Germany") {
- game.austria_hungary_border_reopened_tracker = true
- }
- game.state = 'vm_tst_6_sc'
- },
- done () {
- vm_next()
- }
-}
-
-states.vm_tst_6_sc = {
- inactive: 'do support check.',
- prompt () {
- view.prompt = `Support check: ${spaces[game.selected_space].name_unique}. Roll a die`
- gen_action('roll')
- },
- roll() {
- clear_undo()
- do_sc(spaces[game.selected_space].name_unique)
- game.vm_available_ops--
- game.valid_spaces = []
- game.state = 'vm_tst_6'
- return
- }
-}
-
-states.vm_tst_8 = {
- inactive: 'use Tiananmen Square Track award.',
- prompt() {
- if (game.vm_event_to_do && game.vm_infl_to_do) {
- view.prompt = 'Choose whether to play for event or operations first.'
- gen_action('event')
- gen_action('ops')
- }
- else if (!game.vm_event_to_do && game.vm_infl_to_do) {
- view.prompt = 'Event resolved. Use card for operations.'
- gen_action('ops')
- }
- else if (game.vm_event_to_do && !game.vm_infl_to_do) {
- view.prompt = 'Operations resolved. Use card for event.'
- gen_action('event')
- }
- else if (!game.vm_event_to_do && !game.vm_infl_to_do) {
- view.prompt = 'Event and operations: done.'
- gen_action('done')
- }
- },
- event() {
- push_undo()
- game.vm_event_to_do = false
- game.return_state = 'vm_tst_8'
- game.return = game.active
- game.vm_event = game.played_card
- goto_vm(game.vm_event)
- },
- ops() {
- push_undo()
- game.vm_infl_to_do = false
- game.return = game.active
- game.return_state = 'vm_tst_8'
- goto_vm(208)
- },
- done() {
- game.tst_8 = true
- end_round()
- }
-}
-
-
-states.vm_tst_8_ops = {
- inactive: 'play card for operations.',
- prompt() {
- view.prompt = `Play ${clean_name(cards[game.played_card].name)} for:`
- gen_action('influence')
- gen_action('support_check')
- if ((game.active === DEM && game.dem_tst_attempted_this_turn === 0 ) || (game.active === COM && game.com_tst_attempted_this_turn === 0 )) {
- gen_action('tst')
- }
- },
- influence(){
- push_undo()
- game.vm_available_ops = cards[game.played_card].ops
- valid_spaces_infl()
- // If ABHR - Set AHBR tracker to true
- if (game.persistent_events.includes(58)) {
- game.austria_hungary_border_reopened_tracker = true
- }
- game.state = 'vm_add_infl'
- },
- support_check() {
- push_undo()
- game.vm_available_ops = 2
- game.state = 'vm_support_check_prep'
- },
- tst() {
- game.state = 'vm_tiananmen_square_attempt'
- }
-}
-
-// ========================= POWER STRUGGLE STATES ========================
-
-states.vm_support_surges = {
- inactive: 'draw cards.',
- prompt() {
- view.prompt = 'Support Surges: draw 2 cards.'
- gen_action('draw')
- },
- draw() {
- if (game.active === DEM) {
- draw_cards(game.power_struggle_deck, game.dem_pwr_hand, game.com_pwr_hand, game.dem_pwr_hand.length+2, game.com_pwr_hand.length)
- } else {
- draw_cards(game.power_struggle_deck, game.dem_pwr_hand, game.com_pwr_hand, game.dem_pwr_hand.length, game.com_pwr_hand.length+2)
- }
- game.phase = 0
- log('Drew 2 cards')
- log('Surrenders initiative')
- vm_next()
- }
-}
-
-states.vm_support_falters = {
- inactive: 'discard cards.',
- prompt() {
- if ((game.active === DEM && game.dem_pwr_hand.length === 0) || (game.active === COM && game.com_pwr_hand.length === 0)) {
- view.prompt = 'Support Falters: no remaining cards to discard.'
- gen_action('pass')
- } else if (game.vm_available_ops > 0) {
- view.prompt = 'Support Falters: discard a card.'
- gen_action('discard')
- } else {
- view.prompt = 'Support Falters: done.'
- gen_action('done')
- }
- },
- discard() {
- console.log('game.com_pwr_hand', game.com_pwr_hand)
- if (game.active === DEM) {discard_card(game.dem_pwr_hand)}
- else {discard_card(game.com_pwr_hand)}
- game.vm_available_ops --
- },
- pass() {
- log_msg_gap('Takes initiative')
- game.return = game.active
- vm_next()
- },
- done() {
- log_msg_gap('Takes initiative')
- game.return = game.active
- vm_next()
- }
-}
-
-/* =================== EVENTS ================================ */
-
-// #region GENERATED EVENT CODE
-const CODE = []
-
-CODE[1] = [ // Legacy of Martial Law*
- [ vm_valid_spaces_country_opp, 'Poland' ],
- [ vm_prompt, 'replace 1 Democratic SP in Poland with a Communist SP' ],
- [ vm_legacy_of_martial_law ],
- [ vm_valid_spaces_country_sc, 'Poland' ],
- [ vm_prompt, 'make a Support Check in Poland' ],
- [ vm_1_support_check ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[2] = [ // Solidarity Legalised*
- [ vm_solidarity_legalised ],
- [ vm_valid_spaces_solidarity_legalised ],
- [ vm_prompt, 'to every uncontrolled Worker and Farmer space in Poland' ],
- [ vm_add_limited_infl, 9, 1 ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[3] = [ // Walesa
- [ vm_valid_spaces_country, 'Poland' ],
- [ vm_prompt, 'any space(s) in Poland' ],
- [ vm_add_infl_free, 4 ],
- [ vm_valid_spaces_country_sc, 'Poland' ],
- [ vm_prompt, 'Make Support Checks in Poland' ],
- [ vm_support_check, 2 ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[4] = [ // Michnik
- [ vm_valid_spaces, 26 ],
- [ vm_prompt, 'the Polish Intellectuals space' ],
- [ vm_add_x_infl, 3 ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[5] = [ // General strike
- [ vm_general_strike ],
- [ vm_return ],
-]
-
-CODE[6] = [ // Brought in for Questioning
- [ vm_brought_in_for_questioning ],
- [ vm_return ],
-]
-
-CODE[7] = [ // State Run Media*
- [ vm_valid_spaces_opponent ],
- [ vm_remove_limited_opp_infl, 4, 2 ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[8] = [ // Prudence
- [ vm_prudence ],
- [ vm_return ],
-]
-
-CODE[9] = [ // The Wall*
- [ vm_the_wall ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[10] = [ // Cult of Personality
- [ vm_if, ()=>!game.the_tyrant_is_gone ],
- [ vm_valid_spaces_country_socio_2, 'Romania', 3, 4 ],
- [ vm_prompt, 'Worker or Farmer spaces in Romania, no more than 2 per space' ],
- [ vm_add_limited_infl, 4, 2 ],
- [ vm_endif ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[11] = [ // Dissident arrested
- [ vm_valid_spaces_opponent_socio, 5 ],
- [ vm_prompt, 'any Intellectuals space' ],
- [ vm_remove_x_opp_infl, 2 ],
- [ vm_return ],
-]
-
-CODE[12] = [ // Apparatchicks
- [ vm_valid_spaces_socio, 2 ],
- [ vm_prompt, ' to any Bureaucratic space(s)' ],
- [ vm_add_infl_free, 3 ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[13] = [ // Stasi
- [ vm_stasi ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[14] = [ // Gorbachev Charms the West
- [ vm_valid_spaces_opponent ],
- [ vm_remove_opp_infl, 2 ],
- [ vm_valid_spaces_sc ],
- [ vm_prompt, 'select a space for the Support Check' ],
- [ vm_1_support_check ],
- [ vm_return ],
-]
-
-CODE[15] = [ // Honecker
- [ vm_permanently_remove ],
- [ vm_honecker ],
- [ vm_return ],
-]
-
-CODE[16] = [ // Nomenklatura*
- [ vm_nomenklatura ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[17] = [ // Roundtable talks
- [ vm_roundtable_talks ],
- [ vm_return ],
-]
-
-CODE[18] = [ // Poszgay Defends the Revolution
- [ vm_poszgay ],
- [ vm_prompt, 'to 4 spaces in Hungary not under Democratic control' ],
- [ vm_add_limited_infl, 4, 1 ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[19] = [ // Papal vist
- [ vm_valid_spaces, 20, 35, 38 ],
- [ vm_prompt, 'any Catholic Church space' ],
- [ vm_add_x_infl, 3 ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[20] = [ // Deutsche Marks*
- [ vm_permanently_remove ],
- [ vm_deutsche_marks ],
- [ vm_return ],
-]
-
-CODE[21] = [ // Common European Home
- [ vm_common_european_home ],
- [ vm_return ],
-]
-
-CODE[22] = [ // Power Struggle - Poland
- [ vm_power_struggle ],
- [ vm_return ],
-]
-
-CODE[23] = [ // Power Struggle - Hungary
- [ vm_power_struggle ],
- [ vm_return ],
-]
-
-CODE[24] = [ // St Nicolas Church
- [ vm_valid_spaces, 6 ],
- [ vm_prompt, 'the Lutheran Church' ],
- [ vm_take_control_prep, 1 ],
- [ vm_st_nicholas_church ],
- [ vm_return ],
-]
-
-CODE[25] = [ // Perestroika
- [ vm_perestroika ],
- [ vm_return ],
-]
-
-CODE[26] = [ // Helsinki Final Act*
- [ vm_helsinki_final_act ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[27] = [ // Consumerism
- [ vm_valid_spaces_opponent_socio, 4 ],
- [ vm_prompt, ' from a Worker space' ],
- [ vm_remove_opp_infl, 1 ],
- [ vm_valid_spaces_opponent_socio, 4 ],
- [ vm_active_country ],
- [ vm_prompt, ()=>`make a support check in a Worker space in ${country_name(game.vm_active_country)}` ],
- [ vm_1_support_check ],
- [ vm_return ],
-]
-
-CODE[28] = [ // Factory Party Cells
- [ vm_valid_spaces_opponent_socio, 4 ],
- [ vm_prompt, ' from Worker spaces' ],
- [ vm_remove_limited_opp_infl, 3, 2 ],
- [ vm_return ],
-]
-
-CODE[29] = [ // Jan Palach Week*
- [ vm_valid_spaces, 30 ],
- [ vm_prompt, 'the Charles University space' ],
- [ vm_add_x_infl, 6 ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[30] = [ // Tear Gas
- [ vm_tear_gas ],
- [ vm_return ],
-]
-
-CODE[31] = [ // Intelligentsia
- [ vm_valid_spaces, 4, 26, 31, 46, 55, 73 ],
- [ vm_prompt, 'Intellectual spaces, no more than 2 per space' ],
- [ vm_add_limited_infl, 4, 2 ],
- [ vm_return ],
-]
-
-CODE[32] = [ // Peasant Parties*
- [ vm_valid_spaces_socio, 3 ],
- [ vm_prompt, 'Farmer spaces, no more than 2 per space' ],
- [ vm_add_limited_infl, 4, 2 ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[33] = [ // Sajudis*
- [ vm_sajudis_check ],
- [ vm_prompt, 'any Minorities space' ],
- [ vm_take_control_prep, 1 ],
- [ vm_sajudis ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[34] = [ // Fidesz*
- [ vm_valid_spaces, 47 ],
- [ vm_prompt, 'the Hungary students space' ],
- [ vm_add_x_infl, 5 ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[35] = [ // Heal our Bleeding Wounds*
- [ vm_heal_our_bleeding_wounds ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[36] = [ // Dash for the West*
- [ vm_permanently_remove ],
- [ vm_prompt, 'Dash for the West: select any Democratic event with an asterix(*) from the discard pile. Event occurs immediately' ],
- [ vm_dash_for_the_west ],
- [ vm_return ],
-]
-
-CODE[37] = [ // Nagy Reburied*
- [ vm_nagy_reburied ],
- [ vm_prompt, 'the Hungary Elite space' ],
- [ vm_remove_all_infl, 1 ],
- [ vm_valid_spaces_country, 'Hungary' ],
- [ vm_prompt, 'Hungary, no more than 2 per space' ],
- [ vm_add_limited_infl, 4, 2 ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[38] = [ // July Concept
- [ vm_valid_spaces_country, 'Bulgaria' ],
- [ vm_prompt, 'Bulgaria' ],
- [ vm_add_infl_free, 3 ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[39] = [ // Eco-Glasnost*
- [ vm_valid_spaces, 66 ],
- [ vm_prompt, 'Ruse' ],
- [ vm_add_x_infl, 4 ],
- [ vm_eco_glasnost ],
- [ vm_return ],
-]
-
-CODE[40] = [ // Hungarian Democratic Forum
- [ vm_valid_spaces_country, 'Hungary' ],
- [ vm_prompt, 'Hungary' ],
- [ vm_add_infl_free, 3 ],
- [ vm_valid_spaces_country_sc, 'Hungary' ],
- [ vm_prompt, 'make a Support Check in Hungary' ],
- [ vm_1_support_check ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[41] = [ // Ceausescu*
- [ vm_if, ()=>!game.the_tyrant_is_gone ],
- [ vm_valid_spaces_country_opp, 'Romania' ],
- [ vm_prompt, ' from Romania' ],
- [ vm_remove_opp_infl, 3 ],
- [ vm_valid_spaces_country_sc, 'Romania' ],
- [ vm_prompt, 'make a support check in Romania' ],
- [ vm_1_support_check ],
- [ vm_prompt, ' from Bucharesti' ],
- [ vm_ceausescu ],
- [ vm_endif ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[42] = [ // Power Struggle - East Germany
- [ vm_power_struggle ],
- [ vm_return ],
-]
-
-CODE[43] = [ // Power Struggle - Bulgaria
- [ vm_power_struggle ],
- [ vm_return ],
-]
-
-CODE[44] = [ // Inflationary Currency
- [ vm_inflationary_currency ],
- [ vm_valid_spaces_country_opp ],
- [ vm_prompt, ()=>` from ${country_name(game.vm_active_country)}` ],
- [ vm_remove_opp_infl, 2 ],
- [ vm_inflationary_currency_discard ],
- [ vm_if, ()=>!discarded_card() ],
- [ vm_valid_spaces_country_sc ],
- [ vm_prompt, ()=>`make a Support Check in ${country_name(game.vm_active_country)}` ],
- [ vm_1_support_check ],
- [ vm_endif ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[45] = [ // Soviet Troop Withdrawals*
- [ vm_valid_spaces_region_opp, 'Eastern Europe' ],
- [ vm_prompt, ' from Eastern Europe' ],
- [ vm_remove_limited_opp_infl, 5, 2 ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[46] = [ // Goodbye Lenin!*
- [ vm_goodbye_lenin ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[47] = [ // Bulgarian Turks Expelled*
- [ vm_bulgarian_turks_expelled ],
- [ vm_prompt, 'Razgrad' ],
- [ vm_remove_all_infl, 1 ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[48] = [ // We are the People!*
- [ vm_we_are_the_people ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[49] = [ // Foreign Currency Debt Burden*
- [ vm_foreign_currency_debt_burden ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[50] = [ // The Sinatra Doctrine*
- [ vm_the_sinatra_doctrine ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[51] = [ // 40th Anniversary Celebration*
- [ vm_40th_anniversary_celebration ],
- [ vm_valid_spaces_country, 'East_Germany' ],
- [ vm_prompt, 'East Germany' ],
- [ vm_add_infl_free ],
- [ vm_40th_anniversary_celebration_vp ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[52] = [ // Normalisation
- [ vm_normalisation ],
- [ vm_prompt, 'the Czechoslovakia Elite and Bureaucrat Spaces' ],
- [ vm_remove_all_infl, 2 ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[53] = [ // Li Peng*
- [ vm_li_peng ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[54] = [ // The Crowd Turns Against Ceausescu*
- [ vm_the_crowd_turns_against_ceausescu ],
- [ vm_return ],
-]
-
-CODE[55] = [ // Power Struggle - Czechoslovakia
- [ vm_power_struggle ],
- [ vm_return ],
-]
-
-CODE[56] = [ // Foreign Television
- [ vm_foreign_television ],
- [ vm_remove_limited_opp_infl, 4, 2 ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[57] = [ // Central Committee Reshuffle*
- [ vm_central_committee_reshuffle ],
- [ vm_prompt, ()=>`${country_name(game.vm_active_country)}` ],
- [ vm_add_infl_free, 3 ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[58] = [ // Austria-Hungary Border Reopened*
- [ vm_austria_hungary_border_reopened ],
- [ vm_return ],
-]
-
-CODE[59] = [ // GrenzTruppen*
- [ vm_grenztruppen ],
- [ vm_return ],
-]
-
-CODE[60] = [ // Toxic Waste*
- [ vm_valid_spaces_socio, 4 ],
- [ vm_prompt, 'any Worker space(s)' ],
- [ vm_add_infl_free, 3 ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[61] = [ // The Monday Demonstrations*
- [ vm_the_monday_demonstrations ],
- [ vm_prompt, 'the Lutheran Church Space and Leipzig' ],
- [ vm_take_control_prep, 2 ],
- [ vm_valid_spaces_country_sc, 'East_Germany' ],
- [ vm_prompt, 'make 5 Support Checks in East Germany' ],
- [ vm_support_check, 5 ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[62] = [ // Yakovlev Counsels Gorbachev*
- [ vm_yakovlev_counsels_gorbachev ],
- [ vm_return ],
-]
-
-CODE[63] = [ // Genscher*
- [ vm_genscher ],
- [ vm_return ],
-]
-
-CODE[64] = [ // Legacy of 1968*
- [ vm_legacy_of_1968 ],
- [ vm_prompt, 'all spaces in Czechoslovakia not controlled by the Communist Player' ],
- [ vm_add_limited_infl, 11, 1 ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[65] = [ // Presidential Visit*
- [ vm_presidential_visit ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[66] = [ // New Forum
- [ vm_valid_spaces_country, 'East_Germany' ],
- [ vm_prompt, '3 spaces in East Germany' ],
- [ vm_add_limited_infl, 3, 1 ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[67] = [ // Reformer Rehabilitated*
- [ vm_prompt, 'Reformer Rehabilitated: chose any non-scoring card in the discard pile. Event takes place immediately' ],
- [ vm_reformer_rehabilitated ],
- [ vm_return ],
-]
-
-CODE[68] = [ // Klaus and Komarek*
- [ vm_klaus_and_komarek ],
- [ vm_prompt, 'Prague' ],
- [ vm_remove_x_opp_infl, 2 ],
- [ vm_valid_spaces, 29 ],
- [ vm_add_x_infl, 2 ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[69] = [ // Systematization*
- [ vm_valid_spaces_country, 'Romania' ],
- [ vm_systematization ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[70] = [ // Securitate*
- [ vm_securitate ],
- [ vm_return ],
-]
-
-CODE[71] = [ // Kiss of Death*
- [ vm_permanently_remove ],
- [ vm_kiss_of_death ],
- [ vm_return ],
-]
-
-CODE[72] = [ // Peasant Parties Revolt
- [ vm_peasant_parties_revolt ],
- [ vm_return ],
-]
-
-CODE[73] = [ // Laszlo Tokes*
- [ vm_valid_spaces, 50, 56 ],
- [ vm_prompt, 'in Timisoara and Harghita/Covasna' ],
- [ vm_add_limited_infl, 2, 1 ],
- [ vm_laszlo_tokes ],
- [ vm_if, ()=>game.phase === 3 ],
- [ vm_prompt, ' in Romania' ],
- [ vm_add_infl ],
- [ vm_else ],
- [ vm_prompt, 'make 2 Support Checks in Romania' ],
- [ vm_support_check, 2 ],
- [ vm_endif ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[74] = [ // FRG Embassies
- [ vm_frg_embassies ],
- [ vm_return ],
-]
-
-CODE[75] = [ // Exit Visas*
- [ vm_exit_visas ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[76] = [ // Warsaw Pact Summit
- [ vm_warsaw_pact_summit ],
- [ vm_if, ()=>game.phase === 3 ],
- [ vm_prompt, ' spaces with no Democratic SPs' ],
- [ vm_add_infl_free, 4 ],
- [ vm_else ],
- [ vm_prompt, 'Select a Student or Intellectual space' ],
- [ vm_valid_spaces_country_socio_2, 3,, 4 ],
- [ vm_support_check_modified, 2, 2 ],
- [ vm_endif ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[77] = [ // Samizdat
- [ vm_samizdat ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[78] = [ // Workers Revolt
- [ vm_workers_revolt ],
- [ vm_return ],
-]
-
-CODE[79] = [ // The Third Way*
- [ vm_the_third_way ],
- [ vm_valid_spaces, 4 ],
- [ vm_prompt, 'the East German Writers space' ],
- [ vm_add_x_infl, 3 ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[80] = [ // Nepotism*
- [ vm_nepotism ],
- [ vm_valid_spaces_region_socio, 'Balkans', 4 ],
- [ vm_prompt, 'Worker spaces in the Balkans' ],
- [ vm_add_infl_free ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[81] = [ // The Baltic Way*
- [ vm_the_baltic_way ],
- [ vm_prompt, 'any Minorities space' ],
- [ vm_take_control_prep, 1 ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[82] = [ // Spitzel*
- [ vm_valid_spaces_country_opp, 'East_Germany' ],
- [ vm_prompt, ' from East Germany' ],
- [ vm_remove_opp_infl, 2 ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[83] = [ // Modrow*
- [ vm_modrow ],
- [ vm_valid_spaces_country, 'East_Germany' ],
- [ vm_prompt, 'East Germany' ],
- [ vm_add_limited_infl, 4, 2 ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[84] = [ // Breakaway Baltic Republics*
- [ vm_breakaway_baltic_republics ],
- [ vm_prompt, 'any Minorities space' ],
- [ vm_take_control_prep, 1 ],
- [ vm_valid_spaces_sc ],
- [ vm_prompt, 'select a space for the support check' ],
- [ vm_1_support_check ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[85] = [ // Tank Column/Tank Man*
- [ vm_tank_column ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[86] = [ // The Wall Must Go!*
- [ vm_the_wall_must_go ],
- [ vm_remove_infl, 3 ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[87] = [ // Kohl Proposes Reunification*
- [ vm_kohl_proposes_reunification ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[88] = [ // Adamec*
- [ vm_adamec ],
- [ vm_valid_spaces_country, 'Czechoslovakia' ],
- [ vm_prompt, 'Czechoslovakia' ],
- [ vm_add_limited_infl, 4, 2 ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[89] = [ // Domino Theory*
- [ vm_prompt, 'Domino Theory: choose a Power Struggle card to play from the discard pile.' ],
- [ vm_domino_theory ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[90] = [ // Civic Forum*
- [ vm_valid_spaces_country, 'Czechoslovakia' ],
- [ vm_prompt, 'Czechoslovakia' ],
- [ vm_add_infl_free, 4 ],
- [ vm_civic_forum ],
- [ vm_valid_spaces_country_sc, 'Czechoslovakia' ],
- [ vm_prompt, 'Select a space in Czechoslovakia' ],
- [ vm_support_check, 2 ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[91] = [ // My First Banana*
- [ vm_valid_spaces_country_opp, 'East_Germany' ],
- [ vm_prompt, ' from East Germany' ],
- [ vm_remove_opp_infl, 2 ],
- [ vm_valid_spaces_country_sc, 'East_Germany' ],
- [ vm_prompt, 'select a space in East Germany' ],
- [ vm_support_check, 2 ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[92] = [ // Betrayal
- [ vm_prompt, 'choose any Orthodox Church space. Replace all Democratic SPs with Communist SPs' ],
- [ vm_betrayal ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[93] = [ // Shock Therapy*
- [ vm_shock_therapy ],
- [ vm_valid_spaces_country ],
- [ vm_prompt, ()=>` ${country_name(game.vm_active_country)}` ],
- [ vm_add_infl_free, 3 ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[94] = [ // Union of Democratic Forces*
- [ vm_valid_spaces_country_opp, 'Bulgaria' ],
- [ vm_prompt, ' from Bulgaria' ],
- [ vm_remove_opp_infl, 4 ],
- [ vm_valid_spaces_country_sc, 'Bulgaria' ],
- [ vm_prompt, 'Make 2 Support Checks in Bulgaria' ],
- [ vm_support_check, 2 ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[95] = [ // Power Struggle - Romania
- [ vm_power_struggle ],
- [ vm_return ],
-]
-
-CODE[96] = [ // The Chinese Solution*
- [ vm_the_chinese_solution ],
- [ vm_valid_spaces_country_sc ],
- [ vm_prompt, ()=>`Make 5 Support Checks in ${country_name(game.vm_active_country)}` ],
- [ vm_support_check_modified, 5, 3 ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[97] = [ // The Tyrant is Gone*
- [ vm_if, ()=>game.persistent_events['the_crowd_turns_against_ceausescu'] ],
- [ vm_valid_spaces, 51 ],
- [ vm_prompt, 'the Romanian Elite Space' ],
- [ vm_remove_x_opp_infl, 4 ],
- [ vm_the_tyrant_is_gone ],
- [ vm_permanently_remove ],
- [ vm_else ],
- [ vm_the_tyrant_is_gone_prep ],
- [ vm_endif ],
- [ vm_return ],
-]
-
-CODE[98] = [ // Politburo Intrigue*
- [ vm_valid_spaces_country_opp, 'Bulgaria' ],
- [ vm_prompt, ' from Bulgaria' ],
- [ vm_remove_limited_opp_infl, 3, 2 ],
- [ vm_valid_spaces_country_sc, 'Bulgaria' ],
- [ vm_prompt, 'make a support check in Bulgaria' ],
- [ vm_1_support_check ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[99] = [ // Ligachev*
- [ vm_ligachev ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[100] = [ // Stand Fast*
- [ vm_stand_fast ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[101] = [ // Elena*
- [ vm_if, ()=>!game.the_tyrant_is_gone ],
- [ vm_valid_spaces, 51 ],
- [ vm_prompt, 'the Romania Elite Space' ],
- [ vm_add_x_infl, 2 ],
- [ vm_endif ],
- [ vm_elena ],
- [ vm_return ],
-]
-
-CODE[102] = [ // National Salvation Front*
- [ vm_national_salvation_front ],
- [ vm_return ],
-]
-
-CODE[103] = [ // Government Resigns*
- [ vm_government_resigns ],
- [ vm_prompt, 'any uncontrolled Elite space' ],
- [ vm_remove_all_infl, 1 ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[104] = [ // New Year's Eve Party*
- [ vm_new_years_eve_party ],
- [ vm_return ],
-]
-
-CODE[105] = [ // Public Against Violence*
- [ vm_valid_spaces, 36, 37 ],
- [ vm_prompt, 'Kosice and Presov' ],
- [ vm_add_x_infl, 2 ],
- [ vm_valid_spaces, 36, 37 ],
- [ vm_add_x_infl, 2 ],
- [ vm_public_against_violence ],
- [ vm_prompt, 'Make a Support Check in Bratislava' ],
- [ vm_support_check_modified, 1, 2 ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[106] = [ // Social Democratic Platform Adopted*
- [ vm_social_democratic_platform_adopted ],
- [ vm_valid_spaces_country ],
- [ vm_prompt, ()=>`${country_name(game.vm_active_country)}` ],
- [ vm_add_infl_free, 2 ],
- [ vm_valid_spaces_country_sc ],
- [ vm_prompt, ()=>`make a Support Check in ${country_name(game.vm_active_country)}` ],
- [ vm_1_support_check ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[107] = [ // Massacre in Timisoara*
- [ vm_if, ()=>!game.the_tyrant_is_gone ],
- [ vm_massacre_in_timisoara ],
- [ vm_valid_spaces_country_sc, 'Romania' ],
- [ vm_prompt, 'Make Support Checks in Romania' ],
- [ vm_support_check_modified, 2, 2 ],
- [ vm_endif ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[108] = [ // Army Backs Revolution*
- [ vm_army_backs_revolution ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[109] = [ // Kremlin Coup*
- [ vm_kremlin_coup ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[110] = [ // Malta Summit*
- [ vm_malta_summit ],
- [ vm_prompt, ' from Elite spaces' ],
- [ vm_remove_opp_infl, 5 ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-// #endregion
-
-
-// ============= TIANANMEN SQUARE TRACK AWARDS ====================
-CODE[203] = [//Tiananmen Square space 3 award
- [vm_tst_3],
- [vm_return]
-]
-CODE[204] = [//Tiananmen Square space 4 award
- [vm_valid_spaces_opponent],
- [vm_tst_4],
- [vm_return]
-]
-CODE[206] = [//Tiananmen Square space 6
- [vm_valid_spaces_sc],
- [vm_tst_6],
- [vm_return]
-]
-CODE[208] = [//Tiananmen Square space 8 event
- [vm_tst_8],
- [vm_return]
-]
-
-// ============= POWER STRUGGLE WILDCARDS =========================
-
-CODE[349] = [//Scare Tactics
- [vm_scare_tactics],
- [vm_valid_spaces_country_opp],
- [vm_prompt, ()=>` from ${country_name(game.vm_active_country)}`],
- [vm_remove_opp_infl, 1],
- [vm_return]
-]
-CODE[350] = [//Support Surges
- [vm_support_surges],
- [vm_return]
-]
-CODE[351] = [//Support Falters
- [vm_support_falters],
- [vm_return]
-]
+"use strict"
+
+// vim:set foldmethod=marker:
+
+const { spaces, cards, power_cards } = require("./data.js")
+
+var game, view, states = {}
+
+const DEM = "Democrat"
+const COM = "Communist"
+
+const first_strategy_card = 1
+const last_strategy_card = 110
+
+// BEGIN CONSTANTS {{{
+
+// SPACES
+const S_SCHWERIN = 0
+const S_ROSTOCK = 1
+const S_BERLIN = 2
+const S_GERMAN_WRITERS = 3
+const S_WALTER_ULBRICHT_ACADEMY = 4
+const S_LUTHERAN_CHURCH = 5
+const S_MAGDEBURG = 6
+const S_HALLE = 7
+const S_LEIPZIG = 8
+const S_ERFURT = 9
+const S_KARL_MARX_STADT = 10
+const S_DRESDEN = 11
+const S_SZCZECIN = 12
+const S_GDANSK = 13
+const S_BYDGOSZCZ = 14
+const S_POZNAN = 15
+const S_WARSZAWA = 16
+const S_BIALYSTOK = 17
+const S_WROCLAW = 18
+const S_CATHOLIC_CHURCH_POLAND = 19
+const S_LODZ = 20
+const S_KATOWICE = 21
+const S_KRAKOW = 22
+const S_LUBLIN = 23
+const S_JAGIELLONIAN_UNIVERSITY = 24
+const S_POLISH_WRITERS = 25
+const S_PLZEN = 26
+const S_CESKE_BUDEJOVICE = 27
+const S_PRAHA = 28
+const S_CHARLES_UNIVERSITY = 29
+const S_CZECH_WRITERS = 30
+const S_BRNO = 31
+const S_OSTRAVA = 32
+const S_BRATISLAVA = 33
+const S_CATHOLIC_CHURCH_CZECHOSLOVAKIA = 34
+const S_PRESOV = 35
+const S_KOSICE = 36
+const S_CATHOLIC_CHURCH_HUNGARY = 37
+const S_GYOR = 38
+const S_TATABANYA = 39
+const S_MISKOLC = 40
+const S_DEBRECEN = 41
+const S_SZOMBATHELY = 42
+const S_SZEKESFEHERVAR = 43
+const S_BUDAPEST = 44
+const S_HUNGARIAN_WRITERS = 45
+const S_EOTVOS_LORAND_UNIVERSITY = 46
+const S_SZEGED = 47
+const S_PECS = 48
+const S_TIMISOARA = 49
+const S_CLUJ_NAPOCA = 50
+const S_TARGU_MURES = 51
+const S_IASI = 52
+const S_BABES_BOLYAI_UNIVERSITY = 53
+const S_ROMANIAN_WRITERS = 54
+const S_HARGHITA_COVASNA = 55
+const S_BRASOV = 56
+const S_ORTHODOX_CHURCH_ROMANIA = 57
+const S_PLOIESTI = 58
+const S_CRAIOVA = 59
+const S_BUCURESTI = 60
+const S_GALATI = 61
+const S_CONSTANTA = 62
+const S_PLEVEN = 63
+const S_ORTHODOX_CHURCH_BULGARIA = 64
+const S_RUSE = 65
+const S_SOFIA_UNIVERSITY = 66
+const S_SOFIA = 67
+const S_STARA_ZAGORA = 68
+const S_RAZGRAD = 69
+const S_BURGAS = 70
+const S_VARNA = 71
+const S_BULGARIAN_WRITERS = 72
+const S_PLOVDIV = 73
+const S_SLIVEN = 74
+
+// CARDS
+const C_LEGACY_OF_MARTIAL_LAW = 1
+const C_SOLIDARITY_LEGALIZED = 2
+const C_WALESA = 3
+const C_MICHNIK = 4
+const C_GENERAL_STRIKE = 5
+const C_BROUGHT_IN_FOR_QUESTIONING = 6
+const C_STATE_RUN_MEDIA = 7
+const C_PRUDENCE = 8
+const C_THE_WALL = 9
+const C_CULT_OF_PERSONALITY = 10
+const C_DISSIDENT_ARRESTED = 11
+const C_APPARATCHIKS = 12
+const C_STASI = 13
+const C_GORBACHEV_CHARMS_THE_WEST = 14
+const C_HONECKER = 15
+const C_NOMENKLATURA = 16
+const C_ROUNDTABLE_TALKS = 17
+const C_POSZGAY_DEFENDS_THE_REVOLUTION = 18
+const C_PAPAL_VISIT = 19
+const C_DEUTSCHE_MARKS = 20
+const C_COMMON_EUROPEAN_HOME = 21
+const C_POWER_STRUGGLE_POLAND = 22
+const C_POWER_STRUGGLE_HUNGARY = 23
+const C_ST_NICHOLAS_CHURCH = 24
+const C_PERESTROIKA = 25
+const C_HELSINKI_FINAL_ACT = 26
+const C_CONSUMERISM = 27
+const C_FACTORY_PARTY_CELLS = 28
+const C_JAN_PALACH_WEEK = 29
+const C_TEAR_GAS = 30
+const C_INTELLIGENTSIA = 31
+const C_PEASANT_PARTIES = 32
+const C_SAJUDIS = 33
+const C_FIDESZ = 34
+const C_HEAL_OUR_BLEEDING_WOUND = 35
+const C_DASH_FOR_THE_WEST = 36
+const C_NAGY_REBURIED = 37
+const C_THE_JULY_CONCEPT = 38
+const C_ECO_GLASNOST = 39
+const C_HUNGARIAN_DEMOCRATIC_FORUM = 40
+const C_CEAUSESCU = 41
+const C_POWER_STRUGGLE_EAST_GERMANY = 42
+const C_POWER_STRUGGLE_BULGARIA = 43
+const C_INFLATIONARY_CURRENCY = 44
+const C_SOVIET_TROOP_WITHDRAWALS = 45
+const C_GOODBYE_LENIN = 46
+const C_BULGARIAN_TURKS_EXPELLED = 47
+const C_WE_ARE_THE_PEOPLE = 48
+const C_FOREIGN_CURRENCY_DEBT_BURDEN = 49
+const C_THE_SINATRA_DOCTRINE = 50
+const C_40TH_ANNIVERSARY_CELEBRATION = 51
+const C_NORMALIZATION = 52
+const C_LI_PENG = 53
+const C_THE_CROWD_TURNS_AGAINST_CEAUSESCU = 54
+const C_POWER_STRUGGLE_CZECHOSLOVAKIA = 55
+const C_FOREIGN_TELEVISION = 56
+const C_CENTRAL_COMMITTEE_RESHUFFLE = 57
+const C_AUSTRIA_HUNGARY_BORDER_REOPENED = 58
+const C_GRENZTRUPPEN = 59
+const C_TOXIC_WASTE = 60
+const C_THE_MONDAY_DEMONSTRATIONS = 61
+const C_YAKOVLEV_COUNSELS_GORBACHEV = 62
+const C_GENSCHER = 63
+const C_LEGACY_OF_1968 = 64
+const C_PRESIDENTIAL_VISIT = 65
+const C_NEW_FORUM = 66
+const C_REFORMER_REHABILITATED = 67
+const C_KLAUS_AND_KOMAREK = 68
+const C_SYSTEMATIZATION = 69
+const C_SECURITATE = 70
+const C_KISS_OF_DEATH = 71
+const C_PEASANT_PARTIES_REVOLT = 72
+const C_LASZLO_TOKES = 73
+const C_FRG_EMBASSIES = 74
+const C_EXIT_VISAS = 75
+const C_WARSAW_PACT_SUMMIT = 76
+const C_SAMIZDAT = 77
+const C_WORKERS_REVOLT = 78
+const C_THE_THIRD_WAY = 79
+const C_NEPOTISM = 80
+const C_THE_BALTIC_WAY = 81
+const C_SPITZEL = 82
+const C_MODROW = 83
+const C_BREAKAWAY_BALTIC_REPUBLICS = 84
+const C_TANK_COLUMN_TANK_MAN = 85
+const C_THE_WALL_MUST_GO = 86
+const C_KOHL_PROPOSES_REUNIFICATION = 87
+const C_ADAMEC = 88
+const C_DOMINO_THEORY = 89
+const C_CIVIC_FORUM = 90
+const C_MY_FIRST_BANANA = 91
+const C_BETRAYAL = 92
+const C_SHOCK_THERAPY = 93
+const C_UNION_OF_DEMOCRATIC_FORCES = 94
+const C_POWER_STRUGGLE_ROMANIA = 95
+const C_THE_CHINESE_SOLUTION = 96
+const C_THE_TYRANT_IS_GONE = 97
+const C_POLITBURO_INTRIGUE = 98
+const C_LIGACHEV = 99
+const C_STAND_FAST = 100
+const C_ELENA = 101
+const C_NATIONAL_SALVATION_FRONT = 102
+const C_GOVERNMENT_RESIGNS = 103
+const C_NEW_YEARS_EVE_PARTY = 104
+const C_PUBLIC_AGAINST_VIOLENCE = 105
+const C_SOCIAL_DEMOCRATIC_PLATFORM_ADOPTED = 106
+const C_MASSACRE_IN_TIMISOARA = 107
+const C_ARMY_BACKS_REVOLUTION = 108
+const C_KREMLIN_COUP = 109
+const C_MALTA_SUMMIT = 110
+
+// END CONSTANTS }}}
+
+const dem_tst_req = [5, 5, 6, 6, 7, 8, 9, 10]
+const com_tst_req = [6, 6, 7, 7, 8, 7, 6, 5]
+const scoring_cards = [22, 23, 42, 43, 55, 95]
+const leader_cards = [37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48]
+const rallies = [1, 2, 3, 4, 5, 6]
+const petitions = [31, 32, 33, 34, 35, 36]
+const wildcards = [49, 50, 51, 52]
+const elite_leaders = [37, 38, 39, 40]
+const leaders = [1, 4, 5, 6, 7]
+const support_loss_roll = [0, 0, 1, 1, 2, 2, 3, 4]
+const vp_roll = [0, 0, 1, 1, 2, 2, 3, 4]
+const countries = ['Poland', 'Hungary', 'East_Germany', 'Bulgaria', 'Czechoslovakia', 'Romania']
+const elite_spaces = [11, 14, 26, 42, 50, 68]
+const all_power_cards = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52 ]
+const numberless_cards = [1, 2, 3, 4, 5, 6, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52 ]
+const auto_resolve_events = [5, 8, 9, 13, 17, 25, 26, 30, 35, 50, 53, 54, 58, 59, 62, 63, 65, 70, 72, 74, 86, 99, 102, 108]
+const switch_events = [6, 20, 71]
+const one_turn_events = [ 8, 13, 25, 50, 63, 74, 49, 58, 59, 100, 101 ]
+const dem_asterisks = [2, 3, 4, 5, 19, 24, 26, 29, 33, 34, 36, 39, 40, 45, 46, 48, 49, 50, 54, 56, 58, 60, 61, 62, 63, 64, 65, 66, 68, 71, 72, 73, 74, 75, 77, 81, 84, 86, 87, 89, 90, 91, 93, 94, 97, 103, 105, 108, 110]
+
+const PC_TACTIC_FAILS = 52
+const PC_SUPPORT_FALTERS = 49
+const THE_CROWD_TURNS_AGAINST_CEAUSESCU_OCCURRED = 540
+const THE_TYRANT_IS_GONE_OCCURRED = 970
+
+// COUNTRY CONSTANTS
+
+const S_EAST_GERMANY = [0,1,2,3,4,5,6,7,8,9,10,11]
+const S_POLAND = [12,13,14,15,16,17,18,19,20,21,22,23,24,25]
+const S_CZECHOSLOVAKIA = [26,27,28,29,30,31,32,33,34,35,36]
+const S_HUNGARY = [37,38,39,40,41,42,43,44,45,46,47,48]
+const S_ROMANIA = [49,50,51,52,53,54,55,56,57,58,59,60,61,62]
+const S_BULGARIA = [63,64,65,66,67,68,69,70,71,72,73,74]
+
+exports.scenarios = [ "Standard" ]
+
+exports.roles = [ DEM, COM ]
+
+// --- SET UP ---
+
+exports.setup = function (seed, scenario, options) {
+ game = {
+ seed: seed,
+ log: [],
+ undo: [],
+ summary: [],
+ active: null,
+ state: 'place_starting_infl',
+ state: 'place_starting_infl',
+ return: '',
+ vm: null,
+ vm_event: 0,
+
+ played_card: 0,
+ available_ops: 0,
+ vm_available_ops: 0,
+ valid_spaces: [],
+ valid_cards: [],
+
+ vp: 0,
+ turn: 0,
+ round: 0,
+ round_player: COM,
+ stability: 0,
+ dem_tst_position: 0,
+ com_tst_position: 0,
+ dem_tst_attempted: 0,
+ com_tst_attempted: 0,
+ dem_tst_attempted_this_turn: 0,
+ com_tst_attempted_this_turn: 0,
+
+ demInfl: [],
+ comInfl: [],
+
+ strategy_deck: [],
+ strategy_discard: [],
+ discard: false,
+ view_opp_hand: false,
+ strategy_removed: [],
+ persistent_events: [],
+ power_struggle_deck: [],
+ power_struggle_discard: [],
+ dem_hand_limit: 8,
+ com_hand_limit: 8,
+ democrat_hand: [],
+ communist_hand: [],
+
+ is_pwr_struggle: false,
+ dem_pwr_hand_limit: 0,
+ com_pwr_hand_limit: 0,
+ dem_pwr_hand: [],
+ com_pwr_hand: [],
+ times_held: [0, 0, 0, 0, 0, 0],
+ revolutions: [false, false, false, false, false, false],
+ }
+
+ log_h1("1989 Dawn of Freedom")
+ game.active = COM
+ start_game()
+ return game
+}
+
+function start_game() {
+ // Draw cards
+ game.strategy_deck = draw_deck()
+
+ //Set starting influence
+ spaces.forEach((space, index) => {
+ game.demInfl[index] = space.demInfl
+ game.comInfl[index] = space.comInfl
+ })
+
+ //Set starting placement ops
+ game.starting_infl = [2, 3, 3, 4, 2]
+ game.temp = 0
+
+ // Set variable event cards where event is playable at start of game
+
+ game.playable_cards = [C_THE_WALL, C_GORBACHEV_CHARMS_THE_WEST, C_HONECKER, C_COMMON_EUROPEAN_HOME, C_MALTA_SUMMIT]
+
+ draw_cards(game.strategy_deck, game.democrat_hand, game.communist_hand, game.dem_hand_limit, game.com_hand_limit)
+
+ valid_spaces_setup()
+ game.available_ops = 2
+ log_h1("Place starting Support Points")
+ log_side()
+}
+
+exports.view = function(state, player) {
+ game = state
+
+ view = {
+ log: game.log,
+ active: game.active,
+ prompt: null,
+ actions: null,
+
+ played_card: game.played_card,
+ valid_spaces: game.valid_spaces,
+ valid_cards: game.valid_cards,
+
+ demInfl: game.demInfl,
+ comInfl: game.comInfl,
+ turn: game.turn,
+ round: game.round,
+ round_player: game.round_player,
+ vp: game.vp,
+ stability: game.stability,
+ dem_tst: game.dem_tst_position,
+ com_tst: game.com_tst_position,
+ persistent_events: game.persistent_events,
+ systematization: game.systematization,
+ the_tyrant_is_gone: game.the_tyrant_is_gone,
+
+ strategy_deck: game.strategy_deck.length,
+ strategy_removed: game.strategy_removed,
+ discard: game.discard,
+ show_opp_hand: game.view_opp_hand, /* Is this still needed?*/
+
+ democrat_hand: game.democrat_hand.length,
+ communist_hand: game.communist_hand.length,
+ democrat_power_hand: game.dem_pwr_hand.length,
+ communist_power_hand: game.com_pwr_hand.length,
+ ceausescu_cards: game.ceausescu_cards,
+ is_pwr_struggle: game.is_pwr_struggle,
+ times_held: game.times_held,
+ revolutions: game.revolutions,
+
+ hand: [],
+ set_aside: [],
+ pwr_hand: [],
+ }
+
+ if (game.is_pwr_struggle) {
+ view.power_struggle_discard = game.power_struggle_discard
+ view.played_power_card = game.played_power_card
+ view.power_card_1 = game.power_card_1
+ view.power_card_2 = game.power_card_2
+ }
+ view.strategy_discard = game.strategy_discard
+
+
+ if (player === game.active && game.vm && game.vm.draw)
+ view.drawn = game.vm.draw
+
+ if (player === game.active) {
+ if (game.selected_space >= 0)
+ view.selected_space = game.selected_space
+ }
+
+ if (player === DEM) {
+ view.hand = game.democrat_hand
+ if (game.communist_hand_red) {
+ view.opp_hand = game.communist_hand_red
+ }
+ view.set_aside = game.democrat_set_aside /*Is this being used? */
+ view.power_hand = [...game.dem_pwr_hand].sort((a, b) => a - b)
+
+ } else if (player === COM) {
+ view.hand = game.communist_hand
+ if (game.opp_power_hand && game.pwr_struggle_in === 'Romania') {view.opp_power_hand = [...game.dem_pwr_hand].sort((a, b) => a - b) }
+ view.power_hand = [...game.com_pwr_hand].sort((a, b) => a - b)
+ }
+
+ if (player === DEM) {
+ view.samizdat = game.samizdat_card
+ }
+
+ if (game.state === "game_over") {
+ view.prompt = game.victory
+ } else if (player === "Observer" || (game.active !== player && game.active !== "Both")) {
+ if (states[game.state]) {
+ let inactive = states[game.state].inactive
+ if (typeof inactive === "function")
+ view.prompt = `Waiting for ${game.active} ${inactive()}`
+ else
+ view.prompt = `Waiting for ${game.active} to ${inactive}`
+ } else {
+ view.prompt = "A Unknown state: " + game.state
+ }
+ } else {
+ view.actions = {}
+
+ if (states[game.state])
+ states[game.state].prompt(player)
+ else
+ view.prompt = "B Unknown state: " + game.state
+ if (view.actions.undo === undefined) {
+ if (game.undo && game.undo.length > 0)
+ view.actions.undo = 1
+ else
+ view.actions.undo = 0
+ }
+ }
+ return view
+}
+
+// === ACTIONS ===========
+
+function gen_action(action, argument) {
+ if (argument === undefined) {
+ view.actions[action] = 1
+ } else {
+ if (!(action in view.actions)) {
+ view.actions[action] = []
+ }
+ view.actions[action].push(argument)
+ }
+}
+
+function gen_action_space(space){
+ gen_action("space", space)
+}
+
+function gen_action_card(card){
+ gen_action("card", card)
+}
+
+function gen_action_power_card(card){
+ gen_action("power_card", card)
+}
+
+exports.action = function (state, player, action, arg) {
+ game = state
+ if (states[game.state] && action in states[game.state]) {
+ states[game.state][action](arg, player)
+ } else {
+ if (action === "undo" && game.undo && game.undo.length > 0)
+ pop_undo()
+ else
+ throw new Error("Invalid action: " + action)
+ }
+ return game
+}
+
+// ============= GAME STATES =======================
+
+states.place_starting_infl = {
+ inactive: 'place starting SPs.',
+ prompt() {
+ if (game.temp === 4 && game.available_ops === 0 ) {
+ view.prompt = 'Place starting SPs: done. Start Turn 1.';
+ gen_action("start");
+ } else if (game.available_ops === 0) {
+ view.prompt = 'Place starting SPs: done.';
+ gen_action("done");
+ return;
+ } else if (game.temp > 2) {
+ view.prompt = `Place your last ${pluralize(game.available_ops,'starting SP')}.`
+ } else {
+ view.prompt = `Place ${pluralize(game.available_ops,'starting SP')}.`
+ }
+ for (let space_id of game.valid_spaces) {
+ gen_action_space(space_id);
+ }
+ },
+ space(space) {
+ add_infl(space, 'available_ops')
+ },
+ done() {
+ do_log_summary()
+ game.temp ++
+ game.available_ops = game.starting_infl[game.temp]
+ next_player()
+ valid_spaces_setup()
+ },
+ start() {
+ do_log_summary()
+ delete game.starting_infl
+ new_turn()
+ clear_undo()
+ game.state = 'choose_card'
+ }
+}
+
+states.choose_card = {
+ inactive: 'choose a card.',
+ prompt() {
+ if ((game.active===DEM && game.democrat_hand.length === 0) || game.active === COM && game.communist_hand.length === 0) {
+ view.prompt = 'No cards remaining: you must pass.'
+ gen_action('pass')
+ } else {
+ view.prompt = 'Choose a card.'
+ let available_cards
+ if (game.active === DEM) {
+ available_cards = game.democrat_hand
+ } else {
+ available_cards = game.communist_hand
+ }
+ for (let card of available_cards) {
+ gen_action_card(card)
+ }
+ }
+ },
+ card(card) {
+ push_undo()
+
+ //Check if player is at risk of losing game due to held scoring card
+ if (!scoring_cards.includes(card)) {
+ let scoring_cards_count = count_scoring_cards()
+
+ if (game.round !== 8 && scoring_cards_count >= (8-game.round)){
+ game.temp = card
+ game.state = 'confirm_card'
+ return
+ }
+ }
+ select_card(card)
+ },
+ pass() {
+ log('No cards remaining. Passed')
+ game.state = 'end_round'
+ }
+}
+
+states.confirm_card = {
+ inactive: 'choose a card.',
+ prompt() {
+ let scoring_cards_count = count_scoring_cards()
+ view.prompt = `${pluralize(scoring_cards_count,'scoring card')} in hand with ${pluralize(8-game.round,'Action Round')} remaining. Scoring cards may not be held. Continue?`
+ gen_action('continue')
+ },
+ continue() {
+ select_card(game.temp)
+ }
+}
+
+states.play_card ={
+ get inactive() {
+ return `play ${clean_name(cards[game.played_card].name)}.`
+ },
+ prompt () {
+ view.prompt = `Play ${clean_name(cards[game.played_card].name)} for:`
+
+ if (scoring_cards.includes(game.played_card)) {
+ gen_action('event')
+ return
+ }
+
+ // Check for Reformer Rehabilitated
+ if (game.played_card === C_REFORMER_REHABILITATED && game.playable_cards.includes(C_REFORMER_REHABILITATED)){
+ if (game.active === DEM && (game.dem_tst_position > game.com_tst_position)) {
+ gen_action('event')
+ }
+ if (game.active === COM && (game.dem_tst_position < game.com_tst_position)) {
+ gen_action('event')
+ }
+ }
+
+ //Check for events
+ if (event_is_playable(game.played_card)) {
+ if ((game.active === DEM && cards[game.played_card].side === 'C' && game.dem_tst_position >= 7 && game.com_tst_position < 7 && !game.tst_7) || (game.active === COM && cards[game.played_card].side === 'D' && game.com_tst_position >= 7 && game.dem_tst_position < 7 && !game.tst_7)){
+ gen_action('tst_7')
+ }
+ if ((game.active === DEM && cards[game.played_card].side !== 'C' && game.dem_tst_position >= 8 && game.com_tst_position < 8 && !game.tst_8) || (game.active === COM && cards[game.played_card].side !== 'D' && game.com_tst_position >= 8 && game.dem_tst_position < 8 && !game.tst_8)){
+ gen_action('tst_8')
+ }
+
+ //Continue with normal logic
+ get_events(game.played_card)
+ }
+
+ gen_action('influence')
+ gen_action('support_check')
+
+ if ((game.active === DEM && game.dem_tst_attempted_this_turn === 0 && game.dem_tst_position < 8 ) || (game.active === COM && game.com_tst_attempted_this_turn === 0 && game.com_tst_position < 8)) {
+ gen_action('tst')
+ }
+ },
+ event() {
+ push_undo()
+ log_gap(`Played C${game.played_card} for the event`)
+ game.vm_infl_to_do = false
+ game.return = game.active
+ if (switch_events.includes(game.played_card)) {next_player()}
+ game.vm_event = game.played_card
+ goto_vm(game.vm_event)
+ },
+ opp_event() {
+ push_undo()
+ log_gap(`Played C${game.played_card} for the event`)
+ game.vm_infl_to_do = true
+ game.return = game.active
+ game.vm_event = game.played_card
+ if (is_auto_resolve(game.played_card) || switch_events.includes(game.played_card)) {
+ goto_vm(game.vm_event)}
+ else {
+ next_player()
+ log(`C${game.vm_event}:`)
+ goto_vm(game.vm_event)
+ }
+ },
+ influence() {
+ push_undo()
+ log_gap(`Played C${game.played_card} to place SPs`)
+ finish_play_card()
+
+ // If ABHR - Set AHBR tracker to true
+ if (game.persistent_events.includes(58)) {
+ game.austria_hungary_border_reopened_tracker = true
+ }
+ game.state='add_influence'
+ valid_spaces_infl()
+ },
+ tst() {
+ push_undo()
+ log_gap(`Played C${game.played_card} to the Tiananmen Square Track`)
+ finish_play_card()
+ game.state='tiananmen_square_attempt'
+ },
+ support_check() {
+ push_undo()
+ log_gap(`Played C${game.played_card} for support checks`)
+ finish_play_card()
+ game.available_ops = 2
+ game.state='support_check_prep'
+ valid_spaces_sc()
+ },
+ tst_7() { /*Cancel opponent event */
+ push_undo()
+ log(`Played C${game.played_card}. Event cancelled using TST Award`)
+ game.tst_7 = true
+ game.vm_infl_to_do = true
+ game.state = 'resolve_opponent_event'
+ },
+ tst_8() { /*Play card for ops and event */
+ push_undo()
+ game.vm_event_to_do = true
+ game.vm_infl_to_do = true
+ game.tst_8 = true
+ log(`Played C${game.played_card} for event and operations`)
+ game.state = 'vm_tst_8'
+ },
+ end_round () {
+ end_round()
+ }
+}
+
+states.resolve_opponent_event = {
+ get inactive() {
+ return `resolve ${clean_name(cards[game.played_card].name)}.`
+ },
+ prompt() {
+ if (game.vm_infl_to_do) {
+ view.prompt = 'Event resolved. Choose to play card for:'
+ gen_action('influence')
+ gen_action('support_check')
+ } else if (game.vm_event_to_do) {
+ // Check for Tiananmen Square Track ability - play opponent card without triggering event
+ if ((game.active === DEM && game.dem_tst_position >= 7 && game.com_tst_position < 7 && !game.tst_7) || (game.active === COM && game.com_tst_position >= 7 && game.dem_tst_position < 7 && !game.tst_7)){
+ gen_action('tst_7')
+ }
+ view.prompt = `${clean_name(cards[game.played_card].name)}: you must resolve the opponent event.`
+ gen_action('opp_event')
+ } else {
+ view.prompt = 'Event resolved. End the action round.'
+ gen_action('end_round')
+ }
+ },
+ influence(){
+ push_undo()
+ // If ABHR - Set AHBR tracker to true
+ if (game.persistent_events.includes(58)) {
+ game.austria_hungary_border_reopened_tracker = true
+ }
+ game.state = 'add_influence'
+ valid_spaces_infl()
+ },
+ support_check() {
+ push_undo()
+ game.available_ops = 2
+ game.state = 'support_check_prep'
+ valid_spaces_sc()
+ },
+ opp_event() {
+ game.vm_event_to_do = false
+ game.return_state = 'resolve_opponent_event'
+ game.vm_event = game.played_card
+ log(`Played C${game.played_card} for the event`)
+ if (is_auto_resolve(game.played_card) || switch_events.includes(game.played_card)) {
+ game.return = game.active
+ goto_vm(game.vm_event)}
+ else {
+ if (game.active === DEM) {
+ game.return = COM
+ } else {
+ game.return = DEM
+ }
+ next_player()
+ log(`C${game.played_card}:`)
+ goto_vm(game.vm_event)
+ }
+ },
+ tst_7() {
+ push_undo()
+ log('Event cancelled using TST Award')
+ game.tst_7 = true
+ game.vm_event_to_do = false
+ },
+ end_round() {
+ push_undo()
+ end_round()
+ }
+}
+
+states.add_influence = {
+ inactive: 'add SPs.',
+ prompt () {
+ if (game.available_ops <= 0) {
+ view.prompt = 'Place SPs: done.'
+ if (!game.vm_event_to_do) {
+ gen_action("end_round")
+ } else {
+ gen_action('done')
+ }
+ } else {
+ view.prompt = `Add SPs: ${game.available_ops} remaining.`
+ for (let space_id of game.valid_spaces) {
+ gen_action_space(space_id);
+ }
+ }
+ },
+ space(space) {
+ add_infl(space, 'available_ops')
+ },
+ end_round() {
+ push_undo()
+ do_log_summary()
+ end_round()
+ },
+ done() {
+ do_log_summary()
+ reset_austria_hungary_border_reopened()
+ game.state = 'resolve_opponent_event'
+ }
+}
+
+states.tiananmen_square_attempt = {
+ inactive: 'do Tiananmen Square Attempt.',
+ prompt () {
+ view.prompt = 'Tiananmen Square Track attempt: Roll a die.'
+ gen_action('roll')
+ },
+ roll() {
+ clear_undo()
+ game.vm_event_to_do = false
+ do_tst_attempt ()
+ }
+}
+
+states.tiananmen_square_attempt_success = {
+ inactive: 'do Tiananmen Square Attempt.',
+ prompt () {
+ if (game.vm_event > 200) {
+ view.prompt = 'Tiananmen Square Track attempt successful. Go to TST Award.'
+ gen_action('done')
+ } else {
+ view.prompt = 'Tiananmen Square Track attempt successful.'
+ gen_action('end_round')
+ }
+
+ },
+ done () {
+ push_undo()
+ goto_vm(game.vm_event)
+ },
+ end_round () {
+ push_undo()
+ end_round()
+ }
+}
+
+states.tiananmen_square_attempt_fail = {
+ inactive: 'do Tiananmen Square Attempt.',
+ prompt () {
+ view.prompt = 'Tiananmen Square Track attempt failed.'
+ gen_action('end_round')
+ },
+ end_round () {
+ push_undo()
+ end_round()
+ }
+}
+
+states.tiananmen_square_attempt_done = {
+ inactive: 'do Tiananmen Square Attempt.',
+ prompt () {
+ view.prompt = 'Tiananmen Square Track attempt: done.'
+ gen_action('end_round')
+ },
+ end_round () {
+ end_round()
+ }
+}
+
+states.tst_goddess = {
+ inactive: 'choose whether to discard a card.',
+ prompt() {
+ view.prompt = 'Tiananmen Square Track award: you may discard a non-Power Struggle Card and draw a replacement.'
+ for (let card of game.valid_cards) {
+ gen_action_card(card)
+ }
+ gen_action('pass')
+ },
+ card(card) {
+ push_undo()
+ discard(card)
+ game.valid_cards = []
+ game.state = 'tst_goddess_draw'
+ },
+ pass() {
+ log('Did not discard')
+ end_goddess()
+ },
+}
+
+states.tst_goddess_draw = {
+ inactive: 'choose whether to discard a card.',
+ prompt() {
+ view.prompt = 'Draw a replacement card.'
+ gen_action('draw')
+ },
+ draw() {
+ if (game.active === DEM) {
+ draw_cards(game.strategy_deck, game.democrat_hand, game.communist_hand, game.democrat_hand.length +1, game.communist_hand.length)
+ } else {
+ draw_cards(game.strategy_deck, game.democrat_hand, game.communist_hand, game.democrat_hand.length, game.communist_hand.length +1)
+ }
+ end_goddess()
+ }
+}
+
+states.support_check_prep = {
+ inactive: 'do support checks',
+ prompt () {
+ if (game.available_ops === 0) {
+ if (game.is_pwr_struggle) {
+ view.prompt = 'The Crowd Turns Against Ceausescu. Support checks: done.'
+ gen_action('done')
+ } else if (!game.vm_event_to_do) {
+ view.prompt = 'Support checks: done.'
+ gen_action('end_round')
+ } else {
+ view.prompt = 'Support checks: done.'
+ gen_action('done')
+ }
+ } else if (game.available_ops > 0) {
+ view.prompt = `Select a space. ${pluralize(game.available_ops, 'support check')} remaining.`
+ for (let space_id of game.valid_spaces) {
+ gen_action_space(space_id)
+ }
+ }
+ },
+ space(space) {
+ push_undo()
+ game.selected_space = space
+
+ // Check for Austria-Hungary Border Reopened - check on first support check only
+ if (game.persistent_events.includes(58)) {
+ if (game.active === DEM && game.available_ops > 1) {
+ if (spaces[game.selected_space].country === 'East_Germany' && game.persistent_events.includes(58) && game.active === DEM) {
+ game.state = 'austria_hungary_border_reopened_check'
+ return
+ }
+ }
+ }
+
+ game.state = 'do_support_check'
+ },
+ end_round() {
+ push_undo()
+ end_round()
+ },
+ done() {
+ push_undo()
+ if (game.is_pwr_struggle) {/*Crowd Turns Against Ceausescu should be the only time you end up here during a power struggle */
+ if (game.return !== game.active) {
+ next_player()
+ }
+ log_h2('Raise the Stakes')
+ game.state = 'raise_stakes_1'
+ return
+ }
+ reset_austria_hungary_border_reopened()
+ game.state = 'resolve_opponent_event'
+ }
+}
+
+states.do_support_check = {
+ inactive: 'do support checks.',
+ prompt () {
+ view.prompt = `Support check: ${spaces[game.selected_space].name_unique}. Roll a die.`
+ gen_action('roll')
+ },
+ roll() {
+ clear_undo()
+ do_sc(game.selected_space)
+ game.available_ops--
+ if (game.available_ops === 0) {
+ game.valid_spaces = []
+ }
+ if (check_vp()) {
+ return
+ } else {
+ game.state = 'support_check_prep'
+ return
+ }
+ }
+}
+
+states.austria_hungary_border_reopened_check = {
+ inactive: 'decide Austria-Hungary Border Reopened.',
+ prompt() {
+ view.prompt = 'Austria-Hungary Border Reopened: will both support checks be in East Germany?'
+ gen_action('yes')
+ gen_action('no')
+ },
+ yes() {
+ game.austria_hungary_border_reopened_tracker = true
+ game.state = 'do_support_check'
+ },
+ no() {
+ game.state = 'do_support_check'
+ }
+}
+
+states.end_round = {
+ inactive: 'finish playing a card.',
+ prompt() {
+ view.prompt = 'End the Action Round.'
+ gen_action('end_round')
+ },
+ end_round() {
+ push_undo()
+ end_round()
+ }
+}
+
+//======================= POWER STRUGGLE ===============================
+
+states.draw_power_cards = {
+ inactive: 'draw cards.',
+ prompt() {
+ view.prompt = `${clean_name(cards[this_card()].name)}: draw cards.`
+ gen_action('draw')
+ },
+ draw() {
+ push_undo()
+ game.power_struggle_deck = [...all_power_cards]
+ let presence = check_presence(game.pwr_struggle_in)
+ if (presence.dem_spaces > 0) {
+ game.dem_pwr_hand_limit = 6 + 2*(presence.dem_spaces - 1)
+ } else {
+ game.dem_pwr_hand_limit = 0
+ }
+ if (presence.com_spaces > 0 ) {
+ game.com_pwr_hand_limit = 6 + 2*(presence.com_spaces - 1)
+ } else {
+ game.com_pwr_hand_limit = 0
+ }
+ // Events which affect cards drawn
+ if (game.persistent_events.includes(C_ROUNDTABLE_TALKS) && game.com_pwr_hand_limit >= 2) {
+ log(`Democrat receives 2 cards from Communist due to C${C_ROUNDTABLE_TALKS}`)
+ game.dem_pwr_hand_limit += 2
+ game.com_pwr_hand_limit -= 2
+ game.persistent_events = game.persistent_events.filter(n => n !== C_ROUNDTABLE_TALKS)
+ game.strategy_discard.push(C_ROUNDTABLE_TALKS)
+ }
+
+ if (game.persistent_events.includes(C_PEASANT_PARTIES_REVOLT)) {
+ let farmer_check
+ for (let space of spaces) {
+ if (space && space.country === game.pwr_struggle_in && space.socio === 3 && check_dem_control(space.space_id)) {
+ farmer_check = true
+ }
+ }
+ if (farmer_check && game.com_pwr_hand_limit > 0) {
+ log(`Democrat receives 1 cards from Communist due to C${C_PEASANT_PARTIES_REVOLT}`)
+ game.dem_pwr_hand_limit += 1
+ game.com_pwr_hand_limit -= 1
+ permanently_remove(C_PEASANT_PARTIES_REVOLT)
+ }
+ }
+
+ if (game.persistent_events.includes(C_NATIONAL_SALVATION_FRONT) && game.dem_pwr_hand_limit >=2 && (game.pwr_struggle_in === 'Romania' || game.pwr_struggle_in === 'Bulgaria')) {
+ log(`Communist receives 2 cards from Democrat due to C${C_NATIONAL_SALVATION_FRONT}`)
+ game.dem_pwr_hand_limit -= 2
+ game.com_pwr_hand_limit += 2
+ permanently_remove(C_NATIONAL_SALVATION_FRONT)
+ }
+
+ //Draw Power Cards
+ game.is_pwr_struggle = true
+ draw_cards(game.power_struggle_deck, game.dem_pwr_hand, game.com_pwr_hand, game.dem_pwr_hand_limit, game.com_pwr_hand_limit)
+ if (game.active === DEM) {
+ game.valid_cards = [...game.dem_pwr_hand]
+ } else {
+ game.valid_cards = [...game.com_pwr_hand]
+ }
+
+ log(`Communist: ${game.com_pwr_hand.length} cards`)
+ log(`Democrat: ${game.dem_pwr_hand.length} cards`)
+
+ //Check if The Crowd Turns Against Ceausescu occurs
+ if (game.persistent_events.includes(C_THE_CROWD_TURNS_AGAINST_CEAUSESCU) && !game.persistent_events.includes(THE_CROWD_TURNS_AGAINST_CEAUSESCU_OCCURRED) && game.pwr_struggle_in === 'Romania') {
+ if (game.active === COM) {
+ game.return = COM
+ next_player()
+ }
+ log_h3(`C${C_THE_CROWD_TURNS_AGAINST_CEAUSESCU}`)
+ game.persistent_events.push(THE_CROWD_TURNS_AGAINST_CEAUSESCU_OCCURRED)
+ game.state = 'the_crowd_turns_against_ceausescu_prep'
+ } else {
+ log_h2('Raise the Stakes')
+ game.state = 'raise_stakes_1'
+ }
+ }
+}
+
+states.the_crowd_turns_against_ceausescu_prep = {
+ get inactive() {
+ return `resolve ${clean_name(cards[C_THE_CROWD_TURNS_AGAINST_CEAUSESCU].name)}.`
+ },
+ prompt() {
+ view.prompt = 'The Crowd Turns Against Ceausescu: draw cards.'
+ gen_action('draw')
+ },
+ draw() {
+ game.ceausescu_cards = []
+ draw_cards(game.power_struggle_deck, game.ceausescu_cards, game.com_pwr_hand, 15, game.com_pwr_hand.length)
+ game.temp = game.ceausescu_cards.filter(card => rallies.includes(card)).length
+ log(`Drew ${pluralize(game.temp, 'Rally in the Square')}.`)
+ game.vm_available_ops = game.temp * 3
+ log(`Democrat takes a ${game.vm_available_ops} Op Action Round`)
+ game.state = 'vm_the_crowd_turns_against_ceausescu'
+ }
+}
+
+states.vm_the_crowd_turns_against_ceausescu = {
+ get inactive() {
+ return `resolve ${clean_name(cards[C_THE_CROWD_TURNS_AGAINST_CEAUSESCU].name)}.`
+ },
+ prompt() {
+ view.prompt = `You have ${game.vm_available_ops} operations points. Play for:`
+ gen_action('influence')
+ gen_action('support_check')
+ },
+ influence() {
+ push_undo()
+ delete game.ceausescu_cards
+ valid_spaces_infl()
+ game.valid_spaces = game.valid_spaces.filter(n => spaces[n].country === 'Romania')
+ game.state = 'the_crowd_turns_against_ceausescu_infl' /* Send this to add_infl. Add check at end of add_infl similar to valid_spaces*/
+ },
+ support_check() {
+ push_undo()
+ delete game.ceausescu_cards
+ valid_spaces_sc()
+ game.available_ops = 2
+ game.state = 'support_check_prep'
+ }
+}
+
+states.the_crowd_turns_against_ceausescu_infl = {
+ inactive: 'add SPs.',
+ prompt () {
+ if (game.vm_available_ops === 0)
+ {
+ view.prompt = 'Place SPs: done.';
+ gen_action("done");
+ return;
+ }
+
+ view.prompt = `Add SPs: ${game.vm_available_ops} remaining`
+ for (let space of game.valid_spaces) {
+ gen_action_space(space)
+ }
+ },
+ space(space) {
+ add_infl(space, 'vm_available_ops')
+ },
+ done() {
+ do_log_summary()
+ if (game.return !== game.active) {
+ next_player()
+ }
+ log_h2('Raise the Stakes')
+ game.state = 'raise_stakes_1'
+ }
+}
+
+states.raise_stakes_1 = {
+ inactive: 'raise the stakes.',
+ prompt () {
+ if ((game.active === DEM && game.dem_pwr_hand.length < 3) || (game.active === COM && game.com_pwr_hand.length < 3)) {
+ view.prompt = 'Raise the stakes: you must pass.'
+ gen_action('pass')
+ }
+ else if (game.raised_stakes_discard === 3) {
+ view.prompt = 'Raise the stakes: done.'
+ gen_action('done')
+ } else {
+ view.prompt = `Discard ${3-game.raised_stakes_discard} cards to raise the stakes.`
+ if (game.raised_stakes_discard === 0) {
+ gen_action('pass')
+ }
+ for (let card of game.valid_cards) {
+ gen_action_power_card(card)
+ }
+ }
+ },
+ power_card(card) {
+ push_undo()
+ if (numberless_cards.includes(card)) {
+ log(`Discarded: P${card}`)
+ } else {
+ log(`Discarded: P${card} V${power_cards[card].value}`)
+ }
+ discard(card)
+
+ game.raised_stakes_discard ++
+ if (game.raised_stakes_discard === 3) {
+ game.raised_stakes++
+ game.valid_cards = []
+ }
+ },
+ pass(){
+ log('Did not raise the stakes')
+ game.raised_stakes_discard = 0
+ next_player()
+ if (game.active === DEM) {
+ game.valid_cards = [...game.dem_pwr_hand]
+ } else {
+ game.valid_cards = [...game.com_pwr_hand]
+ }
+ game.state = 'raise_stakes_2'
+ },
+ done () {
+ log_gap('Raised the stakes')
+ game.raised_stakes_discard = 0
+ next_player()
+ if (game.active === DEM) {
+ game.valid_cards = [...game.dem_pwr_hand]
+ } else {
+ game.valid_cards = [...game.com_pwr_hand]
+ }
+ game.state = 'raise_stakes_2'
+ }
+}
+
+states.raise_stakes_2 = {
+ inactive: 'raise the stakes.',
+ prompt () {
+ if ((game.active === DEM && game.dem_pwr_hand.length < 3) || (game.active === COM && game.com_pwr_hand.length < 3)) {
+ view.prompt = 'Raise the stakes: you must pass.'
+ gen_action('pass')
+ return
+ }
+ if (game.raised_stakes_discard === 3) {
+ view.prompt = 'Raise the stakes: done.'
+ gen_action('done')
+ } else {
+ view.prompt = `Discard ${3-game.raised_stakes_discard} cards to raise the stakes.`
+ if (game.raised_stakes_discard === 0) {
+ gen_action('pass')
+ }
+ for (let card of game.valid_cards) {
+ gen_action_power_card(card)
+ }
+ }
+ },
+ power_card(card) {
+ push_undo()
+ if (numberless_cards.includes(card)) {
+ log(`Discarded: P${card}`)
+ } else {
+ log(`Discarded: P${card} V${power_cards[card].value}`)
+ }
+ discard(card)
+
+ game.raised_stakes_discard ++
+ if (game.raised_stakes_discard === 3) {
+ game.raised_stakes++
+ game.valid_cards = []
+ }
+ },
+ pass() {
+ log('Did not raise the stakes')
+ goto_struggle()
+ },
+ done () {
+ log_gap('Raised the stakes')
+ goto_struggle()
+ },
+}
+
+states.power_struggle = {
+ inactive: 'play a card.',
+ prompt () {
+ if (game.phase === 0) {
+ if (game.valid_cards.length > 0) {
+ view.prompt = "Play a card."
+ for (let card of game.valid_cards) {
+ gen_action_power_card(card)
+ }
+ } else if ( game.valid_cards.length === 0) {
+ view.prompt = 'No valid cards. You must concede.'
+ gen_action('concede')
+ }
+ }
+ if (game.phase === 1) {
+ let base_prompt = `${power_cards[game.played_power_card].name} played` + (leader_cards.includes(game.played_power_card) ? ` as a ${game.proxy_power_card}.` : ".")
+ if (game.valid_cards.length > 0) {
+ view.prompt = `${base_prompt} You must match or concede.`;
+ for (let card of game.valid_cards) {
+ gen_action_power_card(card);
+ }
+ } else {
+ view.prompt = `${base_prompt} You must concede.`;
+ }
+ gen_action('concede')
+ }
+ else if (game.phase === 2) {
+ view.prompt = 'You matched. Roll a die.'
+ gen_action('roll')
+ }
+ else if (game.phase === 3) {
+ view.prompt = 'Play leader as:'
+ if (game.tactics_fails !== "Strike") {gen_action('strike')}
+ if (game.tactics_fails !== "March") {gen_action('march')}
+ if (game.tactics_fails !== "Rally in the Square") {gen_action('rally')}
+ if (game.tactics_fails !== "Petition") {gen_action('petition')}
+ }
+ },
+ power_card(card) {
+ push_undo()
+ discard(card)
+ if (game.phase === 0) {
+ game.power_card_1 = card
+ delete game.power_card_2
+ }
+ if (game.phase === 1) {
+ game.power_card_2 = card
+ }
+ game.valid_cards=[]
+ game.return_state = 'power_struggle'
+ if (game.phase === 0) {delete game.proxy_power_card}
+ if (card === PC_TACTIC_FAILS) {
+ if (game.proxy_power_card) {
+ log_gap(`Played P${PC_TACTIC_FAILS}: ${game.proxy_power_card} no longer playable`)
+ } else {
+ log_gap(`Played P${PC_TACTIC_FAILS}: P${game.played_power_card} no longer playable`)
+ }
+ } else {
+ if (game.phase === 0 && leader_cards.includes(card)) {} /* Log nothing. Probably a better way to do this */
+ else if (numberless_cards.includes(card)) {
+ log_gap(`Played: P${card}`)
+ } else {
+ log_gap(`Played: P${card} V${power_cards[card].value}`)
+ }
+ }
+ if (game.phase === 0) {
+ if (leader_cards.includes(card)) {
+ game.played_power_card = card
+ game.phase = 3
+ } else if (card === 51){ /*Scare Tactics */
+ game.return = ''
+ goto_vm(351) /*Can I combine these 3 into a single stage where you goto_vm(300 + card) ? */
+ } else if (card === 50) { /*Support Surges */
+ if (game.active === DEM) {
+ game.return = COM
+ } else {
+ game.return = DEM
+ }
+ goto_vm(350)
+ } else if (game.phase === 0 && card === 49) { /*Support Falters */
+ next_player()
+ goto_vm(349)
+ } else {
+ game.played_power_card = card
+ game.phase = 1
+ next_player()
+ do_valid_cards()
+ }
+ } else if (game.phase === 1) {
+ if (card === PC_TACTIC_FAILS) {
+ if (game.proxy_power_card) {
+ game.tactics_fails = game.proxy_power_card
+ } else {
+ game.tactics_fails = power_cards[game.played_power_card].name
+ }
+ game.phase = 0
+ next_player()
+ do_valid_cards()
+ } else if (power_cards[game.played_power_card].value === 1) {
+ log('Takes initiative')
+ game.phase = 0
+ do_valid_cards()
+ } else {
+ game.phase = 2
+ }
+ }
+ },
+ roll () {
+ clear_undo()
+ let roll = roll_d6()
+ log(`Roll: D${roll}`)
+ if (roll >= power_cards[game.played_power_card].value) {
+ log('Initiative roll successful')
+ game.phase = 0
+ do_valid_cards()
+ } else {
+ log(`Initiative roll failed. Required ${power_cards[game.played_power_card].value} or more`)
+ game.phase = 0
+ next_player()
+ do_valid_cards()
+ }
+ },
+ concede () {
+ push_undo()
+ game.valid_cards = []
+ delete game.power_card_1
+ delete game.power_card_2
+ log('Conceded')
+ log_h2('Aftermath')
+ log_h3('Support Loss')
+ if (game.phase === 0) {
+ game.played_power_card = 0
+ game.proxy_power_card = 0 /*If conceded when held the initiative but had no playable cards, ignore the last played card */
+ }
+ game.phase = 0
+ game.state = 'support_loss'
+ },
+ strike () {
+ log(`Played: P${game.played_power_card} as a Strike`)
+ game.proxy_power_card = 'Strike'
+ game.phase = 1
+ next_player()
+ do_valid_cards()
+ },
+ march () {
+ log(`Played: P${game.played_power_card} as a March`)
+ game.proxy_power_card = 'March'
+ game.phase = 1
+ next_player()
+ do_valid_cards()
+ },
+ rally () {
+ log(`Played: P${game.played_power_card} as a Rally in the Square`)
+ game.proxy_power_card = 'Rally in the Square'
+ game.phase = 1
+ next_player()
+ do_valid_cards()
+ },
+ petition () {
+ log(`Played: P${game.played_power_card} as a Petition`)
+ game.proxy_power_card = 'Petition'
+ game.phase = 1
+ next_player()
+ do_valid_cards()
+ }
+}
+
+states.support_loss ={
+ inactive: 'do Support Loss.',
+ prompt () {
+ let ps_state = game.persistent_events.includes(111) ? "New Year's Eve Party" : "Power Struggle"
+ if (game.phase === 0) {
+ view.prompt = 'You lost the Power Struggle. Roll a die for Support Loss.'
+ gen_action('roll')
+ } else if (game.phase === 1 && game.available_ops > 0 && game.valid_spaces.length > 0) {
+ view.prompt = `${ps_state} - ${country_name(game.pwr_struggle_in)}. Support Loss: remove ${pluralize(game.available_ops,'SP')}.`
+
+ for (let space_id of game.valid_spaces) {
+ gen_action_space(space_id)
+ }
+ } else if (game.phase === 1 && game.available_ops === 0 ) {
+ view.prompt = `${ps_state} - ${country_name(game.pwr_struggle_in)}. Support Loss: finished.`
+ gen_action('done')
+ } else if (game.phase === 1 && game.valid_spaces.length === 0) {
+ view.prompt = `${ps_state} - ${country_name(game.pwr_struggle_in)}. Support Loss: no remaining SPs to remove.`
+ gen_action('done')
+ }
+ },
+ roll () {
+ game.available_ops = support_loss_roll[get_aftermath_roll()]
+ if (game.available_ops === 0) {
+ log('Does not remove SPs')
+ }
+ game.phase++
+ if (game.available_ops > 0) {
+ valid_spaces_support_loss()
+ }
+ },
+ space(space) {
+ game.remove_opponent_infl = false /* Don't know why this is needed... */
+ remove_infl(space, 'available_ops')
+ },
+ done () {
+ do_log_summary()
+ next_player()
+ log_h3('Victory Point')
+ game.phase = 0
+ game.state = 'vp_roll'
+ }
+}
+
+states.vp_roll = {
+ inactive: 'do VP Roll.',
+ prompt () {
+ let ps_state = game.persistent_events.includes(111) ? "New Year's Eve Party" : "Power Struggle"
+ if (game.phase === 0) {
+ view.prompt = `${ps_state} - ${country_name(game.pwr_struggle_in)}: roll a die for Victory.`
+ gen_action('roll')
+ } else if (game.phase === 1) {
+ view.prompt = `${ps_state} - ${country_name(game.pwr_struggle_in)}: take power.`
+ gen_action('take')
+ } else if (game.phase === 2) {
+ view.prompt = `${ps_state} - ${country_name(game.pwr_struggle_in)}: proceed to scoring.`
+ gen_action('scoring')
+ }
+ },
+ roll () {
+ let roll = get_aftermath_roll()
+ let vp_change = vp_roll[roll]
+ if (game.active === DEM) {
+ log(`+${vp_change} VP`)
+ } else {
+ log(`-${vp_change} VP`)
+ }
+ if (game.active === DEM) {game.vp += vp_change}
+ else {game.vp -= vp_change}
+ if (game.active === DEM && roll >= 4) {
+ game.phase = 1
+ } else {
+ game.phase = 0
+ if (game.active === DEM) {next_player()}
+ game.state = 'choose_power'
+ }
+ },
+ take () {
+ push_undo()
+ let scoring_card = scoring_cards[countries.indexOf(game.pwr_struggle_in)]
+ permanently_remove(scoring_card)
+ take_power(game.pwr_struggle_in)
+ game.phase = 2
+ },
+ scoring () {
+ push_undo()
+ log_h2('Scoring')
+ score_country(game.pwr_struggle_in)
+ resolve_tyrant()
+ },
+}
+
+states.choose_power = {
+ inactive: 'choose whether to remain in power.',
+ prompt () {
+ if (game.phase === 0) {
+ view.prompt = 'Choose whether to remain in power.'
+ gen_action('retain')
+ gen_action('surrender')
+ } else if (game.phase === 1) {
+ view.prompt = 'Proceed to scoring.'
+ gen_action('scoring')
+ }
+ },
+ retain() {
+ push_undo()
+ retain_power(game.pwr_struggle_in)
+ game.phase = 1
+ },
+ surrender () {
+ push_undo()
+ take_power(game.pwr_struggle_in)
+ permanently_remove(game.played_card)
+ game.phase = 1
+ },
+ scoring () {
+ push_undo()
+ score_country(game.pwr_struggle_in)
+ resolve_tyrant()
+ }
+}
+
+states.the_tyrant_is_gone ={
+ inactive: 'resolve The Tyrant is Gone.',
+ prompt() {
+ view.prompt = 'Play The Tyrant is Gone for the event.'
+ gen_action('event')
+ },
+ event() {
+ if (game.active !== DEM) {
+ next_player()
+ }
+ log_h3(`C${C_THE_TYRANT_IS_GONE}`)
+ game.vm_event = C_THE_TYRANT_IS_GONE
+ goto_vm(game.vm_event)
+ }
+}
+
+states.finish_scoring ={
+ inactive: 'finish scoring.',
+ prompt() {
+ view.prompt = 'End power struggle.'
+ gen_action('done')
+ } ,
+ done() {
+ log_msg_gap('Power Struggle resolved') /*At this point log card dicarded or permanently removed? */
+ if (game.persistent_events.includes(111)) {
+ game.state = 'new_years_eve_party'
+ return
+ }
+ if (check_vp()) {
+ return
+ }
+ reset_power()
+ end_round()
+ }
+}
+
+// ======================================= END TURN STATES ==========================================
+
+states.end_turn_4_5_4 = {
+ inactive: 'verify held cards.',
+ prompt() {
+ view.prompt = 'End Turn: verify held cards.'
+ gen_action('check')
+ },
+ check() {
+ log_h2('Verify held cards')
+ const dem_has_scoring_card = game.democrat_hand.some(card => scoring_cards.includes(card))
+ const com_has_scoring_card = game.communist_hand.some(card => scoring_cards.includes(card))
+ if (!dem_has_scoring_card && !com_has_scoring_card) {
+ log('No held scoring cards')
+ }
+
+ if (dem_has_scoring_card && com_has_scoring_card) {
+ log('Both players have held scoring cards')
+ goto_game_over('', `The game is tied due to held scoring cards!`)
+ }
+ else if (dem_has_scoring_card) {
+ log('Democrat player has a held scoring card')
+ goto_game_over(COM, `${COM} won by held scoring card!`)
+ }
+ else if (com_has_scoring_card) {
+ log('Communist player has a held scoring card')
+ goto_game_over(DEM, `${DEM} won by held scoring card!`)
+ }
+ else if (game.persistent_events.includes(C_NEW_YEARS_EVE_PARTY)) {
+ log_h1(`New Year's Eve Party`)
+ game.vm_event = 104
+ //Check if the Communist receives VP from The Tyrant is Gone
+ if (game.the_tyrant_is_gone && game.the_tyrant_is_gone > 0) {
+ game.vp -= 2
+ log(`Communist receives 2 VP from C97`)
+ }
+ game.persistent_events.push(111)
+ if (game.active !== DEM) {
+ next_player()
+ }
+ game.state = 'new_years_eve_party'
+ }
+ else if(game.turn === 10) {
+ clear_undo()
+ log_h2('Final Scoring')
+
+ //Check if the Communist receives VP from The Tyrant is Gone
+ if (game.the_tyrant_is_gone && game.the_tyrant_is_gone > 0) {
+ game.vp -= 2
+ log(`Communist receives 2 VP from C97`)
+ }
+ game.state = 'final_scoring_held'
+
+ } else {
+ new_turn()
+ }
+ }
+}
+
+states.final_scoring_held = {
+ inactive: 'resolve final scoring.',
+ prompt() {
+ view.prompt = 'Final Scoring: Communist scores VP bonus for the number of countries they retain power.'
+ gen_action('bonus')
+ },
+ bonus() {
+ push_undo()
+ const held_countries = game.revolutions.filter(value => value === false).length
+ let vp_gain = 4*held_countries
+ log(`Communist holds power in ${pluralize(held_countries, 'country', 's')}: -${vp_gain} VP`)
+ game.vp -= 4*held_countries
+ game.temp = {'East_Germany': false, 'Poland': false, 'Czechoslovakia': false, 'Hungary': false, 'Romania': false, 'Bulgaria': false}
+ game.state = 'final_scoring'
+ }
+}
+
+states.final_scoring = {
+ inactive: 'score countries.',
+ prompt() {
+ if (game.temp['East_Germany'] && game.temp['Poland'] && game.temp['Czechoslovakia'] && game.temp['Hungary'] && game.temp['Romania'] && game.temp['Bulgaria']) {
+ view.prompt = 'Final scoring: done.'
+ gen_action('end')
+ } else {
+ view.prompt = 'Choose a country to score:'
+ if (!game.temp['East_Germany']) {gen_action('east_germany')}
+ if (!game.temp['Poland']) {gen_action('poland')}
+ if (!game.temp['Czechoslovakia']) {gen_action('czechoslovakia')}
+ if (!game.temp['Hungary']) {gen_action('hungary')}
+ if (!game.temp['Romania']) {gen_action('romania')}
+ if (!game.temp['Bulgaria']) {gen_action('bulgaria')}
+ }
+ },
+ east_germany() {
+ score_country('East_Germany')
+ game.temp['East_Germany'] = true
+ },
+ poland() {
+ score_country('Poland')
+ game.temp['Poland'] = true
+ },
+ czechoslovakia() {
+ score_country('Czechoslovakia')
+ game.temp['Czechoslovakia'] = true
+ },
+ hungary() {
+ score_country('Hungary')
+ game.temp['Hungary'] = true
+ },
+ romania() {
+ score_country('Romania')
+ game.temp['Romania'] = true
+ },
+ bulgaria() {
+ score_country('Bulgaria')
+ game.temp['Bulgaria'] = true
+ },
+ end() {
+ delete game.temp
+ if (game.vp > 0) {
+ goto_game_over(DEM, `${DEM} wins on Victory Point Track!`)
+ } else if (game.vp < 0) {
+ goto_game_over(COM, `${COM} wins on Victory Point Track!`)
+ } else if (game.vp === 0) {
+ goto_game_over('', `The game is tied!`) /*Not sure what to pass for result */
+ }
+ }
+}
+
+states.game_over = {
+ get inactive() {
+ return game.victory
+ },
+ prompt() {
+ view.prompt = game.victory
+ },
+}
+
+// ========================== EVENT SPECIFIC STATES =================================
+
+states.general_strike = {
+ inactive: 'discard a card.',
+ prompt() {
+ if (game.played_card === 0 ) {
+ view.prompt = 'General Strike: you must discard a card or play a Scoring Card.'
+ game.communist_hand
+ for (let card of game.communist_hand) {
+ gen_action_card(card)
+ }
+ } else if (game.played_card > 0 ) {
+ view.prompt = 'General Strike: roll a die.'
+ gen_action('roll')
+ }
+ },
+ card (card) {
+ push_undo()
+ game.played_card = card
+ let find_card
+ find_card = game.communist_hand.indexOf(card)
+ game.communist_hand.splice(find_card, 1)
+ game.available_ops = get_card_ops(card)
+ if (scoring_cards.includes(card)) {
+ game.vm_event = card
+ log(`Played C${card} for the event`)
+ game.return_state = 'general_strike'
+ goto_vm(game.vm_event)
+ } else {
+ log(`Discarded C${card}`)
+ }
+ },
+ roll() {
+ clear_undo()
+ let roll = roll_d6()
+ log(`Roll: D${roll}`)
+ logi(`+${game.available_ops} ops`)
+ let total = roll + game.available_ops
+ log(`Modified roll: ${total}`)
+
+ if (total > 5) {
+ log('The strike is over.')
+ permanently_remove(C_GENERAL_STRIKE)
+ game.persistent_events = game.persistent_events.filter(n => n !== 5)
+ } else {
+ log('The strike continues. Required 6 or more')
+ }
+ game.state = 'end_round'
+ },
+}
+
+states.honecker ={
+ inactive: 'resolve Honecker.',
+ prompt() {
+ view.prompt = 'Honecker: you may take an extra action round.'
+ gen_action('extra')
+ gen_action('pass')
+ },
+ extra() {
+ push_undo()
+ game.round++
+ log(`Communist chooses to take an extra Action Round due to C${C_HONECKER}`)
+ log_h2(`Action Round ${game.round}`)
+ game.round_player = COM
+ permanently_remove(C_HONECKER)
+ if (game.persistent_events.includes(C_GENERAL_STRIKE)) {
+ game.state = 'general_strike'
+ } else {
+ game.state = 'choose_card'
+ }
+ },
+ pass() {
+ push_undo()
+ log(`C${C_HONECKER}: passed`)
+ permanently_remove(C_HONECKER)
+ game.state = 'end_round'
+ }
+}
+
+states.new_years_eve_party = {
+ get inactive() {
+ return `resolve ${clean_name(cards[104].name)}.`
+ },
+ prompt() {
+ if (!game.is_pwr_struggle) {
+ view.prompt = `New Year's Eve Party: you may choose a country to have a final power struggle.`
+ if (!game.revolutions[0]) {gen_action('poland')}
+ if (!game.revolutions[1]) {gen_action('hungary')}
+ if (!game.revolutions[2]) {gen_action('east_germany')}
+ if (!game.revolutions[3]) {gen_action('bulgaria')}
+ if (!game.revolutions[4]) {gen_action('czechoslovakia')}
+ if (!game.revolutions[5]) {gen_action('romania')}
+ gen_action('pass')
+ } else {
+ view.prompt = `New Year's Eve Party: done.`
+ gen_action('end')
+ }
+ },
+ east_germany() {
+ push_undo()
+ log('Chose to score East Germany')
+ game.vm_event = 42
+ goto_vm(42)
+ },
+ poland() {
+ push_undo()
+ log('Chose to score Poland')
+ game.vm_event = 22
+ goto_vm(22)
+ },
+ czechoslovakia() {
+ push_undo()
+ log('Chose to score Czechoslovakia')
+ game.vm_event = 55
+ goto_vm(55)
+ },
+ hungary() {
+ push_undo()
+ log('Chose to score Hungary')
+ game.vm_event = 23
+ goto_vm(23)
+ },
+ romania() {
+ push_undo()
+ log('Chose to score Romania')
+ game.vm_event = 95
+ goto_vm(95)
+ },
+ bulgaria () {
+ push_undo()
+ log('Chose to score Bulgaria')
+ game.vm_event = 43
+ goto_vm(43)
+ },
+ pass() {
+ push_undo()
+ log('No final power struggle')
+ if (game.vp > 0) {
+ goto_game_over(DEM, `New Year's Eve Party: ${DEM} wins on Victory Point Track!`)
+ } else if (game.vp < 0) {
+ goto_game_over(COM, `New Year's Eve Party: ${COM} wins on Victory Point Track!`)
+ } else if (game.vp === 0) {
+ goto_game_over('', `New Year's Eve Party: The game is tied!`) /*Not sure what to pass for result */
+ }
+ },
+ end() {
+ if (game.vp > 0) {
+ goto_game_over(DEM, `New Year's Eve Party: ${DEM} wins on Victory Point Track!`)
+ } else if (game.vp < 0) {
+ goto_game_over(COM, `New Year's Eve Party: ${COM} wins on Victory Point Track!`)
+ } else if (game.vp === 0) {
+ goto_game_over('', `New Year's Eve Party: The game is tied!`) /*Not sure what to pass for result */
+ }
+ }
+}
+
+states.stasi_end_round = {
+ inactive: 'choose next card due to Stasi.',
+ prompt() {
+ if (game.democrat_hand.length === 0) {
+ view.prompt = 'Stasi: no cards remaining.'
+ gen_action('pass')
+ return
+ }
+ view.prompt = 'Stasi: you must select your next card to play.'
+
+ for (let card of game.democrat_hand) {
+ gen_action_card(card)
+ }
+ },
+ card(card) {
+ push_undo()
+ log_gap(`Democrat selected C${card} as next card.`)
+ game.stasi_card = card
+ if (!scoring_cards.includes(card) && count_scoring_cards() >= (7-game.round)){
+ game.temp = card
+ game.state = 'stasi_confirm_scoring_card'
+ return
+ }
+ game.state = 'stasi_finish'
+ },
+ pass() {
+ log('Stasi: Democrat has no remaining cards')
+ game.stasi_card = 0
+ end_stasi_choose_card()
+ },
+}
+
+states.stasi_confirm_scoring_card = {
+ inactive: 'choose a card.',
+ prompt() {
+ view.prompt = `${pluralize(count_scoring_cards(),'scoring card')} in hand with ${pluralize(7-game.round,'Action Round')} remaining. Scoring cards may not be held. Continue?`
+ gen_action('continue')
+ },
+ continue() {
+ push_undo()
+ end_stasi_choose_card()
+ }
+}
+
+states.stasi_finish = {
+ inactive: 'choose next card due to Stasi.',
+ prompt() {
+ view.prompt = 'Stasi. Choose card: done.'
+ gen_action('done')
+ },
+ done() {
+ push_undo()
+ end_stasi_choose_card()
+ }
+}
+
+states.stasi_confirm = {
+ inactive: 'choose next card due to Stasi.',
+ prompt() {
+ view.prompt = `If Common European Home selected, it must be played for Operations. Otherwise select the opponent's card instead.`
+ gen_action('done')
+ },
+ done() {
+ game.playable_cards = game.playable_cards.filter( n => n !== C_COMMON_EUROPEAN_HOME)
+ end_stasi_choose_card()
+ }
+}
+
+states.stasi_play_card = {
+ inactive: 'play a card.',
+ prompt () {
+ if (game.democrat_hand.length === 0) {
+ view.prompt = 'Stasi: you must pass.'
+ gen_action('pass')
+ } else {
+ view.prompt = `Stasi: you must play ${clean_name(cards[game.stasi_card].name)}.`
+ gen_action_card(game.stasi_card)
+ }
+ },
+ card(card) {
+ push_undo()
+ game.played_card = card
+ let find_card
+ find_card = game.democrat_hand.indexOf(card);
+ game.democrat_hand.splice(find_card, 1);
+ game.available_ops = get_card_ops(card)
+
+ if (game.democrat_hand.includes(C_COMMON_EUROPEAN_HOME) && cards[card].side === "C") {
+ game.state = 'stasi_resolve_common_european_home'
+ } else {
+ game.state = 'play_card'
+ }
+ },
+ pass () {
+ log('No cards remaining. Passed')
+ //end_round()
+ game.state = 'end_round'
+ },
+ done () {
+ if (game.democrat_hand.includes(C_COMMON_EUROPEAN_HOME)) {
+ game.state = 'stasi_resolve_common_european_home'
+ } else {
+ game.state = 'play_card'
+ }
+ }
+}
+
+states.stasi_resolve_common_european_home = {
+ inactive: 'play a card.',
+ prompt () {
+ view.prompt = `Stasi: play ${clean_name(cards[game.played_card].name)} with Common European Home?`
+ gen_action('yes')
+ gen_action('no')
+ },
+ yes() {
+ log(`Played C${game.played_card} with Common European Home`)
+ silent_discard(C_COMMON_EUROPEAN_HOME)
+ game.vm_infl_to_do = true
+ game.vm_event_to_do = false
+ game.state = 'resolve_opponent_event'
+ },
+ no() {
+ game.state = 'play_card'
+ }
+}
+
+
+// ==================== SUPPORTING STATE FUNCTIONS =============================
+
+
+function add_infl(space, ops) {
+ push_undo()
+ log_summary(`Added £ SP in %${space}`)
+
+ //If AHBR - check AHBR conditions
+ if (game.persistent_events.includes(58)) {
+ if (spaces[space].country !== 'East_Germany'){
+ game.austria_hungary_border_reopened_tracker = false
+ }
+ }
+
+ // Check Genscher
+ if (game.persistent_events.includes(C_GENSCHER) && game.active === DEM && spaces[space].country === 'East_Germany' && check_com_control(space)) {
+ game[ops]--
+ log_summary(`(-1 op due to C${C_GENSCHER})`)
+ } else if (check_opp_control(space)) {
+ game[ops] -= 2
+ //Check if Austria Hungary Border Reopened was used to place last SP in a controlled space in East Germany. If so, game.available_op will be negative
+ if (game[ops] < 0) {
+ log_summary(`(Used +1 op from C${C_AUSTRIA_HUNGARY_BORDER_REOPENED})`)
+ }
+ } else {
+ game[ops]--
+ }
+
+ // Update influence values
+ if (game.active === COM) {
+ game.comInfl[space]++
+ } else {
+ game.demInfl[space]++
+ }
+ check_tyrant()
+
+ // Check Austria Hungary Border Reopened is true and condition has been met
+ if (game[ops] === 0 && game.active === DEM && game.persistent_events.includes(C_AUSTRIA_HUNGARY_BORDER_REOPENED) && game.austria_hungary_border_reopened_tracker) {
+ game[ops] ++
+ log('+1 op from C58')
+ game.austria_hungary_border_reopened_tracker = false
+ game.valid_spaces = game.valid_spaces.filter(n => spaces[n].country === 'East_Germany')
+ }
+
+ // If only 1 IP remaining, may not place in opponent controlled spaces
+
+ // Check for Genscher & Austria Hungary Border Reopened
+
+ if (game[ops] === 1) {
+ if (game.active === DEM) {
+ if (game.persistent_events.includes(63) || (game.persistent_events.includes(58) && game.austria_hungary_border_reopened_tracker)) {
+ game.valid_spaces = game.valid_spaces.filter(n => !(check_opp_control(n) && spaces[n].country !== 'East_Germany'))
+ } else {
+ game.valid_spaces = game.valid_spaces.filter(n => !check_opp_control(n))
+ }
+ } else {
+ game.valid_spaces = game.valid_spaces.filter(n => !check_opp_control(n))
+ }
+ }
+
+ //Clear valid spaces if no IP remaining.
+ if (game[ops] <= 0 ) {
+ game.valid_spaces = []
+ }
+}
+
+function remove_infl(space, ops) {
+ push_undo()
+ log_summary(`Removed £ SP from %${space}`)
+
+ if (game.remove_opponent_infl === true) {
+ if (game.active === COM) {
+ game.demInfl[space]--
+ if (game.demInfl[space] === 0) {
+ game.valid_spaces = game.valid_spaces.filter(id => id !== space);
+ }
+ } else {
+ game.comInfl[space]--
+ if (game.comInfl[space] === 0) {
+ game.valid_spaces = game.valid_spaces.filter(id => id !== space);
+ }
+ }
+ check_tyrant()
+
+ } else {
+ if (game.active === COM) {
+ game.comInfl[space]--
+ if (game.comInfl[space] === 0) {
+ game.valid_spaces = game.valid_spaces.filter(id => id !== space);
+ }
+ } else {
+ game.demInfl[space]--
+ if (game.demInfl[space] === 0) {
+ game.valid_spaces = game.valid_spaces.filter(id => id !== space);
+ }
+ }
+ check_tyrant()
+ }
+ game[ops]--
+ if (game.vm_influence_added && game.vm_influence_added[space] >= 0) {game.vm_influence_added[space]++}
+ if (game[ops]===0) {game.valid_spaces = []}
+}
+
+function do_sc(space) {
+ clear_undo()
+ let tear_gas_start = game.persistent_events.includes(C_TEAR_GAS)
+ let the_wall_start = game.persistent_events.includes(C_THE_WALL)
+ log_gap(`Support check: %${space}`)
+ let roll = roll_d6()
+
+ // Check for The Wall
+ if (game.active === COM && game.persistent_events.includes(C_THE_WALL) && spaces[space].country === 'East_Germany') {
+ logi(`No adjacency for Democrats due to C${C_THE_WALL}`)
+ log_gap(`Roll: D${roll}`)
+ }
+ // Continue with Support Check Logic
+ else { log(`Roll: D${roll}`) }
+
+ // Check for the Crowd Turns Against Ceausescu
+
+ if (game.is_pwr_struggle) {
+ roll += game.vm_available_ops
+ logi(`+${game.vm_available_ops} from Ceausescu`)
+ }
+
+ // Check if in Tiananmen Square Track Award
+
+ else if (game.state === 'vm_tst_6_sc') {
+ roll += get_tst_6_ops()
+ roll += 2
+ logi('+2 TST award')
+ }
+ else {
+ let card_ops = get_card_ops(this_card())
+ roll += card_ops
+ logi(`+${card_ops} from card ops`)
+ }
+
+ if (game.support_check_modifier > 0) {
+ roll += game.support_check_modifier
+ logi(`+${game.support_check_modifier} from event`)
+ }
+
+ // Events which modify SC rolls
+ if (game.active === COM && game.persistent_events.includes(C_TEAR_GAS) && spaces[space].socio === 6) {
+ roll ++
+ logi(`+1 from C${C_TEAR_GAS}`)
+ permanently_remove(C_TEAR_GAS)
+ game.persistent_events = game.persistent_events.filter(n => n !== C_TEAR_GAS)
+ }
+ if (game.active === DEM && spaces[space].region === 'Eastern Europe' && game.persistent_events.includes(C_FRG_EMBASSIES)) {
+ roll++
+ logi(`+1 from C${C_FRG_EMBASSIES}`)
+ }
+ if (game.active === DEM && spaces[space].country === 'East_Germany' && game.persistent_events.includes(C_GRENZTRUPPEN)) {
+ roll--
+ logi(`-1 from C${C_GRENZTRUPPEN}`)
+ }
+ if ((game.active === COM && game.stand_fast === DEM && check_dem_control(space)) || (game.active === DEM && game.stand_fast === COM && check_com_control(space))){
+ roll--
+ logi(`-1 from C${C_STAND_FAST}`)
+ }
+ if (game.active === DEM && game.persistent_events.includes(C_ELENA) && spaces[space].country === 'Romania') {
+ roll--
+ logi(`-1 from C${C_ELENA}`)
+ }
+ if (game.active === DEM && game.persistent_events.includes(C_AUSTRIA_HUNGARY_BORDER_REOPENED) && game.austria_hungary_border_reopened_tracker) {
+ roll++
+ logi(`+1 from C${C_AUSTRIA_HUNGARY_BORDER_REOPENED}`)
+ }
+
+ // Continue with logic - check for adjacency
+
+ // Events which affect adjacency - The Wall
+
+ const adj = count_adj(space)
+ if (game.active === COM && game.persistent_events.includes(C_THE_WALL) && spaces[space].country === 'East_Germany') {
+ roll += adj.com_adj
+ if (adj.com_adj > 0) {
+ logi(`+${adj.com_adj} adjacency`)
+ }
+ permanently_remove(C_THE_WALL)
+
+ // Standard adjacency
+ } else {
+ if (adj.dem_adj > 0 || adj.com_adj > 0 ){
+ if (game.active === DEM) {
+ roll += adj.dem_adj
+ roll -= adj.com_adj
+ if (adj.dem_adj > 0) {
+ logi(`+${adj.dem_adj} from adjacency`)
+ }
+ if (adj.com_adj > 0) {
+ logi(`-${adj.com_adj} from opponent adjacency`)
+ }
+ } else {
+ roll += adj.com_adj
+ roll -= adj.dem_adj
+ if (adj.com_adj > 0) {
+ logi(`+${adj.com_adj} from adjacency`)
+ }
+ if (adj.dem_adj > 0) {
+ logi(`-${adj.dem_adj} from opponent adjacency`)
+ }
+ }
+ }
+ }
+
+ // Support check calcs
+ log(`Modified roll: ${roll}`)
+ const stability = spaces[space].stability
+ logi(`-${stability*2} (stability * 2)`)
+ const change_infl = Math.max(0, roll - stability*2)
+ if (change_infl > 0) {
+ log_msg_gap(`Change influence: ${change_infl} SP`)
+ if(game.active === DEM) {
+ if (change_infl > game.comInfl[space]) {
+ const residual = change_infl - game.comInfl[space]
+ game.comInfl[space] = 0
+ game.demInfl[space] += residual
+ } else {
+ game.comInfl[space] -= change_infl
+ }
+ if (game.comInfl[space] === 0) {
+ game.valid_spaces = game.valid_spaces.filter(id => id !== space)
+ }
+ } else {
+ if (change_infl > game.demInfl[space]) {
+ const residual = change_infl - game.demInfl[space]
+ game.demInfl[space] = 0
+ game.comInfl[space] += residual
+ } else {
+ game.demInfl[space] -= change_infl
+ }
+ if (game.demInfl[space] === 0) {
+ game.valid_spaces = game.valid_spaces.filter(id => id !== space)
+ }
+ }
+ check_tyrant()
+
+ } else {
+ log_msg_gap('Change influence: 0 SP')
+ }
+ //Check VP awards
+ if (game.active === COM && game.persistent_events.includes(C_HELSINKI_FINAL_ACT) && (spaces[space].socio === 5 || spaces[space].socio === 6) ) {
+ log('+1 VP from C26')
+ game.vp ++
+ }
+ if (game.active === COM && game.persistent_events.includes(C_ECO_GLASNOST) && spaces[space].space_id === S_RUSE) {
+ log('+1 VP from C39')
+ game.vp++
+ }
+
+ //Check if Tear Gas or The Wall used
+ let tear_gas_end = game.persistent_events.includes(C_TEAR_GAS)
+ let the_wall_end = game.persistent_events.includes(C_THE_WALL)
+ if (tear_gas_start && !tear_gas_end) {
+ log(`C${C_TEAR_GAS} no longer in effect`)
+ }
+ if (the_wall_start && !the_wall_end) {
+ log(`C${C_THE_WALL} no longer in effect`)
+ }
+
+
+ // If Austria-Hungary Border Reopened used, all future support checks must be in East Germany
+ if (game.persistent_events.includes(C_AUSTRIA_HUNGARY_BORDER_REOPENED)){
+ if (game.austria_hungary_border_reopened_tracker) {
+ game.valid_spaces = game.valid_spaces.filter(n => spaces[n].country === 'East_Germany')
+ }
+ }
+ delete game.selected_space
+}
+
+function valid_spaces_setup() {
+ for (let i =0 ; i < spaces.length ; i++) {
+ let space = spaces[i]
+
+ if (game.active === COM) {
+ let infl = game.demInfl[i]
+
+ if (infl === 0) {
+ game.valid_spaces.push(space.space_id);
+ }
+ } else {
+ let infl = game.comInfl[i]
+ if (infl === 0) {
+ game.valid_spaces.push(space.space_id);
+ }
+ }
+ }
+}
+
+function valid_spaces_sc() {
+ let valid_spaces_set = new Set();
+
+ for (let i = 0 ; i < spaces.length; i++) {
+ let space = spaces[i]
+
+ if (game.active === DEM) {
+ let infl = game.comInfl[i]
+ if (infl !== 0 ) {
+ valid_spaces_set.add(space.space_id);
+ }
+ } else {
+ let infl = game.demInfl[i]
+ if (infl !== 0 ) {
+ // Check Events that block support checks in a given space
+ if (game.persistent_events.includes(C_SOLIDARITY_LEGALIZED) && space.space_id === S_GDANSK) {continue}
+ if (game.persistent_events.includes(C_WE_ARE_THE_PEOPLE) && space.space_id === S_LEIPZIG) {continue}
+ if (game.persistent_events.includes(C_FOREIGN_CURRENCY_DEBT_BURDEN) && space.country === game.foreign_currency_debt_burden) {continue}
+
+ valid_spaces_set.add(space.space_id);
+ }
+ }
+ }
+ game.valid_spaces = Array.from(valid_spaces_set);
+
+ //Check for the Crown Turns Against Ceausescu
+ if (game.is_pwr_struggle && game.pwr_struggle_in === 'Romania' && game.persistent_events.includes(C_THE_CROWD_TURNS_AGAINST_CEAUSESCU)) {
+ game.valid_spaces = game.valid_spaces.filter(n => spaces[n].country === 'Romania')
+ }
+ return game.valid_spaces;
+}
+
+function valid_spaces_support_loss() {
+ let valid_spaces_set = new Set();
+ for (let i = 0; i < game.demInfl.length; i++) {
+ let space = spaces[i]
+ if (game.active === DEM) {
+ let infl = game.demInfl[i]
+ if (infl > 0 && space.country === game.pwr_struggle_in) {
+ valid_spaces_set.add(space.space_id);
+ }
+ } else {
+ let infl = game.comInfl[i]
+ if (infl > 0 && space.country === game.pwr_struggle_in) {
+ valid_spaces_set.add(space.space_id);
+ }
+ }
+ }
+ game.valid_spaces = Array.from(valid_spaces_set);
+ return game.valid_spaces;
+}
+
+function valid_spaces_infl() {
+ // Check if function is called from the VM or not, take relevant ops variable
+ let ops = game.state.startsWith('vm') ? game.vm_available_ops : game.available_ops;
+
+ let valid_spaces_set = new Set();
+ for (let i = 0; i < game.demInfl.length; i++) {
+ let space = spaces[i]
+ let player_influence = game.active === COM ? game.comInfl[i] : game.demInfl[i];
+
+ // If the piece has the player's influence, add it and its adjacent spaces to the set
+ if (player_influence > 0) {
+ valid_spaces_set.add(space.space_id);
+ let adjacent_spaces = get_adjusted_adjacency(space.space_id)
+
+ for (let adj_space_id of adjacent_spaces) {
+ if (adj_space_id >= 0) {
+ const adj_piece = spaces[adj_space_id];
+
+ // Check if the adjacent space is controlled by the opponent
+ const opponent_control = check_opp_control(adj_piece.space_id)
+
+ //Check for Genscher. Can always place in East Germany even with 1 op
+ if (game.active === DEM && adj_piece.country === 'East_Germany' && game.persistent_events.includes(C_GENSCHER)){
+ valid_spaces_set.add(adj_piece.space_id)
+ }
+
+
+ // Otherwise, only add the adjacent space if the available_ops >= 2 or the space is not controlled by the opponent
+ if (ops >= 2 || !opponent_control) {
+ valid_spaces_set.add(adj_piece.space_id)
+ }
+ }
+ }
+ }
+ }
+ game.valid_spaces = Array.from(valid_spaces_set);
+ return game.valid_spaces;
+}
+
+function valid_cards(player_hand, presence) {
+ const valid_cards_set = new Set()
+ if (game.phase === 0) {
+
+ for (let c of player_hand) {
+ let card = power_cards[c]
+ // Never add tactics fails
+ if (c === PC_TACTIC_FAILS) {
+ continue
+ }
+ // Cannot play the suit of Tactics Fails
+ if (card.name === game.tactics_fails) {
+ continue
+ }
+
+
+ if (card.socio === 0) {
+ valid_cards_set.add(c)
+ } else if (leaders.includes(card.socio) && presence[card.socio]) {
+ valid_cards_set.add(c)
+ }
+ }
+ } else if (game.phase === 1) {
+ for (let c of player_hand) {
+ let card = power_cards[c]
+ if (!leader_cards.includes(c) && card.name === power_cards[game.played_power_card].name) {
+ valid_cards_set.add(c)
+ } else if (card.name === game.proxy_power_card) {
+ valid_cards_set.add(c)
+ } else if (leaders.includes(card.socio) && presence[card.socio]) {
+ valid_cards_set.add(c)
+ } else if (c === PC_TACTIC_FAILS) {
+ valid_cards_set.add(c)
+ }
+ }
+ }
+ game.valid_cards = Array.from(valid_cards_set)
+ return game.valid_cards
+}
+
+function do_valid_cards() {
+ let presence = check_presence(game.pwr_struggle_in)
+ if (game.active === DEM) {
+ valid_cards(game.dem_pwr_hand, presence.dem_leaders)
+ } else {
+ valid_cards(game.com_pwr_hand, presence.com_leaders)}
+}
+
+function count_adj(space_id) {
+ let dem_adj = 0
+ let com_adj = 0
+
+ let adjacent_spaces = get_adjusted_adjacency(space_id)
+ for (let adj_space_id of adjacent_spaces) {
+ if (check_dem_control(adj_space_id)) {
+ dem_adj++
+ }
+ if (check_com_control(adj_space_id)) {
+ com_adj++
+ }
+ }
+ return {dem_adj, com_adj}
+}
+
+function check_control(space_id) {
+ if ( (game.comInfl[space_id] - game.demInfl[space_id]) >= spaces[space_id].stability) {
+ return true;
+ } else if ((game.demInfl[space_id] - game.comInfl[space_id]) >= spaces[space_id].stability) {
+ return true;
+ } else {
+ return false;
+ }
+}
+
+function check_opp_control(space_id) {
+ if (game.active === DEM && ((game.comInfl[space_id] - game.demInfl[space_id]) >= spaces[space_id].stability)) {
+ return true;
+ } else if (game.active === COM && ((game.demInfl[space_id] - game.comInfl[space_id]) >= spaces[space_id].stability)) {
+ return true;
+ } else {
+ return false;
+ }
+}
+
+function check_dem_control(space_id) {
+ if ((game.demInfl[space_id] - game.comInfl[space_id]) >= spaces[space_id].stability) {
+ return true;
+ } else {
+ return false;
+ }
+}
+
+function check_com_control(space_id) {
+ if ((game.comInfl[space_id] - game.demInfl[space_id]) >= spaces[space_id].stability) {
+ return true;
+ } else {
+ return false;
+ }
+}
+
+function do_tst_attempt() {
+ let roll = roll_d6();
+ log(`Roll: D${roll}`);
+
+ roll += game.available_ops
+ logi(`+${game.available_ops} from card ops`)
+
+ // TIANANMEN SQUARE MODIFIERS
+
+ if (game.active === DEM && game.dem_tst_attempted === 1 || game.active === COM && game.com_tst_attempted === 1) {
+ roll ++;
+ logi('+1 from previous TST attempts')
+ }
+ if (game.active === DEM && game.dem_tst_position >= 1 && game.com_tst_position === 0) {
+ roll ++
+ logi('+1 from TST award')
+ }
+ if (game.active === COM && game.com_tst_position >= 1 && game.dem_tst_position === 0) {
+ roll ++
+ logi('+1 from TST award')
+ }
+ if ((game.active === DEM && cards[game.played_card].side === 'D') || (game.active === COM && cards[game.played_card].side === 'C')) {
+ roll ++;
+ logi('+1 for playing own card');
+ }
+ if (game.active === COM && game.persistent_events.includes(53)) {
+ roll ++
+ logi('+1 from C53')
+ }
+ log(`Modified roll: ${roll}`)
+
+ // TIANANMEN SQUARE ATTEMPT
+ game.return = game.active
+ game.return_state = 'tiananmen_square_attempt_done'
+ if (game.active === DEM) {
+ game.dem_tst_attempted_this_turn = 1
+ if (roll >= dem_tst_req[game.dem_tst_position]) {
+ log(`${dem_tst_req[game.dem_tst_position]} required: success`)
+ game.dem_tst_position++
+ game.dem_tst_attempted = 0
+
+ //Check if they have reached box 7 or 8 first
+ if (game.dem_tst_position === 7 && game.com_tst_position < 7) {
+ game.tst_7 = false
+ }
+ if (game.dem_tst_position === 8 && game.com_tst_position < 8) {
+ game.tst_8 = false
+ }
+
+ //Check if they have caught up to box 7 or 8
+ if (game.dem_tst_position >= 7 && game.com_tst_position >= 7) {
+ delete game.tst_7
+ }
+ if (game.dem_tst_position >= 8 && game.com_tst_position >= 8) {
+ delete game.tst_8
+ }
+
+ //Check if TST events occur
+ if (game.dem_tst_position === 3 && game.com_tst_position < 3) {game.vm_event = 203}
+ else if (game.dem_tst_position === 4 && game.com_tst_position < 4) {game.vm_event = 204}
+ game.state = 'tiananmen_square_attempt_success'
+ } else {
+ log(`${dem_tst_req[game.dem_tst_position]} required: fail`)
+ game.dem_tst_attempted = 1
+ game.state = 'tiananmen_square_attempt_fail'
+ }
+ } else {
+ game.com_tst_attempted_this_turn = 1
+ if (roll >= com_tst_req[game.com_tst_position]) {
+ log(`${com_tst_req[game.com_tst_position]} required: success`)
+ game.com_tst_position++
+ game.com_tst_attempted = 0
+
+ //Check if they have reached box 7 or 8 first
+ if (game.com_tst_position === 7 && game.dem_tst_position < 7) {
+ game.tst_7 = false
+ }
+ if (game.com_tst_position === 8 && game.dem_tst_position < 8) {
+ game.tst_8 = false
+ }
+
+ //Check if they have caught up to box 7 or 8
+ if (game.com_tst_position >= 7 && game.dem_tst_position >= 7) {
+ delete game.tst_7
+ }
+ if (game.com_tst_position >= 8 && game.dem_tst_position >= 8) {
+ delete game.tst_8
+ }
+
+ //Check if TST events occur
+ if (game.com_tst_position === 3 && game.dem_tst_position < 3) {game.vm_event = 203}
+ else if (game.com_tst_position === 4 && game.dem_tst_position < 4) {game.vm_event = 204}
+ game.state = 'tiananmen_square_attempt_success'
+ } else {
+ log(`${com_tst_req[game.com_tst_position]} required: fail`)
+ game.com_tst_attempted = 1
+ game.state = 'tiananmen_square_attempt_fail'
+ }
+ }
+}
+
+function check_presence(country) {
+
+ let dem_spaces = 0;
+ let com_spaces = 0;
+ let dem_battlegrounds = 0;
+ let com_battlegrounds = 0;
+ let dem_leaders = {1: false, 4: false, 5: false, 6: false, 7: false};
+ let com_leaders = {1: false, 4: false, 5: false, 6: false, 7: false};
+
+
+ for (let i = 0; i < spaces.length; i++) {
+ let space = spaces[i]
+ if (space.country === country) {
+
+ if (check_dem_control(i)) {
+ dem_spaces++;
+ if (space.battleground === 1) {
+ dem_battlegrounds++;
+ }
+ if (leaders.includes(space.socio)) {
+ dem_leaders[space.socio] = true;
+ }
+ }
+ if (check_com_control(i)) {
+ com_spaces++;
+ if (space.battleground === 1) {
+ com_battlegrounds++;
+ }
+ if (leaders.includes(space.socio)) {
+ com_leaders[space.socio] = true;
+ }
+ }
+ }
+ }
+
+ // Determine domination
+ let dem_domination = dem_battlegrounds > com_battlegrounds && dem_spaces > com_spaces && dem_spaces - dem_battlegrounds > 0;
+ let com_domination = com_battlegrounds > dem_battlegrounds && com_spaces > dem_spaces && com_spaces - com_battlegrounds > 0;
+
+ // Determine control
+ let total_battlegrounds = battlegrounds(country);
+ let dem_control = dem_battlegrounds === total_battlegrounds && dem_spaces > com_spaces;
+ let com_control = com_battlegrounds === total_battlegrounds && com_spaces > dem_spaces;
+
+ return {
+ dem_spaces: dem_spaces,
+ com_spaces: com_spaces,
+ dem_battlegrounds: dem_battlegrounds,
+ com_battlegrounds: com_battlegrounds,
+ dem_domination: dem_domination,
+ com_domination: com_domination,
+ dem_control: dem_control,
+ com_control: com_control,
+ dem_leaders: dem_leaders,
+ com_leaders: com_leaders
+ };
+}
+
+function battlegrounds(country) {
+ let battlegrounds = 0;
+ if (country === "Hungary") {
+ battlegrounds = 4
+ } else if (country === "Bulgaria") {
+ battlegrounds = 5
+ } else {
+ battlegrounds = 6
+ }
+ return battlegrounds;
+}
+
+function take_power(country) {
+ log(`Democrat takes power in ${game.pwr_struggle_in}`)
+ game.revolutions[find_country_index(country)] = true
+ game.times_held[find_country_index(country)] = 1
+}
+
+function retain_power(country){
+ game.times_held[find_country_index(country)]++
+ let vp_gain = get_value(country)*game.times_held[find_country_index(country)]
+ log(`Chooses to retain power`)
+ log(`-${vp_gain} VP`)
+ game.vp -= vp_gain
+}
+
+function score_country(country) {
+ log_h3(`Scoring: ${country}`)
+
+//Get scoring values
+ let value_presence = get_value(country)
+ let value_domination = value_presence*2
+ let value_control
+ if (country !== "Hungary") {
+ value_control = value_presence*3
+ } else {
+ value_control = 4
+ }
+
+ let dem_vp = 0
+ let com_vp = 0
+ //Check for presence
+ let presence = check_presence(country)
+
+ //If one side has domination or control
+ if (presence.dem_control || presence.dem_domination) {
+ log(`Democrat:`)
+ if (presence.dem_control) {
+ logi(`Control: +${value_control} VP`)
+ dem_vp += value_control
+ }
+ else {
+ logi(`Domination: +${value_domination} VP`)
+ dem_vp += value_domination
+ }
+ logi(`Battlegrounds: +${presence.dem_battlegrounds} VP`)
+ dem_vp += presence.dem_battlegrounds
+ log(`Total: +${dem_vp} VP`)
+
+ log_gap('Communist:')
+ if (presence.com_spaces > 0) {
+ logi(`Presence: -${value_presence} VP`)
+ com_vp -= value_presence
+ if (presence.com_battlegrounds >0) {
+ logi(`Battlegrounds: -${presence.com_battlegrounds} VP`)
+ com_vp -= presence.com_battlegrounds
+ }
+ log(`Total: ${com_vp} VP`)
+ } else {
+ log('No presence: 0 VP')
+ }
+ }
+ else if (presence.com_control || presence.com_domination) {
+ log('Communist:')
+ if (presence.com_control) {
+ logi(`Control: -${value_control} VP`)
+ com_vp -= value_control
+ }
+ else {
+ logi(`Domination: -${value_domination} VP`)
+ com_vp -= value_domination
+ }
+ logi(`Battlegrounds: -${presence.com_battlegrounds} VP`)
+ com_vp -= presence.com_battlegrounds
+ log(`Total: ${com_vp} VP`)
+
+ log_gap('Democrat:')
+ if (presence.dem_spaces > 0) {
+ logi(`Presence: +${value_presence} VP`)
+ dem_vp += value_presence
+ if (presence.dem_battlegrounds > 0) {
+ logi(`Battlegrounds: +${presence.dem_battlegrounds} VP`)
+ dem_vp += presence.dem_battlegrounds
+ }
+ log (`Total: +${dem_vp} VP`)
+ } else {
+ log('No presence: 0 VP')
+ }
+ }
+
+ //Otherwise, presence and battlegrounds
+ else {
+ log("No domination or control")
+ log_gap(`Communist:`)
+ if (presence.com_spaces > 0) {
+ logi(`Presence: -${value_presence} VP`)
+ com_vp -= value_presence
+ if (presence.com_battlegrounds > 0) {
+ logi(`Battlegrounds: -${presence.com_battlegrounds} VP`)
+ com_vp -= presence.com_battlegrounds
+ } else {
+ logi('No battlegrounds')
+ }
+ logi(`Total: ${com_vp} VP`)
+ } else {
+ logi('No presence: 0 VP')
+ }
+ log_gap('Democrat:')
+ if (presence.dem_spaces > 0) {
+ logi(`Presence: +${value_presence} VP`)
+ dem_vp += value_presence
+ if (presence.dem_battlegrounds > 0) {
+ logi(`Battlegrounds: +${presence.dem_battlegrounds} VP`)
+ dem_vp += presence.dem_battlegrounds
+ } else {
+ logi('No battlegrounds')
+ }
+ logi(`Total: +${dem_vp} VP`)
+ } else {
+ logi('No presence: 0 VP')
+ }
+ }
+
+//Calculate change VP
+ let change_vp = dem_vp + com_vp
+ game.vp += change_vp
+ if (change_vp > 0 ) {
+ log_gap(`Scoring: +${change_vp} VP`)
+ } else {
+ log_gap(`Scoring: ${change_vp} VP`)
+ }
+}
+
+function get_value(country) {
+ let value
+ if (country === "East_Germany" || country === "Poland") {value = 3}
+ else if (country === "Czechoslovakia" || country === "Romania") {value = 2}
+ else value = 1
+ return value
+}
+
+function get_end_infl_prompt() {
+ view.prompt = `${clean_name(cards[this_card()].name)}. Add SPs: done.`
+ if (!game.vm_infl_to_do) {
+ gen_action('end_round')
+ } else {
+ gen_action('done')
+ }
+}
+
+function get_aftermath_roll() {
+ clear_undo()
+ let roll = roll_d6()
+ log(`Roll: D${roll}`)
+ let rally_win = 0
+ let petition_win = 0
+ if (rallies.includes(game.played_power_card) || game.proxy_power_card === 'Rally in the Square') { rally_win = 2}
+ if (petitions.includes(game.played_power_card) || game.proxy_power_card === 'Petition') { petition_win = 2}
+ let modified_roll = roll + game.raised_stakes + rally_win - petition_win
+
+ // Special check for Yakovlev Counsels Gobachev. Applies only if Democrat wins, so only if Com is doing support loss and if Dem is doing VP roll
+ if (game.state === 'support_loss') {
+ if (game.active === COM && game.persistent_events.includes(C_YAKOVLEV_COUNSELS_GORBACHEV)) {
+ logi(`+1 from C${C_YAKOVLEV_COUNSELS_GORBACHEV}`)
+ modified_roll ++
+ }
+ } else {
+ if (game.active === DEM && game.persistent_events.includes(C_YAKOVLEV_COUNSELS_GORBACHEV)) {
+ logi(`+1 from C${C_YAKOVLEV_COUNSELS_GORBACHEV}`)
+ modified_roll ++
+ }
+ }
+ if (modified_roll < 0) {modified_roll = 0}
+ else if (modified_roll > 7) {modified_roll = 7}
+
+ if (game.raised_stakes !== 0) {
+ logi(`+${game.raised_stakes} from Raising the Stakes`)
+ }
+ if (rally_win !== 0) {
+ logi('+2 from winning on a P1')
+ }
+ if (petition_win !== 0) {
+ logi('-2 from winning on a P31')
+ }
+ if (modified_roll !== roll) {
+ log(`Modified roll: ${modified_roll}`)
+ }
+ return modified_roll
+}
+
+function add_to_persistent_events(card) {
+ game.persistent_events.push(card)
+ remove_from_discard(card)
+ //let silent_cards = [C_SYSTEMATIZATION, C_FOREIGN_CURRENCY_DEBT_BURDEN]
+ if (is_auto_resolve(card)) {log_gap(`C${card}:`)}
+}
+
+function permanently_remove(card) {
+ game.persistent_events = game.persistent_events.filter( c => c !== card)
+ remove_from_discard(card)
+ if (!game.strategy_removed.includes(card)) {
+ game.strategy_removed.push(card)
+ }
+}
+
+function check_vp() {
+ if (game.vp >= 20) {
+ goto_game_over(DEM, `${DEM} won an Automatic Victory!`)
+ return true
+ } else if(game.vp <= -20) {
+ goto_game_over(COM, `${COM} won an Automatic Victory!`)
+ return true
+ }
+ return false
+}
+
+function game_over() {
+ if (game.vp >= 20 || game.vp <= -20) {
+ return true
+ } else { return false}
+}
+
+function goto_game_over(result, victory) {
+ game.state = "game_over"
+ game.active = "None"
+ game.result = result
+ game.victory = victory
+ log_h1("Game Over")
+ log(game.victory)
+ return
+}
+
+function goto_struggle(){
+ game.raised_stakes_discard = 0
+ game.valid_cards = []
+ log_h2('Play Cards')
+ next_player()
+ game.state = 'power_struggle'
+ do_valid_cards()
+}
+
+function reset_austria_hungary_border_reopened() {
+ game.austria_hungary_border_reopened_tracker = false
+}
+
+function end_stasi_choose_card() {
+ if (game.stasi_card === C_COMMON_EUROPEAN_HOME) {
+ game.state = 'stasi_confirm'
+ } else {
+ game.round_player = COM
+ game.round ++
+ log_h2(`Action Round ${game.round}`)
+ next_player()
+ game.valid_spaces = []
+ if (game.persistent_events.includes(5)) {
+ log_h3('C5')
+ game.state = 'general_strike'
+ } else {
+ game.state = 'choose_card'
+ }
+ }
+}
+
+function end_goddess() {
+ game.return_state = ''
+ log_h2("Action Round " + game.round)
+ if (game.active === DEM) {
+ next_player()
+ } else {
+ log_side()
+ }
+ if (game.persistent_events.includes(5)) {
+ game.state = 'general_strike'
+ } else {
+ game.state = 'choose_card'
+ }
+}
+
+function check_reformer() { /*Is this function still used?*/
+ if (game.dem_tst_position !== game.com_tst_position) {
+ if (!game.playable_cards.includes(67)) {
+ game.playable_cards.push(67)
+ }
+ } else {
+ game.playable_cards = game.playable_cards.filter(n => n !== 67)
+ }
+}
+
+function count_scoring_cards() {
+ let scoring_check
+ if (game.active === DEM) {
+ scoring_check = game.democrat_hand.filter(card => scoring_cards.includes(card)).length
+ } else {
+ scoring_check = game.communist_hand.filter(card => scoring_cards.includes(card)).length
+ }
+ return scoring_check
+}
+
+function select_card(card){
+ game.played_card = card
+ game.temp = 0
+ let find_card
+ if (game.active === COM) {
+ find_card = game.communist_hand.indexOf(card)
+ game.communist_hand.splice(find_card, 1)
+ } else {
+ find_card = game.democrat_hand.indexOf(card)
+ game.democrat_hand.splice(find_card, 1)
+ }
+ game.available_ops = get_card_ops(card)
+
+ //Check Ligachev
+ if (game.active === DEM && game.persistent_events.includes(99) && card !== C_GORBACHEV_CHARMS_THE_WEST) {
+ log(`-3 VP from C${C_LIGACHEV}`)
+ game.vp -= 3
+ if (check_vp()) {
+ return
+ }
+ game.persistent_events = game.persistent_events.filter(n => n !== 99)
+ game.strategy_removed.push(C_LIGACHEV)
+ }
+ game.state = 'play_card'
+}
+
+function is_auto_resolve(card) {
+ let ceausecu_events = [10, 41, 69, 101, 107]
+ if (auto_resolve_events.includes(card)) {
+ return true
+ }
+ else if (card === C_THE_TYRANT_IS_GONE) {
+ if (game.persistent_events.includes(C_THE_CROWD_TURNS_AGAINST_CEAUSESCU)) {
+ return true
+ }
+ }
+ else if (ceausecu_events.includes(card) && game.persistent_events.includes(THE_TYRANT_IS_GONE_OCCURRED)) {
+ return true
+ }
+ else if (card === C_KOHL_PROPOSES_REUNIFICATION && !game.persistent_events.includes(C_THE_WALL_MUST_GO)) {
+ return true
+ }
+ else if (card === C_BROUGHT_IN_FOR_QUESTIONING && game.active === DEM) {
+ if (game.democrat_hand.length === 0) {
+ if (!game.state.startsWith('vm')) { logi('Democrat has no cards to discard') }
+ return true }
+ }
+ else if (card === C_DEUTSCHE_MARKS && game.active === DEM) {
+ if (game.democrat_hand.length === 0) {
+ if (!game.state.startsWith('vm')) { logi('Democrat has no cards to give') }
+ return true }
+ }
+ else if (card === C_KISS_OF_DEATH && game.active === COM) {
+ if (game.communist_hand.length === 0) {
+ if (!game.state.startsWith('vm')) { logi('Communist has no cards to discard') }
+ return true }
+ }
+ else if (card === C_DISSIDENT_ARRESTED && game.active === DEM) {
+ let dem_intellectual_infl = spaces.filter(space => space.socio === 5 && game.demInfl[space.space_id] > 0).length
+ if (dem_intellectual_infl === 0) {
+ if (!game.state.startsWith('vm')) { logi('No influence to remove') }
+ return true
+ }
+ } else if ((card === C_SAJUDIS || card === C_THE_BALTIC_WAY) && game.active === COM) {
+ if (game.systematization && game.systematization === S_HARGHITA_COVASNA ) {
+ if (check_dem_control(S_RAZGRAD)) {
+ if (!game.state.startsWith('vm')) { logi('Minorities spaces already controlled') }
+ return true
+ }
+ } else if (check_dem_control(S_RAZGRAD) && check_dem_control(S_HARGHITA_COVASNA)) {
+ if (!game.state.startsWith('vm')) { logi('Minorities spaces already controlled') }
+ return true
+ }
+ } else if (card === C_CEAUSESCU && game.active === DEM) {
+ let dem_romania_infl = spaces.filter(space => space.country === 'Romania' && game.demInfl[space.space_id] > 0).length
+ if (dem_romania_infl === 0) {
+ if (!game.state.startsWith('vm')) { logi('No influence to remove') }
+ return true
+ }
+ }
+ else if (card === C_WE_ARE_THE_PEOPLE && game.active === COM) {
+ if (game.demInfl[S_LUTHERAN_CHURCH] === 0) {
+ if (!game.state.startsWith('vm')) { logi('No influence to remove') }
+ return true
+ }
+ }
+ else if (card === C_BETRAYAL && game.active === DEM) {
+ if (!game.systematization === S_ORTHODOX_CHURCH_ROMANIA) {
+ if (game.demInfl[S_ORTHODOX_CHURCH_BULGARIA] === 0) {
+ if (!game.state.startsWith('vm')) { logi('No influence to remove') }
+ return true
+ }
+ } else if (game.demInfl[S_ORTHODOX_CHURCH_BULGARIA] === 0 && game.demInfl[S_ORTHODOX_CHURCH_ROMANIA] === 0) {
+ if (!game.state.startsWith('vm')) { logi('No influence to remove') }
+ return true
+ }
+ }
+ else if (card === C_GOVERNMENT_RESIGNS && game.active === COM) {
+ let uncontrolled_elites = spaces.filter( space => spaces[space.space_id].socio === 1 && game.comInfl[space.space_id] > 0 && !check_control(space.space_id)).length
+ if (uncontrolled_elites === 0) {
+ if (!game.state.startsWith('vm')) { logi('No uncontrolled Elite spaces') }
+ return true
+ }
+ } else if (card === C_ST_NICHOLAS_CHURCH && game.active === COM) {
+ if (check_dem_control(S_LUTHERAN_CHURCH)) {
+ if (!game.state.startsWith('vm')) { logi('Lutheran Church already controlled') }
+ return true
+ }
+ } else if (card === C_BULGARIAN_TURKS_EXPELLED && game.active === DEM) {
+ if (game.demInfl[S_RAZGRAD] === 0 ) {
+ if (!game.state.startsWith('vm')) { logi('No influence to remove') }
+ return true
+ }
+ } else if (card === C_NORMALIZATION && game.active === DEM) {
+ if (game.demInfl[S_PRAHA] === 0 && game.demInfl[S_PLZEN] === 0 ) {
+ if (!game.state.startsWith('vm')) { logi('No influence to remove') }
+ return true
+ }
+ } else if (card === C_DOMINO_THEORY) {
+ if (game.revolutions.filter(value => value === true).length < 2) {
+ return true
+ } else if (!scoring_cards.some(card => game.strategy_discard.includes(card))) {
+ return true
+ }
+ } else if (card === C_UNION_OF_DEMOCRATIC_FORCES && game.active === COM) {
+ let bulgarian_presence = spaces.filter(space => space.country === 'Bulgaria' && game.comInfl[space.space_id] > 0).length
+ if (bulgarian_presence === 0) {
+ if (!game.state.startsWith('vm')) { logi('No SPs to remove') }
+ return true
+ }
+ } else if (card === C_EXIT_VISAS && game.active === COM) {
+ if (game.democrat_hand.length === 0) {
+ if (!game.state.startsWith('vm')) { logi('Democrat has no cards to discard') }
+ return true
+ }
+ } else if (card === C_SAMIZDAT && game.active === COM) {
+ if (game.democrat_hand.length === 0) {
+ if (!game.state.startsWith('vm')) { logi('Democrat has no cards to set aside') }
+ return true
+ }
+ } else if (card === C_SPITZEL && game.active === DEM) {
+ let dem_germany_infl = spaces.filter(space => space.country === 'East_Germany' && game.demInfl[space.space_id] > 0).length
+ if (dem_germany_infl === 0) {
+ if (!game.state.startsWith('vm')) { logi('No influence to remove') }
+ return true
+ }
+ } else if (card === C_MY_FIRST_BANANA && game.active === COM) {
+ let com_germany_infl = spaces.filter(space => space.country === 'East_Germany' && game.comInfl[space.space_id] > 0).length
+ if (com_germany_infl === 0) {
+ if (!game.state.startsWith('vm')) { logi('No influence to remove') }
+ return true
+ }
+ } else if (card === C_POLITBURO_INTRIGUE && game.active === DEM) {
+ let dem_bulgaria_infl = spaces.filter(space => space.country === 'Bulgaria' && game.demInfl[space.space_id] > 0).length
+ if (dem_bulgaria_infl === 0) {
+ if (!game.state.startsWith('vm')) { logi('No influence to remove') }
+ return true
+ }
+ }
+ else {
+ return false
+ }
+}
+
+function get_events(card){
+ if (event_is_playable(card)) {
+ if (cards[card].side === 'D') {
+ if (game.active === DEM) {gen_action('event')}
+ if (game.active === COM) {gen_action('opp_event')}
+ }
+ else if (cards[card].side === 'C') {
+ if (game.active === COM) {gen_action('event')}
+ if (game.active === DEM) {gen_action('opp_event')}
+ }
+ else {
+ gen_action('event')
+ }
+ }
+}
+
+function event_is_playable(card) {
+ //Reformer never playable here
+ if (card === C_REFORMER_REHABILITATED) {
+ return false
+ }
+ //Check for Common European Home under Stasi
+ else if (game.stasi_card === C_COMMON_EUROPEAN_HOME && card === C_COMMON_EUROPEAN_HOME && game.active === DEM) {
+ return false
+ }
+ //Check for The Chinese Solution
+ else if (game.com_tst_position >= 7 && card === C_THE_CHINESE_SOLUTION) {
+ return true
+ }
+
+ //Check for Gorbachev Charms the West after Breakaway Baltic Republics
+ else if (card === C_GORBACHEV_CHARMS_THE_WEST && !game.playable_cards.includes(C_GORBACHEV_CHARMS_THE_WEST)) {
+ return false
+ }
+ //Then check normally
+ else if (game.playable_cards.includes(card)) {
+ return true
+ } else if (cards[card].playable) {
+ return true
+ } else {
+ return false
+ }
+}
+
+function get_card_ops(card) {
+ let ops = cards[card].ops
+ if (game.persistent_events.includes(C_PERESTROIKA) && game.active === COM) {
+ if(game.state === 'choose_card' || game.state === 'stasi_play_card' || game.state === 'vm_common_european_home_play' || game.state === 'general_strike') {
+ log(`+1 op from C${C_PERESTROIKA}`)
+ }
+ ops ++
+ }
+ if (game.persistent_events.includes(C_THE_SINATRA_DOCTRINE) && game.active === DEM) {
+ if(game.state === 'choose_card' || game.state === 'stasi_play_card' || game.state === 'vm_common_european_home_play' || game.state === 'vm_laszlo_tokes') {
+ log(`+1 op from C${C_THE_SINATRA_DOCTRINE}`)
+ }
+ ops ++
+ }
+
+ if ((game.active === DEM && game.dem_tst_position >= 2 && game.com_tst_position <= 1 && cards[card].ops === 1) || (game.active === COM && game.com_tst_position >=2 && game.dem_tst_position <= 1 && cards[card].ops === 1)) {
+ if(game.state === 'choose_card' || game.state === 'stasi_play_card' || game.state === 'vm_common_european_home_play') {
+ log('+1 op from Tiananmen Square Track')
+ }
+ ops ++
+ }
+
+ if ((game.active === DEM && game.prudence && game.prudence.DEM !== 0)) {
+ if(game.state === 'choose_card' || game.state === 'stasi_play_card' || game.state === 'vm_common_european_home_play' || game.state === 'vm_laszlo_tokes') {
+ if (ops > 2) {
+ log(`${pluralize(game.prudence.DEM,'op')} from C${C_PRUDENCE}`)
+ } else {
+ if (ops > 1) {
+ log(`-1 op from C${C_PRUDENCE}`)
+ }
+ }
+ }
+ ops += game.prudence.DEM
+
+ if (ops < 1) {
+ ops = 1
+ }
+ }
+
+ if (game.active === COM && game.prudence && game.prudence.COM < 0) {
+ if(game.state === 'choose_card' || game.state === 'general_strike' || game.state === 'vm_common_european_home_play') {
+ if (ops > 2) {
+ log(`${pluralize(game.prudence.COM,'op')} from C${C_PRUDENCE}`)
+ } else if (ops > 1) {
+ log(`-1 op from C${C_PRUDENCE}`)
+ }
+ }
+ ops += game.prudence.COM
+ if (ops < 1) {
+ ops = 1
+ }
+ } return ops
+}
+
+function get_tst_6_ops() {
+ let ops = 0
+ if (game.persistent_events.includes(C_PERESTROIKA) && game.active === COM) {
+ logi(`+1 op from C${C_PERESTROIKA}`)
+ ops ++
+ }
+ if (game.persistent_events.includes(C_THE_SINATRA_DOCTRINE) && game.active === DEM) {
+ logi(`+1 op from C${C_THE_SINATRA_DOCTRINE}`)
+ ops ++
+ }
+ if ((game.active === DEM && game.prudence && game.prudence.DEM !== 0)) {
+ if (ops > 0) {
+ log(`${pluralize(game.prudence.DEM,'op')} from C${C_PRUDENCE}`)
+ } else {
+ logi(`-1 op from C${C_PRUDENCE}`)
+ }
+ ops += game.prudence.DEM
+ if (ops < -1) {
+ ops = -1
+ }
+ }
+
+ if (game.active === COM && game.prudence && game.prudence.COM < 0) {
+ if (ops > 0) {
+ logi(`${pluralize(game.prudence.COM,'op')} from C${C_PRUDENCE}`)
+ } else {
+ logi(`-1 op from C${C_PRUDENCE}`)
+ }
+ ops += game.prudence.COM
+ if (ops < -1) {
+ ops = -1
+ }
+ }
+ return ops
+}
+
+function finish_play_card() {
+ // Check if Common European Home played for influence
+ if (game.played_card === C_COMMON_EUROPEAN_HOME) {
+ if (game.active === DEM) {
+ game.vp --
+ logi(`-1 VP for playing C${C_COMMON_EUROPEAN_HOME} for operations`)
+ } else {
+ game.vp ++
+ logi(`+1 VP for playing C${C_COMMON_EUROPEAN_HOME} for operations`)
+ }
+ if (check_vp()) {
+ return
+ }
+ }
+ // Check if card is opponent card with event that needs to be resolved
+
+ if (cards[game.played_card].playable || game.playable_cards.includes(game.played_card)) {
+ if ((game.active === DEM && cards[game.played_card].side === "C" ) || (game.active === COM && cards[game.played_card].side === "D")) {
+ game.vm_event_to_do = true
+ }
+ }
+}
+
+function finish_the_wall() {
+ if (game.the_wall_must_go['dem_wins'] === 2) {
+ game.persistent_events.push(C_THE_WALL_MUST_GO)
+ game.playable_cards = game.playable_cards.filter(card => card !== C_THE_WALL)
+ log('+3 VP')
+ game.vp += 3
+ if (check_vp()) {
+ return
+ }
+ for (let i = 0; i < spaces.length; i++) {
+ let space = spaces[i]
+ if (space.country === 'East_Germany' && game.comInfl[i] > 0){
+ game.valid_spaces.push(space.space_id)
+ }
+ }
+ if (game.active === DEM) {next_player()}
+ game.return = COM
+ vm_next ()
+ } else {
+ permanently_remove(C_THE_WALL_MUST_GO)
+ delete game.the_wall_must_go
+ if (game.vm_infl_to_do) {
+ game.return = COM
+ } else {
+ game.return = game.active
+ }
+ vm_return()
+ }
+}
+
+// =========== MOVING THROUGH TURNS ============
+
+function end_round() {
+ //Check if the game is over! WHY IS THIS NEEDED?
+ if (game.state === 'game_over') {
+ return}
+
+ //Check if the card needs to be discarded.
+ let discard_check = [...game.strategy_removed, ...game.persistent_events]
+ if (!discard_check.includes(game.played_card) && game.played_card > 0) {
+ game.strategy_discard.push(game.played_card)
+ }
+
+ //Reset
+ game.played_card = 0
+ delete game.temp
+ delete game.vm_event
+ delete game.phase
+ game.remove_opponent_infl = false
+ game.is_pwr_struggle = false
+ game.vm_infl_to_do = false /*Can get rid of this and use game.return_state? */
+ delete game.vm_event_to_do
+ delete game.vm_infl_to_do
+ delete game.vm_active_country
+ game.return_state = ''
+ game.discard = false
+ game.return = ''
+ game.valid_cards = []
+ game.valid_spaces = []
+ check_common_european_home()
+ reset_austria_hungary_border_reopened() /*This should be redundant! */
+
+ // Check for duplicate card entries
+ let card_check
+ if (game.samizdat_card > 0) {
+ card_check = [...game.strategy_deck, ...game.strategy_discard, ...game.strategy_removed, ...game.persistent_events, ...game.communist_hand, ... game.democrat_hand, game.samizdat_card];
+ } else {
+ card_check = [...game.strategy_deck, ...game.strategy_discard, ...game.strategy_removed, ...game.persistent_events, ...game.communist_hand, ... game.democrat_hand];
+ }
+ card_check = card_check.filter(card => card <= last_strategy_card)
+ function check_duplicates(array) {
+ return new Set(array).size !== array.length;
+ }
+
+ function find_duplicates(array) {
+ const duplicates = array.filter((item, index) => array.indexOf(item) !== index);
+ return [...new Set(duplicates)];
+ }
+
+ card_check = card_check.sort((a, b) => a - b)
+
+ if (check_duplicates(card_check)) {
+ console.log('duplicate cards: card check', card_check)
+ const duplicates = find_duplicates(card_check)
+ console.log('game.strategy_deck', game.strategy_deck, 'game.strategy_discard', game.strategy_discard, 'game.strategy_removed', game.strategy_removed, 'game.persistent_events', game.persistent_events, 'game.communist_hand', game.communist_hand, 'game.democrat_hand', game.democrat_hand)
+ throw new Error(`Duplicate cards detected: ${duplicates.join(', ')}`)
+ }
+
+ if (game.turn <= 3) {
+ if (card_check.length !== 40) {
+ console.log('wrong number of cards in game', card_check)
+ throw new Error(`Wrong number of cards: ${card_check.length}`)
+ }
+ } else if (game.turn <=7) {
+ if (card_check.length !== 81) {
+ console.log('wrong number of cards in game', card_check)
+ throw new Error(`Wrong number of cards: ${card_check.length}`)
+ }
+ } else if (card_check.length !== 110) {
+ console.log('Entire array:', JSON.stringify(card_check))
+ throw new Error(`Wrong number of cards: ${card_check.length}`)
+ }
+
+ //Check if the Reformer is playable
+ check_reformer()
+
+ // Check if last round and if so resolve end turn events
+ if (game.round_player === DEM && game.round === 7) {
+ if(game.persistent_events.includes(C_HONECKER)) {
+ if (game.active !== COM) {
+ next_player()
+ }
+ game.state = 'honecker'
+ return
+ }
+ else if (game.dem_tst_position >= 6 && game.com_tst_position <= 5) {
+ if (game.active !== DEM) {
+ next_player()
+ }
+ game.return = game.active
+ clear_undo()
+ game.return_state = 'end_turn_4_5_4'
+ goto_vm(206)
+ return
+ } else if (game.com_tst_position >= 6 && game.dem_tst_position <= 5) {
+ if (game.active !== COM) {
+ next_player()
+ }
+ game.return = game.active
+ clear_undo()
+ game.return_state = 'end_turn_4_5_4'
+ goto_vm(206)
+ return
+ }
+ else {
+ clear_undo()
+ game.state = 'end_turn_4_5_4'
+ return
+ }
+ }
+
+ // Resolve end action round
+ //Stasi check
+ if(game.round_player === COM && game.persistent_events.includes(C_STASI)) {
+ //If in Honecker, turn ends
+ if (game.round === 8) {
+ clear_undo()
+ game.state = 'end_turn_4_5_4'
+ return
+ }
+ //Otherwise go to Stasi
+ game.round_player = DEM
+ if (game.active !== DEM) {
+ next_player()
+ } else {
+ log_h3('Democratic Action Round')
+ }
+ if (game.democrat_hand.includes(game.stasi_card)) {
+ log_h3('C13')
+ game.state = 'stasi_play_card'
+ } else {
+ game.stasi_card = 0
+ game.state = 'choose_card'
+ }
+ return
+ }
+ //Check if in extra Action Round
+ else if (game.round_player === COM && game.round === 8) {
+ clear_undo()
+ game.state = 'end_turn_4_5_4'
+ return
+ }
+ //Normal round end
+ else if (game.round_player===COM) {
+ game.round_player = DEM
+ if (game.active !== DEM) {
+ next_player()
+ } else {
+ log_h3('Democratic Action Round')
+ }
+ game.state = 'choose_card'
+ return
+ }
+ if (game.round_player === DEM) {
+
+ if(game.persistent_events.includes(C_STASI)) {
+ if (game.active !== DEM) {
+ next_player()
+ }
+ log_h3('C13')
+ game.state = 'stasi_end_round'
+ return
+ } else if(game.round_player === DEM && game.persistent_events.includes(C_GENERAL_STRIKE)){
+ game.state = 'general_strike'
+ game.round ++
+ log_h2(`Action Round ${game.round}`)
+ game.round_player = COM
+ if (game.active !== COM) {
+ next_player()
+ }
+ log_h3('C5')
+ return
+ } else {
+ game.state = 'choose_card'
+ game.round_player = COM
+ game.round ++
+ log_h2(`Action Round ${game.round}`)
+ if (game.active !== COM) {
+ next_player()
+ }
+ }
+ }
+}
+
+function new_turn() {
+ clear_undo()
+ game.turn ++
+ game.round = 1
+ game.valid_spaces=[]
+ game.active = COM
+ game.round_player = COM
+ game.dem_tst_attempted_this_turn = 0
+ game.com_tst_attempted_this_turn = 0
+ if (game.tst_7) {game.tst_7 = false}
+ if (game.tst_8) {game.tst_8 = false}
+ delete game.selected_space
+
+ //Remove events that only last one turn
+
+ for (let e of one_turn_events) {
+ if (game.persistent_events.includes(e)) {
+ end_one_turn_event(e)
+ }
+ }
+ if (game.prudence) {
+ delete game.prudence
+ log_summary(`C${8}`)
+ }
+ if (game.summary.length > 0) {
+ log('No longer in effect:')
+ pop_summary_i()
+ log_br()
+ }
+ delete game.stasi_card
+ delete game.stand_fast
+
+ if (game.samizdat_card > 0 ) {
+ game.democrat_hand.push(game.samizdat_card)
+ delete game.samizdat_card
+ }
+
+ log_h1("Turn " + game.turn)
+
+ if (game.turn === 4) { add_midyear() }
+ if (game.turn === 8) { add_lateyear() }
+
+ if (game.turn > 1) {
+ if (game.persistent_events.includes(C_PRESIDENTIAL_VISIT)) {
+ game.com_hand_limit = 7
+ log('Communist draws 7 cards due to C65')
+ permanently_remove(C_PRESIDENTIAL_VISIT)
+ game.persistent_events = game.persistent_events.filter( card => card !== C_PRESIDENTIAL_VISIT)
+ }
+ draw_cards(game.strategy_deck, game.democrat_hand, game.communist_hand, game.dem_hand_limit, game.com_hand_limit)
+ game.com_hand_limit = 8
+ }
+
+ //Check if TST effects need to be resolved
+ if ((game.dem_tst_position >=5 && game.com_tst_position <= 4) || (game.com_tst_position >= 5 && game.dem_tst_position <= 4)) {
+ log_h2('Tiananmen Square Track Award')
+
+ if ((game.dem_tst_position >= 5 && game.com_tst_position <= 4 && game.active !== DEM) || (game.com_tst_position >= 5 && game.dem_tst_position <= 4 && game.active !== COM)) {
+ next_player()
+ }
+ let hand = game.dem_tst_position >=5 ? game.democrat_hand : game.communist_hand
+ for (let card of hand) {
+ if (scoring_cards.includes(card)) continue
+ game.valid_cards.push(card)
+ }
+ game.state = 'tst_goddess'
+ } else {
+ log_h2("Action Round " + game.round)
+ log_side()
+ if (game.persistent_events.includes(5)) {
+ log_h3('C5')
+ game.state = 'general_strike'
+ }
+ else {
+ game.state = 'choose_card'
+ }
+ }
+}
+
+function end_one_turn_event(event) {
+ game.persistent_events = game.persistent_events.filter(n => n !== event)
+ game.strategy_removed.push(event)
+ log_summary(`C${event}`)
+}
+
+function next_player() {
+ clear_undo()
+ if (game.active === DEM)
+ game.active = COM
+ else
+ game.active = DEM
+ log_side()
+}
+
+function change_player() {
+ clear_undo()
+ if (game.active === DEM)
+ game.active = COM
+ else
+ game.active = DEM
+}
+
+function random(range) {
+ return (game.seed = game.seed * 200105 % 34359738337) % range
+}
+
+function roll_d6() {
+ return random(6) + 1
+}
+
+function find_country_index(country) {
+ return countries.indexOf(country)
+}
+
+function draw_deck() {
+ let deck = []
+ for (let c = first_strategy_card; c <= last_strategy_card; ++c)
+ if (cards[c].period === 1)
+ deck.push(c)
+ return deck
+}
+
+function draw_cards(deck, democrat_hand, communist_hand, dem_hand_limit, com_hand_limit) {
+ //Start with the communist player
+ let turn = 'communist';
+ while (democrat_hand.length < dem_hand_limit || communist_hand.length < com_hand_limit) {
+ if (deck.length === 0) {
+ log_h3('--- Reshuffle ---')
+ deck.push(...game.strategy_discard)
+ game.strategy_discard = []
+ } else if (turn === 'communist' && communist_hand.length < com_hand_limit) {
+ communist_hand.push(draw_card(deck));
+ turn = 'democrat';
+ } else if(turn === 'communist' && communist_hand.length === com_hand_limit) {
+ turn = 'democrat';
+ }
+ else if (turn === 'democrat' && democrat_hand.length < dem_hand_limit) {
+ democrat_hand.push(draw_card(deck));
+ turn = 'communist';
+ }
+ else if (turn === 'democrat' && democrat_hand.length === dem_hand_limit) {
+ turn = 'communist';
+ }
+ }
+ clear_undo()
+}
+
+function draw_card(deck) {
+ if (deck.length === 0) {
+ log_h3('--- Reshuffle ---')
+ deck.push(...game.strategy_discard)
+ game.strategy_discard = []
+ }
+ const randomIndex = Math.floor(random(deck.length))
+ return deck.splice(randomIndex, 1)[0];
+}
+
+function discard(card) {
+ let find_card
+ if (!game.is_pwr_struggle) {
+ if (game.active === COM) {
+ find_card = game.communist_hand.indexOf(card)
+ game.communist_hand.splice(find_card, 1)
+ } else {
+ find_card = game.democrat_hand.indexOf(card)
+ game.democrat_hand.splice(find_card, 1)
+ }
+ if (!game.strategy_discard.includes(card)) {
+ game.strategy_discard.push(card)
+ log(`Discarded C${card}`)
+ }
+ } else if (game.is_pwr_struggle) {
+ if (game.active === COM) {
+ find_card = game.com_pwr_hand.indexOf(card);
+ game.com_pwr_hand.splice(find_card, 1);
+ } else {
+ find_card = game.dem_pwr_hand.indexOf(card);
+ game.dem_pwr_hand.splice(find_card, 1);
+ }
+ game.power_struggle_discard.push(card)
+ }
+}
+function silent_discard(card) {
+ let find_card
+ if (!game.is_pwr_struggle) {
+ if (game.active === COM) {
+ find_card = game.communist_hand.indexOf(card)
+ game.communist_hand.splice(find_card, 1)
+ } else {
+ find_card = game.democrat_hand.indexOf(card)
+ game.democrat_hand.splice(find_card, 1)
+ }
+ if (!game.strategy_discard.includes(card)) {
+ game.strategy_discard.push(card)
+ }
+ } else if (game.is_pwr_struggle) {
+ if (game.active === COM) {
+ find_card = game.com_pwr_hand.indexOf(card);
+ game.com_pwr_hand.splice(find_card, 1);
+ } else {
+ find_card = game.dem_pwr_hand.indexOf(card);
+ game.dem_pwr_hand.splice(find_card, 1);
+ }
+ game.power_struggle_discard.push(card)
+ }
+}
+
+function remove_from_discard(card) {
+ let card_index = game.strategy_discard.indexOf(card)
+ if (card_index !== -1) {
+ game.strategy_discard.splice(card_index, 1)
+ }
+}
+
+function discard_card(hand) {
+ let card = Math.floor(random(hand.length))
+ let discarded_card = hand.splice(card, 1)[0]
+ if (game.is_pwr_struggle) {
+ if (numberless_cards.includes(discarded_card)) {
+ logi(`Discarded: P${discarded_card}`)
+ } else {
+ logi(`Discarded: P${discarded_card} V${power_cards[discarded_card].value}`)
+ }
+ game.power_struggle_discard.push(discarded_card)
+ } else {
+ log(`Discarded C${discarded_card}`)
+ game.strategy_discard.push(discarded_card)
+ }
+ return discarded_card
+}
+
+function add_midyear() {
+ for (let c = first_strategy_card; c <= last_strategy_card; ++c)
+ if (cards[c].period === 2)
+ game.strategy_deck.push(c)
+ log_h3('Mid-year cards added to draw deck')
+}
+
+function add_lateyear() {
+ for (let c = first_strategy_card; c <= last_strategy_card; ++c)
+ if (cards[c].period === 3)
+ game.strategy_deck.push(c)
+ log_h3('Late-year cards added to draw deck')
+}
+
+function reset_power() {
+ game.power_struggle_deck = []
+ game.power_struggle_discard = []
+ game.dem_pwr_hand = []
+ game.com_pwr_hand = []
+ delete game.phase
+ delete game.raised_stakes_round
+ delete game.raised_stakes
+ delete game.raised_stakes_discard
+ delete game.played_power_card
+ delete game.tactics_fails
+ delete game.view_opp_power_hand
+
+ let scoring_events = [C_PEASANT_PARTIES_REVOLT, C_YAKOVLEV_COUNSELS_GORBACHEV, C_THE_CROWD_TURNS_AGAINST_CEAUSESCU]
+ for (let e of scoring_events ) {
+ if (e === C_THE_CROWD_TURNS_AGAINST_CEAUSESCU ) {
+ if (game.persistent_events.includes(e) && game.pwr_struggle_in === 'Romania') {
+ permanently_remove(e)
+ }
+ } else if (game.persistent_events.includes(e)) {
+ permanently_remove(e)
+ }
+ }
+}
+
+function check_tyrant() {
+ if (game.the_tyrant_is_gone > 0 && check_dem_control(game.the_tyrant_is_gone)) {
+ log('+2 VP from C97')
+ game.vp += 2
+ if (check_vp()) {
+ return
+ }
+ delete game.the_tyrant_is_gone
+ }
+}
+
+function resolve_tyrant() {
+ if (game.persistent_events.includes(C_THE_TYRANT_IS_GONE) && game.pwr_struggle_in === 'Romania' && game.persistent_events.includes(THE_CROWD_TURNS_AGAINST_CEAUSESCU_OCCURRED)) {
+ game.return_state = 'finish_scoring'
+ if (game.active !== DEM) {
+ next_player()
+ }
+ game.state = 'the_tyrant_is_gone'
+ } else {
+ game.state = 'finish_scoring'
+ }
+}
+
+function check_systematization() { /* Check for Systematization - may not use this space */
+ if (game.systematization > 0) {
+ game.valid_spaces = game.valid_spaces.filter(n => n !== game.systematization)
+ }
+}
+
+function check_common_european_home() {
+ if (!game.playable_cards.includes(C_COMMON_EUROPEAN_HOME)) {
+ game.playable_cards.push(C_COMMON_EUROPEAN_HOME)
+ }
+}
+
+function this_card() {
+ return game.vm_event > 0 ? game.vm_event : game.played_card
+}
+
+const pluralize = (count, noun, suffix = 's') => {
+ if (Math.abs(count) === 1) {
+ return `${count} ${noun}`
+ } else {
+ if (noun.endsWith('y') && !/[aeiou]y$/.test(noun)) {
+ noun = noun.slice(0, -1) + 'ie'
+ }
+ return `${count} ${noun}${suffix}`
+ }
+}
+
+function clean_name(str) {
+ if (str && str.slice(-1) === '*') {
+ return str.slice(0, -1)
+ } else {
+ return str;
+ }
+}
+
+function country_name(country) {
+ return country.replace(/_/g, ' ')
+}
+
+// ======== LOG FUNCTIONS =============
+
+function log(msg) {
+ game.log.push(msg)
+}
+
+function log_br() {
+ if (game.log.length > 0 && game.log[game.log.length - 1] !== "")
+ game.log.push("")
+}
+
+function logi(msg) {
+ game.log.push(">" + msg)
+}
+
+function log_h1(msg) {
+ log_br()
+ log(".h1 " + msg)
+ log_br()
+}
+
+function log_h2(msg) {
+ log_br()
+ log(".h2 " + msg)
+ log_br()
+}
+
+function log_h3(msg) {
+ log_br()
+ log(".h3 " + msg)
+}
+
+function log_gap(msg) {
+ log_br()
+ game.log.push(msg)
+}
+
+function log_msg_gap(msg) {
+ game.log.push(msg)
+ log_br()
+}
+
+
+function log_side() {
+ log_br()
+ if (game.active === DEM)
+ log(".h2d " + game.active)
+ else
+ log(".h2c " + game.active)
+ log_br()
+}
+
+function log_sep() {
+ log(".hr")
+}
+
+function log_action(msg) {
+ log_br()
+ log(msg)
+}
+
+// ============= SUMMARY FUNCTIONS =============
+
+function push_summary() {
+ if (game.summary)
+ throw "TOO MANY SUMMARIES"
+ game.summary = []
+}
+
+function log_summary(msg) {
+
+ if (msg.startsWith('Added') || msg.startsWith('Removed')) {
+ for (let item of game.summary) {
+ if (item[1] === msg) {
+ item[0]++
+ return
+ }
+ }
+ }
+ game.summary.push([1, msg])
+}
+
+function pop_summary() {
+ if (game.summary.length > 0) {
+ for (let [n, msg] of game.summary) {
+ if (n > 1) {
+ log(msg.replace("£ SP", `${n} SPs`));
+ } else {
+ log(msg.replace("£ SP", `${n} SP`));
+ }
+ }
+ }
+ game.summary = []
+}
+
+function pop_summary_i() {
+ if (game.summary.length > 0) {
+ for (let [n, msg] of game.summary) {
+ if (n > 1) {
+ logi(msg.replace("£ SP", `${n} SPs`));
+ } else {
+ logi(msg.replace("£ SP", `${n} SP`));
+ }
+ }
+ }
+ game.summary = []
+}
+
+function do_log_summary() {
+ if (game.summary.length > 0) {
+ pop_summary()
+ log_br()
+ }
+}
+
+// ============ UNDO FUNCTIONS ==================
+
+function clear_undo() {
+ if (game.undo.length > 0)
+ game.undo = []
+}
+
+function push_undo() {
+ let copy = {}
+ for (let k in game) {
+ let v = game[k]
+ if (k === "undo")
+ continue
+ else if (k === "log")
+ v = v.length
+ else if (typeof v === "object" && v !== null)
+ v = object_copy(v)
+ copy[k] = v
+ }
+ game.undo.push(copy)
+}
+
+function pop_undo() {
+ let save_log = game.log
+ let save_undo = game.undo
+ game = save_undo.pop()
+ save_log.length = game.log
+ game.log = save_log
+ game.undo = save_undo
+}
+
+// Fast deep copy for objects without cycles
+function object_copy(original) {
+ if (Array.isArray(original)) {
+ let n = original.length
+ let copy = new Array(n)
+ for (let i = 0; i < n; ++i) {
+ let v = original[i]
+ if (typeof v === "object" && v !== null)
+ copy[i] = object_copy(v)
+ else
+ copy[i] = v
+ }
+ return copy
+ } else {
+ let copy = {}
+ for (let i in original) {
+ let v = original[i]
+ if (typeof v === "object" && v !== null)
+ copy[i] = object_copy(v)
+ else
+ copy[i] = v
+ }
+ return copy
+ }
+}
+
+
+/* =================== VM FUNCTIONS ========================== */
+
+function goto_vm(proc) {
+ let old_vm = game.vm;
+
+ game.state = "vm";
+ game.vm = {
+ prompt: 0,
+ fp: proc,
+ ip: 0,
+ };
+
+ if (old_vm) {
+ game.vm.return_vm = old_vm;
+ }
+
+ vm_exec();
+}
+
+function vm_exec() {
+ vm_inst(0)();
+}
+
+function vm_inst(a) {
+ return CODE[game.vm.fp][game.vm.ip][a]
+}
+
+function vm_next() {
+ game.vm.ip++;
+ vm_exec();
+}
+
+function vm_logi(){
+ logi(vm_operand(1))
+ vm_next()
+}
+
+function vm_operand(a) {
+ let x = CODE[game.vm.fp][game.vm.ip][a]
+ if (a > 0 && typeof x === "function")
+ return x()
+ return x
+}
+
+function vm_if() {
+ if (!vm_operand(1)) {
+ let balance = 1
+ while (balance > 0) {
+ ++game.vm.ip
+ switch (vm_operand(0)) {
+ case vm_if:
+ ++balance
+ break
+ case vm_endif:
+ --balance
+ break
+ case vm_else:
+ if (balance === 1)
+ --balance
+ break
+ }
+ if (game.vm.ip < 0 || game.vm.ip > CODE[game.vm.fp].length)
+ throw "ERROR"
+ }
+ }
+ vm_next()
+}
+
+function vm_else() {
+ vm_goto(vm_endif, vm_if, 1, 1)
+}
+
+function vm_endif() {
+ vm_next()
+}
+
+function vm_goto_step(step) {
+ for (let i = game.vm.ip; i < CODE[game.vm.fp].length; i++) {
+ if (CODE[game.vm.fp][i][0] === step) {
+ game.vm.ip = i;
+ vm_exec();
+ return;
+ }
+ }
+
+ console.log("ERROR: Target operation not found in the current procedure.");
+}
+
+
+function vm_goto(op, nop, dir, step) {
+ let balance = 1
+ while (balance > 0) {
+ game.vm.ip += dir
+ if (vm_inst(0) === op)
+ --balance
+ if (vm_inst(0) === nop)
+ ++balance
+ if (game.vm.ip < 0 || game.vm.ip > CODE[game.vm.fp].length)
+ throw "ERROR"
+ }
+ game.vm.ip += step
+ vm_exec()
+}
+
+function event_prompt(str) {
+ if (typeof str === "undefined")
+ str = CODE[game.vm.fp][game.vm.prompt][1]
+ if (typeof str === "function")
+ str = str()
+ if (!str) {
+ str = ""
+ }
+ return str
+}
+
+function vm_prompt() {
+ if (game.vm.prompt)
+ game.vm._prompt = game.vm.prompt
+ game.vm.prompt = game.vm.ip
+ vm_next()
+}
+
+function vm_return() {
+ //Remove temporary vm variables
+ delete game.support_check_modifier
+ delete game.vm_max_infl
+ delete game.vm_influence_added
+ delete game.communist_hand_red
+ game.vm_event = 0 /*Reset to 0 now that event has been completed. Hopefully this doesn't cause issues! */
+ if (game.persistent_events.includes(C_AUSTRIA_HUNGARY_BORDER_REOPENED)) {
+ reset_austria_hungary_border_reopened()
+ }
+
+ //Check if end event state is needed
+ if (game.is_pwr_struggle || game.state === 'vm_tst_6' || game.return_state === 'tiananmen_square_attempt_done') {
+ vm_end_event()
+ }
+ //Check if auto-resolve opponent event
+ else if (is_auto_resolve(game.played_card) && ((cards[game.played_card].side === 'C' && game.active === DEM) || (cards[game.played_card].side === 'D' && game.active === COM) )) {
+ vm_end_event()
+ }
+ else {
+ game.state = 'vm_end_event'
+ }
+}
+
+function vm_end_event() {
+ if (game.return !== game.active) {
+ next_player()}
+ if (game.return_state === 'power_struggle') {
+ do_valid_cards()
+ }
+ if (game.return_state && game.return_state !== '') {
+ game.state = game.return_state
+ }
+ else if (game.vm_infl_to_do) {
+ game.state = 'resolve_opponent_event'}
+ else {
+ end_round()
+ }
+}
+
+/* ================== VM ACTIONS =========================== */
+
+function vm_valid_spaces() {
+ for (let i = 1; i <= 6; i++) {
+ let operand = vm_operand(i)
+ if (operand) {
+ let space = spaces.find(space => space.ascii_name === operand)
+ game.valid_spaces.push(space.space_id)
+ }
+ }
+ check_systematization();
+ vm_next();
+}
+
+function vm_valid_spaces_com() {
+ let operand = vm_operand(1)
+ let space = spaces.find(space => space.ascii_name === operand)
+ if (game.comInfl[space.space_id] >0) {
+ game.valid_spaces.push(space.space_id)
+ }
+ check_systematization();
+ vm_next();
+}
+
+function vm_valid_spaces_opponent () {
+ let valid_spaces = []
+ for (let i = 0; i < spaces.length; i++) {
+ let space = spaces[i]
+
+ if (game.active === DEM) {
+ let infl = game.comInfl[i]
+ if (infl > 0) {
+ valid_spaces.push(space.space_id)
+ }
+ } else {
+ let infl = game.demInfl[i]
+ if (infl > 0) {
+ valid_spaces.push(space.space_id)
+ }
+ }
+ }
+ game.valid_spaces = valid_spaces
+ vm_next()
+}
+
+function vm_valid_spaces_socio () {
+ let valid_spaces = []
+ for (let i = 0; i < spaces.length; i++) {
+ let space = spaces[i]
+ if (space.socio === vm_operand(1)) {
+ valid_spaces.push(space.space_id)
+ }
+ }
+ game.valid_spaces = valid_spaces
+ check_systematization()
+ vm_next()
+}
+
+function vm_valid_spaces_opponent_socio () {
+ let valid_spaces = []
+ for (let i = 0; i < spaces.length; i++) {
+ let space = spaces[i]
+ if (game.active === DEM) {
+ let infl = game.comInfl[i]
+ if (infl > 0 && space.socio === vm_operand(1)) {
+ valid_spaces.push(space.space_id)
+ }
+ } else {
+ let infl = game.demInfl[i]
+ if (infl > 0 && space.socio === vm_operand(1)) {
+ valid_spaces.push(space.space_id)
+ }
+ }
+ }
+ game.valid_spaces = valid_spaces
+ check_systematization()
+ vm_next()
+}
+
+function vm_valid_spaces_country () {
+ let country
+ if (vm_operand(1)) {country = vm_operand(1)}
+ else {country = game.vm_active_country}
+ for (let space of spaces) {
+ if (space.country === country) {
+ game.valid_spaces.push(space.space_id);
+ }
+ }
+ check_systematization()
+ vm_next()
+}
+
+function vm_valid_spaces_sc () {
+ valid_spaces_sc()
+ vm_next()
+}
+
+function vm_valid_spaces_country_opp () {
+ let country = ''
+ if (vm_operand(1)) {
+ country = vm_operand(1) }
+ else {
+ country = game.vm_active_country
+ }
+ for (let space of spaces) {
+ if (game.active === DEM) {
+ if (space.country === country && game.comInfl[space.space_id] >0) {
+ game.valid_spaces.push(space.space_id);
+ }
+ } else {
+ if (space.country === country && game.demInfl[space.space_id]>0) {
+ game.valid_spaces.push(space.space_id);
+ }
+ }
+ }
+ vm_next()
+}
+
+function vm_valid_spaces_country_sc () {
+ let active_country
+ if (vm_operand(1)) {
+ active_country = vm_operand(1) }
+ else {
+ active_country = game.vm_active_country
+ }
+ valid_spaces_sc()
+ game.valid_spaces = game.valid_spaces.filter( s => spaces[s].country === active_country)
+ vm_next()
+}
+
+function vm_valid_spaces_country_socio_2() {
+ for (let space of spaces) {
+ if (space.space_id === game.systematization) continue
+ if ((space.country === vm_operand(1) && space.socio === vm_operand(2)) || (space.country === vm_operand(1) && space.socio === vm_operand(3))) {
+ game.valid_spaces.push(space.space_id);
+ }
+ }
+ vm_next()
+}
+
+function vm_valid_spaces_region_socio() {
+ let valid_spaces = []
+ for (let space of spaces) {
+ if (space.space_id === game.systematization) continue
+ if (space.region === vm_operand(1) && space.socio === vm_operand(2)) {
+ valid_spaces.push(space.space_id);
+ }
+ }
+ game.valid_spaces = valid_spaces
+ vm_next()
+}
+
+function vm_valid_spaces_region_opp() {
+ let valid_spaces = []
+ for (let space of spaces) {
+ let s = space.space_id
+ if ((game.active === DEM && space.region === vm_operand(1) && game.comInfl[s] > 0 ) || (game.active === COM && space.region === vm_operand(1) && game.demInfl[s] > 0 )) {
+ valid_spaces.push(space.space_id);
+ }
+ }
+ game.valid_spaces = valid_spaces
+ vm_next()
+}
+
+function vm_valid_spaces_solidarity_legalised() {
+ let valid_spaces = []
+ for (let i = 0; i < spaces.length; i++) {
+ let space = spaces[i]
+ let uncontrolled = (!check_control(i) && !check_opp_control(i))
+ if ((space.country === 'Poland' && uncontrolled && space.socio === 3) || (space.country === 'Poland' && uncontrolled && space.socio === 4)) {
+ valid_spaces.push(space.space_id);
+ }
+ }
+ game.valid_spaces = valid_spaces
+ vm_next()
+}
+
+function vm_active_country () {
+ game.valid_spaces = game.valid_spaces.filter(space_id => spaces[space_id].country === game.vm_active_country)
+ vm_next()
+}
+
+function vm_take_control_prep() {
+ game.vm_available_ops = vm_operand(1)
+ game.state = 'vm_take_control'
+}
+
+function vm_take_control(space) {
+ if (game.active === DEM) {
+ let current_infl = game.demInfl[space]
+ let opponent_infl = game.comInfl[space]
+ let stability = spaces[space].stability
+
+ if ((current_infl - opponent_infl) < stability) {
+ game.demInfl[space] += stability - current_infl + opponent_infl
+ }
+ } else if (game.active === COM) {
+ let current_infl = game.comInfl[space]
+ let opponent_infl = game.demInfl[space]
+ let stability = spaces[space].stability
+
+ if ((current_infl - opponent_infl) < stability) {
+ game.comInfl[space] += stability - current_infl + opponent_infl
+ }
+ }
+ game.valid_spaces = game.valid_spaces.filter(id => id !== space)
+ log(`Took control of %${space}`)
+}
+
+function vm_do_add_infl_free(space) {
+ push_undo()
+ log_summary(`Added £ SP in %${space}.`)
+
+ // Update influence values
+ if (game.active === COM) {
+ game.comInfl[space]++
+ } else {
+ game.demInfl[space]++
+ }
+ game.vm_available_ops--
+ check_tyrant()
+}
+
+function vm_add_infl() {
+ if (vm_operand(1)) {game.vm_available_ops = vm_operand(1)}
+ game.state = 'vm_add_infl'
+}
+
+function vm_add_infl_free() {
+ if (vm_operand(1)) {game.vm_available_ops = vm_operand(1)}
+ game.state = 'vm_add_infl_free'
+}
+
+function vm_add_x_infl() {
+ game.vm_available_ops = vm_operand(1)
+ game.state = 'vm_add_x_infl'
+}
+
+function vm_do_add_x_infl(space) {
+ push_undo()
+ log(`Added ${game.vm_available_ops} SPs in %${space}.`)
+ if (game.active === COM) {
+ game.comInfl[space] += game.vm_available_ops
+ } else {
+ game.demInfl[space] += game.vm_available_ops
+ }
+ check_tyrant()
+ game.vm_available_ops = 0
+ game.valid_spaces = []
+}
+
+function vm_add_limited_infl() {
+ game.vm_available_ops = vm_operand(1)
+ game.vm_max_infl = vm_operand(2)
+ game.state = 'vm_add_limited_infl'
+}
+
+function vm_do_add_limited_infl(space, max_infl) {
+ push_undo()
+ log_summary(`Added £ SP in %${space}`)
+ game.vm_available_ops --
+
+ if (!game.vm_influence_added) {
+ game.vm_influence_added = {};
+ }
+
+ if (!game.vm_influence_added[space]) {
+ game.vm_influence_added[space] = 0;
+ }
+
+ if (game.active === COM) {
+ game.comInfl[space] ++
+ } else {
+ game.demInfl[space] ++
+ }
+
+ game.vm_influence_added[space] ++
+
+ if (game.vm_influence_added[space] === max_infl) {
+ game.valid_spaces = game.valid_spaces.filter(id => id !== space);
+ }
+ check_tyrant()
+ if (game.vm_available_ops === 0) {game.valid_spaces = [] }
+}
+
+function vm_remove_infl() {
+ game.vm_available_ops = vm_operand(1)
+ game.state = 'vm_remove_infl'
+}
+
+function vm_remove_opp_infl() {
+ game.vm_available_ops = vm_operand(1)
+ game.remove_opponent_infl = true
+ if (game.is_pwr_struggle) {
+ game.state = 'vm_scare_tactics'
+ } else {
+ game.state = 'vm_remove_infl'
+ }
+}
+
+function vm_remove_x_opp_infl() {
+ game.vm_available_ops = vm_operand(1)
+ game.remove_opponent_infl = true
+ game.state = 'vm_remove_x_infl'
+}
+
+function vm_do_remove_x_infl(space) {
+ push_undo()
+
+ if (game.remove_opponent_infl) {
+ if (game.active === COM) {
+ if (game.demInfl[space] >= game.vm_available_ops) {
+ game.demInfl[space] -= game.vm_available_ops
+ } else {
+ game.vm_available_ops = game.demInfl[space]
+ game.demInfl[space] -= game.vm_available_ops
+ }
+ } else {
+ if (game.comInfl[space] >= game.vm_available_ops) {
+ game.comInfl[space] -= game.vm_available_ops
+ } else {
+ game.vm_available_ops = game.comInfl[space]
+ game.comInfl[space] -= game.vm_available_ops
+ }
+ }
+ } else {
+ if (game.active === COM) {
+ if (game.comInfl[space] >= game.vm_available_ops) {
+ game.comInfl[space] -= game.vm_available_ops
+ } else {
+ game.vm_available_ops = game.comInfl[space]
+ game.comInfl[space] -= game.vm_available_ops
+ }
+ } else {
+ if (game.demInfl[space] >= game.vm_available_ops) {
+ game.demInfl[space] -= game.vm_available_ops
+ } else {
+ game.vm_available_ops = game.demInfl[space]
+ game.demInfl[space] -= game.vm_available_ops
+ }
+ }
+ }
+
+ log(`Removed ${game.vm_available_ops} SPs from %${space}`)
+ check_tyrant()
+ game.vm_available_ops = 0
+ game.valid_spaces = []
+}
+
+function vm_remove_limited_opp_infl() {
+ game.vm_available_ops = vm_operand(1)
+ game.vm_max_infl = vm_operand(2)
+ game.remove_opponent_infl = true
+ game.state = 'vm_remove_limited_infl'
+}
+
+function vm_do_remove_limited_infl(space, max_infl) {
+ push_undo()
+ log_summary(`Removed £ SP from %${space}.`)
+ game.vm_available_ops --
+
+ if (!game.vm_influence_added) {
+ game.vm_influence_added = {};
+ }
+
+ if (!game.vm_influence_added[space]) {
+ game.vm_influence_added[space] = 0;
+ }
+
+ if (game.active === COM) {
+ game.demInfl[space] --
+ if (game.demInfl[space] === 0) {
+ game.valid_spaces = game.valid_spaces.filter(id => id !== space)
+ }
+ } else {
+ game.comInfl[space] --
+ if (game.comInfl[space] === 0) {
+ game.valid_spaces = game.valid_spaces.filter(id => id !== space)
+ }
+ }
+
+ game.vm_influence_added[space] ++
+
+ if (game.vm_influence_added[space] === max_infl) {
+ game.valid_spaces = game.valid_spaces.filter(id => id !== space);
+ }
+
+ check_tyrant()
+ if (game.vm_available_ops === 0) {game.valid_spaces = []}
+}
+
+function vm_remove_all_infl() {
+ game.vm_available_ops = vm_operand(1)
+ game.state = 'vm_remove_all_infl'
+}
+
+function vm_do_remove_all_infl(space) {
+ push_undo()
+
+ if (game.remove_opponent_infl === true) {
+ if (game.active === COM) {
+ log(`Removed all Democratic SP from %${space}`)
+ game.demInfl[space] = 0
+ } else {
+ log(`Removed all Communist SP from %${space}`)
+ game.comInfl[space] = 0
+ }
+ check_tyrant()
+
+ } else {
+ if (game.active === COM) {
+ log(`Removed all Communist SP from %${space}`)
+ game.comInfl[space] = 0
+ } else {
+ log(`Removed all Democratic SP from %${space}`)
+ game.demInfl[space] = 0
+ }
+ check_tyrant()
+ }
+ game.vm_available_ops --
+ game.valid_spaces = game.valid_spaces.filter(id => id !== space)
+}
+
+function vm_replace_all_infl(space_id) {
+ if (game.active === DEM) {
+ game.demInfl[space_id] += game.comInfl[space_id]
+ log(`Replaced ${game.comInfl[space_id]} Communist SP in %${space_id} with Democratic SP`)
+ game.comInfl[space_id] = 0
+ } else {
+ game.comInfl[space_id] += game.demInfl[space_id]
+ log(`Replaced ${game.demInfl[space_id]} Democrat SP in %${space_id} with Communist SP`)
+ game.demInfl[space_id] = 0
+ }
+ check_tyrant()
+}
+
+function vm_1_support_check() {
+ game.vm_available_ops = 1
+ game.state = 'vm_1_support_check_prep'
+}
+
+function vm_support_check() {
+ game.vm_available_ops = vm_operand(1)
+ game.state = 'vm_support_check_prep'
+}
+
+function vm_support_check_modified() {
+ game.vm_available_ops = vm_operand(1)
+ game.support_check_modifier = vm_operand(2)
+ game.state = 'vm_support_check_prep'
+}
+
+function vm_switch_infl(id){
+ push_undo()
+ game.demInfl[id] -= game.vm_available_ops
+ game.comInfl[id] += game.vm_available_ops
+ log(`Replaced ${pluralize(game.vm_available_ops,'SP')} in %${id}`)
+ game.vm_available_ops = 0
+ check_tyrant()
+}
+
+/* ===================== EVENT SPECIFIC FUNCTIONS ========== */
+
+function vm_40th_anniversary_celebration() {
+ if (game.vp < 0 ) {game.vm_available_ops = 4}
+ else {game.vm_available_ops = 2}
+ vm_next()
+}
+
+function vm_40th_anniversary_celebration_vp() {
+ game.vp --
+ log('-1VP')
+ if (check_vp()) {
+ return
+ }
+ vm_next()
+}
+
+function vm_adamec() {
+ game.state = 'vm_adamec'
+}
+
+function vm_army_backs_revolution() {
+ if (game.persistent_events.includes(C_SECURITATE)) {
+ permanently_remove(C_SECURITATE)
+ }
+ add_to_persistent_events(C_ARMY_BACKS_REVOLUTION)
+ logi(`C${C_SECURITATE} no longer has any effect`)
+ vm_next()
+}
+
+function vm_army_block() {
+ permanently_remove(C_SECURITATE)
+ logi(`Has no effect after C${C_ARMY_BACKS_REVOLUTION}`)
+ vm_next()
+}
+
+function vm_austria_hungary_border_reopened() {
+ add_to_persistent_events(C_AUSTRIA_HUNGARY_BORDER_REOPENED)
+ logi(`For the remainder of the turn, cards played by the Democrat have +1 Ops value if all Operations Points are used in East Germany`)
+ game.austria_hungary_border_reopened_tracker = false
+ vm_next()
+}
+
+function vm_betrayal() {
+ if (game.demInfl[S_ORTHODOX_CHURCH_ROMANIA] > 0 ) { game.valid_spaces.push(S_ORTHODOX_CHURCH_ROMANIA) }
+ if (game.demInfl[S_ORTHODOX_CHURCH_BULGARIA] >0 ) { game.valid_spaces.push(S_ORTHODOX_CHURCH_BULGARIA) }
+ game.state = 'vm_switch_infl'
+}
+
+function vm_breakaway_baltic_republics() {
+ log('+5 VP')
+ game.vp += 5
+ game.stability++
+ if (check_vp()) {
+ return
+ }
+ game.playable_cards.push(C_KREMLIN_COUP)
+ game.playable_cards = game.playable_cards.filter(n => n !== C_GORBACHEV_CHARMS_THE_WEST)
+ if (!check_dem_control(S_HARGHITA_COVASNA) && game.systematization !== S_HARGHITA_COVASNA) {game.valid_spaces.push(S_HARGHITA_COVASNA)}
+ if (!check_dem_control(S_RAZGRAD)) {game.valid_spaces.push(S_RAZGRAD)}
+ vm_next()
+}
+
+function vm_brought_in_for_questioning() {
+ if (game.active === COM) {
+ game.active = DEM
+ }
+ game.phase = 0
+ game.state = 'vm_brought_in_for_questioning'
+}
+
+function vm_bulgarian_turks_expelled(){
+ game.remove_opponent_infl = true
+ game.vp -= 2
+ log('-2VP')
+ if (check_vp()) {
+ return
+ }
+ vm_next()
+}
+
+function vm_ceausescu() {
+ let adj_cluj = false
+
+ if (game.demInfl[S_TIMISOARA] > 0 ) {adj_cluj = true}
+ if (game.demInfl[S_BABES_BOLYAI_UNIVERSITY] > 0 ) {adj_cluj = true}
+ if (game.demInfl[S_ORTHODOX_CHURCH_ROMANIA] > 0 ) {adj_cluj = true}
+ if (game.demInfl[S_BUCURESTI] > 0 ) {adj_cluj = true}
+
+ if (adj_cluj && game.comInfl[S_BUCURESTI]>0) {
+ game.valid_spaces = [S_BUCURESTI]
+ game.vm_available_ops = 1
+ game.remove_opponent_infl = false
+ game.state = 'vm_remove_infl'
+ }
+ else {vm_next()}
+}
+
+function vm_central_committee_reshuffle() {
+ game.state = 'vm_central_committee_reshuffle'
+}
+
+function vm_civic_forum_prep() {
+ log('+1 VP')
+ game.vp++
+ if (check_vp()) {
+ return
+ }
+ vm_next()
+}
+
+function vm_civic_forum() {
+ if (check_dem_control(S_CZECH_WRITERS)) {
+ vm_next()
+ } else {
+ vm_return()
+ }
+}
+
+function vm_cluj_check(){
+ if (game.comInfl[S_CLUJ_NAPOCA] > 0 ) {
+ game.valid_spaces.push(S_CLUJ_NAPOCA)
+ }
+ vm_next()
+}
+
+function vm_common_european_home() {
+ if (game.active === DEM) {
+ for (let c of game.democrat_hand) {
+ if (cards[c].side === 'C') {
+ game.valid_cards.push(c)
+ }
+ }
+ } else {
+ for (let c of game.communist_hand) {
+ if (cards[c].side === 'D') {
+ game.valid_cards.push(c)
+ }
+ }
+ }
+ game.state = "vm_common_european_home_choose"
+}
+
+function vm_dash_for_the_west() {
+ game.valid_cards = []
+ for (let c of game.strategy_discard) {
+ if (cards[c].side === 'D' && cards[c].remove && (cards[c].playable || game.playable_cards.includes(c))) {
+ game.valid_cards.push(c)
+ }
+ }
+ game.state = 'vm_dash_for_the_west'
+}
+
+function vm_deutsche_marks() {
+ let max_value = 1;
+ for (let c of game.democrat_hand) {
+ if (cards[c].ops > max_value) {
+ max_value = cards[c].ops
+ }
+ }
+ let valid_cards = [];
+ for (let c of game.democrat_hand) {
+ if (cards[c].ops === max_value) {
+ valid_cards.push(c);
+ }
+ }
+ game.valid_cards = valid_cards
+ game.state = 'vm_deutsche_marks_prep'
+}
+
+function vm_domino_theory() {
+ game.discard = true
+ for (let card of game.strategy_discard) {
+ if (scoring_cards.includes(card)) {game.valid_cards.push(card) }
+ }
+ game.phase = 0
+ game.state = 'vm_play_event_from_discard'
+}
+
+function vm_domino_theory_pass() {
+ if (game.revolutions.filter(value => value === true).length < 2) {
+ logi('Democrat holds power in fewer than 2 countries')
+ } else if (!scoring_cards.some(card => game.strategy_discard.includes(card))) {
+ logi('No scoring cards in discard')
+ }
+ vm_next()
+}
+
+function vm_eco_glasnost() {
+ add_to_persistent_events(C_ECO_GLASNOST)
+ logi(`+1 VP for Communist support checks in Ruse for the rest of the game`)
+ vm_next()
+}
+
+function vm_elena(){
+ add_to_persistent_events(C_ELENA)
+ logi(`-1 modifier to Democratic Support checks in Romania for the rest of this turn`)
+ vm_next()
+}
+
+function vm_eliminate(space_id) { // Eliminate the democrat influence and move the communist influence to Bucuresti
+ log(`Eliminated %${space_id}`)
+ if (space_id === S_BUCURESTI) {
+ game.demInfl[space_id] = 0
+ game.comInfl[space_id] = 0
+ } else {
+ game.demInfl[space_id] = 0
+ game.comInfl[S_BUCURESTI] += game.comInfl[space_id]
+ if (game.comInfl[space_id] > 0 ) {
+ log(`${pluralize(game.comInfl[space_id],'Communist SP')} relocated to %${S_BUCURESTI}`)
+ }
+ game.comInfl[space_id] = 0
+ }
+}
+
+function get_adjusted_adjacency(space_id) {
+ let adjacent_spaces = spaces[space_id].adjacent;
+ if (adjacent_spaces.includes(game.systematization)) {
+ let eliminated_space_id = game.systematization;
+ adjacent_spaces = adjacent_spaces.map(adj_space_id => {
+ if (adj_space_id === eliminated_space_id) {
+ return spaces[eliminated_space_id].adjacent;
+ }
+ return adj_space_id;
+ }).flat(); // Flatten in case the eliminated space has multiple adjacencies
+ }
+ adjacent_spaces = adjacent_spaces.filter(s => s !== space_id)
+ return adjacent_spaces;
+}
+
+function vm_exit_visas() {
+ game.state = 'vm_exit_visas'
+}
+
+function vm_foreign_currency_debt_burden() {
+ log('+1VP')
+ game.vp++
+ if (check_vp()) {
+ return
+ }
+ add_to_persistent_events(C_FOREIGN_CURRENCY_DEBT_BURDEN)
+ game.state = 'vm_foreign_currency_debt_burden'
+}
+
+function vm_foreign_television() {
+ for (let i = 0 ; i < spaces.length; i++) {
+ if (i === S_DRESDEN) {continue} /*Does not apply to Dresden*/
+ if (game.comInfl[i] > 0 ) {
+ game.valid_spaces.push(i)
+ }
+ }
+ vm_next()
+}
+function vm_frg_embassies() {
+ add_to_persistent_events(C_FRG_EMBASSIES)
+ logi(`+1 modifier for Democratic Support Checks in Eastern Europe for the rest of this turn`)
+ vm_next()
+}
+
+function vm_general_strike() {
+ add_to_persistent_events(C_GENERAL_STRIKE)
+ logi(`Each Action Round the Communist must instead discard a card and roll a die until the modified die roll exceeds 5`)
+ vm_next()
+}
+
+function vm_genscher() {
+ add_to_persistent_events(C_GENSCHER)
+ logi(`Cancels +1 Ops cost to place Democratic SPs in Communist controlled spaces in East Germany for the rest of the turn`)
+ vm_next()
+}
+
+function vm_goodbye_lenin() {
+ game.view_opp_hand = true
+ game.communist_hand_red = []
+ // Select Red cards to show
+ for (let card of game.communist_hand) {
+ if (cards[card].red) {
+ game.communist_hand_red.push(card)
+ }
+ }
+ //Check if these cards are playable
+ for (let card of game.communist_hand_red) {
+ if (cards[card].playable || game.playable_cards.includes(card)) {
+ game.valid_cards.push(card)
+ }
+ }
+ game.state = 'vm_goodbye_lenin'
+}
+
+function vm_government_resigns() {
+ for (let i = 0; i < spaces.length; i++) {
+ let space = spaces[i]
+ if (space.socio === 1 && game.comInfl[i] > 0 && !check_control(i)) {
+ game.valid_spaces.push(i)
+ }
+ }
+ game.remove_opponent_infl = true
+ vm_next()
+}
+
+function vm_grenztruppen() {
+ add_to_persistent_events(C_GRENZTRUPPEN)
+ logi(`-1 modifier for Democratic Support Checks in East Germany for the rest of this turn`)
+ vm_next()
+}
+
+function vm_heal_our_bleeding_wounds() {
+ let change_vp = 0
+ if (game.turn <= 3) {change_vp = -3 }
+ else if (game.turn <= 7) {change_vp = -1}
+ else change_vp = 3
+ if (change_vp >0) {
+ log(`+${change_vp} VP`)
+ } else {
+ log(`-${change_vp} VP`)
+ }
+ game.vp += change_vp
+ if (check_vp()) {
+ return
+ }
+ vm_next()
+}
+
+function vm_helsinki_final_act() {
+ add_to_persistent_events(C_HELSINKI_FINAL_ACT)
+ logi(`+1 VP for every Support Check by the Communist Player in Student or Intellectual spaces for the rest of the game`)
+ vm_next()
+}
+
+function vm_honecker() {
+ add_to_persistent_events(C_HONECKER)
+ logi(`The Communist may take one extra Action Round this turn`)
+ game.valid_cards = []
+ for (let c of game.strategy_discard) {
+ if (scoring_cards.includes(c)) {
+ continue}
+ else {
+ game.valid_cards.push(c)
+ }
+ }
+ game.discard = true
+ game.state = 'vm_honecker'
+}
+
+function vm_inflationary_currency() {
+ game.state = 'vm_inflationary_currency'
+}
+
+function vm_inflationary_currency_discard() {
+ // This function starts with the player who is playing Inflationary Currency for the Event
+ // Switch player and check the hand of their opponent to see if the have cards with ops > 3 to discard
+ next_player()
+ if (game.active === COM) {
+ for (let card of game.communist_hand){
+ if (get_card_ops(card) >= 3) {
+ game.valid_cards.push(card)
+ }
+ }
+ } else {
+ for (let card of game.democrat_hand){
+ if (get_card_ops(card) >= 3) {
+ game.valid_cards.push(card)
+ }
+ }
+ }
+ game.state = 'vm_inflationary_currency_discard'
+}
+
+function vm_kiss_of_death() {
+ game.state = 'vm_kiss_of_death'
+}
+
+function vm_klaus_and_komarek() {
+ if (game.comInfl[S_PRAHA] > 0 ) {game.valid_spaces = [S_PRAHA]}
+ vm_next()
+}
+
+function vm_kohl_proposes_reunification_prep() {
+ log('+2 VP')
+ game.vp += 2
+ if (check_vp()) {
+ return
+ }
+ vm_next()
+}
+function vm_kohl_proposes_reunification() {
+ game.vm_event = C_KOHL_PROPOSES_REUNIFICATION
+ game.state = 'vm_common_european_home_play'
+}
+
+function vm_kremlin_coup() {
+ log('-3 VP')
+ game.vp -= 3
+ game.stability ++
+ if (check_vp()) {
+ return
+ }
+ game.support_check_modifier = 1
+ game.temp = []
+ countries.forEach(country => {
+ if (!game.revolutions[find_country_index(country)]) {
+ game.temp.push(country)
+ }
+ })
+ game.playable_cards = game.playable_cards.filter(c => c !== C_MALTA_SUMMIT)
+ game.state = 'vm_kremlin_coup_choose_country'
+}
+
+function vm_laszlo_tokes() {
+ add_to_persistent_events(C_LASZLO_TOKES)
+ logi(`Allows play of C${C_MASSACRE_IN_TIMISOARA}`)
+ game.playable_cards.push(C_MASSACRE_IN_TIMISOARA)
+ game.state = 'vm_laszlo_tokes'
+}
+
+function vm_legacy_of_martial_law() {
+ game.vm_available_ops = 1
+ game.state = 'vm_switch_infl'
+}
+
+function vm_legacy_of_1968() {
+ for (let i = 0; i < spaces.length; i++) {
+ let space = spaces[i]
+ if ((!check_com_control(i) && space.country === 'Czechoslovakia')) {
+ game.valid_spaces.push(space.space_id);
+ }
+ }
+ vm_next()
+}
+
+function vm_li_peng() {
+ add_to_persistent_events(C_LI_PENG)
+ logi(`+1 modifier to all Communist Tiananmen Square Track attempts for the rest of the game`)
+ vm_next()
+}
+
+function vm_ligachev() {
+ add_to_persistent_events(C_LIGACHEV)
+ logi(`-3VPs if the Democrat does not play C${C_GORBACHEV_CHARMS_THE_WEST} next Action Round`)
+ vm_next()
+}
+
+function vm_malta_summit() {
+ game.state = 'vm_malta_summit'
+}
+
+function vm_massacre_in_timisoara() {
+ game.persistent_events = game.persistent_events.filter(n => n !== C_LASZLO_TOKES)
+ game.strategy_removed.push(C_LASZLO_TOKES)
+ vm_next()
+}
+
+function vm_modrow() {
+ game.playable_cards = game.playable_cards.filter(n => n !== C_HONECKER)
+ add_to_persistent_events(C_MODROW)
+ logi(`Prevents play of C${C_HONECKER} for the event`)
+ game.state = 'vm_modrow'
+}
+
+function vm_nagy_reburied(){
+ if (game.comInfl[S_SZOMBATHELY] > 0) {
+ game.valid_spaces.push(S_SZOMBATHELY)
+ }
+ vm_next()
+}
+
+function vm_national_salvation_front() {
+ add_to_persistent_events(C_NATIONAL_SALVATION_FRONT)
+ logi(`In the next Power Struggle in the Balkans, the Communist draws 2 random Power Struggle cards from the Democrat hand`)
+ vm_next()
+}
+
+function vm_nepotism() {
+ game.state = 'vm_nepotism'
+}
+
+function vm_new_years_eve_party() {
+ game.state = 'vm_new_years_eve_party'
+}
+
+function vm_nomenklatura() {
+ game.state = 'vm_nomenklatura'
+}
+
+function vm_normalization() {
+ if (game.demInfl[S_PLZEN] >0) {game.valid_spaces.push(S_PLZEN)}
+ if (game.demInfl[S_PRAHA] > 0) {game.valid_spaces.push(S_PRAHA)}
+ game.remove_opponent_infl = true
+ vm_next()
+}
+
+function vm_peasant_parties_revolt() {
+ add_to_persistent_events(C_PEASANT_PARTIES_REVOLT)
+ logi(`In the next Power Stuggle, if the Democrat controls a Farmer space draw 1 Power Struggle card at random from the Communist hand`)
+ vm_next()
+}
+
+function vm_perestroika() {
+ add_to_persistent_events(C_PERESTROIKA)
+ logi(`+1 Ops value for cards played by the Communist for the rest of this turn`)
+ vm_next()
+}
+
+function vm_poszgay() {
+ let valid_spaces = []
+ for (let space of spaces) {
+ if (space && space.country === 'Hungary' && !check_dem_control(space.space_id)) {
+ valid_spaces.push(space.space_id);
+ }
+ }
+ game.valid_spaces = valid_spaces
+ vm_next()
+}
+
+function vm_power_struggle() {
+ game.is_pwr_struggle = true
+ game.phase = 0
+ game.raised_stakes = 0
+ game.raised_stakes_round = 0
+ game.raised_stakes_discard = 0
+ game.pwr_struggle_in = countries[scoring_cards.indexOf(game.vm_event)]
+ log_h2(`C${game.vm_event}`)
+
+ //Check for Securitate
+ if (game.pwr_struggle_in === 'Romania' && game.persistent_events.includes(C_SECURITATE)) {
+ log(`C${C_SECURITATE}: Democrat reveals Power Struggle cards`)
+ game.opp_power_hand = true
+ }
+ log_h2('Deal Cards')
+ game.state = 'draw_power_cards'
+}
+
+function vm_presidential_visit() {
+ add_to_persistent_events(C_PRESIDENTIAL_VISIT)
+ logi(`Communist hand size is reduced to 7 next turn`)
+ vm_next()
+}
+
+function vm_prudence() {
+ if (!game.prudence) {
+ game.prudence = {DEM: 0, COM: 0}
+ }
+ if (game.active === DEM) {
+ game.prudence.COM --
+ log(`${game.prudence.COM} to Communist Ops this turn`)
+ } else {
+ game.prudence.DEM --
+ log(`${game.prudence.DEM} to Democrat Ops this turn`)}
+ vm_next()
+}
+
+function vm_public_against_violence() {
+ game.valid_spaces = []
+ if (game.comInfl[S_BRATISLAVA] > 0 ) {game.valid_spaces.push(S_BRATISLAVA)}
+ vm_next()
+}
+
+function vm_reformer_rehabilitated () {
+ permanently_remove(C_REFORMER_REHABILITATED)
+ game.discard = true
+ for (let card of game.strategy_discard) {
+ if (!event_is_playable(card)) continue
+ if (card === game.played_card) continue
+ if (card === C_COMMON_EUROPEAN_HOME) continue
+ if (scoring_cards.includes(card)) continue
+
+ game.valid_cards.push(card)
+ }
+ game.state = 'vm_play_event_from_discard'
+}
+
+function vm_roundtable_talks() {
+ add_to_persistent_events(C_ROUNDTABLE_TALKS)
+ logi(`In the next Power Struggle the Democrat draws 2 random Power Struggle cards from the Communist hand`)
+ vm_next()
+}
+
+function vm_sajudis_check() {
+ if (!check_dem_control(S_RAZGRAD)) {
+ game.valid_spaces.push(S_RAZGRAD)
+ }
+ if (!check_dem_control(S_HARGHITA_COVASNA)) {
+ game.valid_spaces.push(S_HARGHITA_COVASNA)
+ }
+ vm_next()
+}
+
+function vm_sajudis() {
+ game.playable_cards.push(C_THE_BALTIC_WAY)
+ game.stability++
+ log('+1 VP')
+ game.vp++
+ if (check_vp()) {
+ return
+ }
+ log(`Allows play of C${C_THE_BALTIC_WAY} for the event`)
+ vm_next()
+}
+
+function vm_samizdat() {
+ game.state = 'vm_samizdat'
+}
+
+function vm_securitate() {
+ add_to_persistent_events(C_SECURITATE)
+ logi(`The Democrat must reveal their Power Struggle cards at the start of Power Struggles in Romania`)
+ vm_next()
+}
+
+function vm_shock_therapy() {
+ game.state = 'vm_shock_therapy'
+}
+
+function vm_social_democratic_platform_adopted() {
+ game.state = 'vm_social_democratic_platform_adopted'
+}
+
+function vm_solidarity_legalised() {
+ game.playable_cards.push(C_WALESA)
+ add_to_persistent_events(C_SOLIDARITY_LEGALIZED)
+ logi(`Allows play of C${C_WALESA}`)
+ vm_next()
+}
+
+function vm_st_nicholas_church () {
+ add_to_persistent_events(C_ST_NICHOLAS_CHURCH)
+ logi(`Allows play of C${C_THE_MONDAY_DEMONSTRATIONS}`)
+ game.playable_cards.push(C_THE_MONDAY_DEMONSTRATIONS)
+ vm_next()
+}
+
+function vm_stasi() {
+ add_to_persistent_events(C_STASI)
+ logi(`For the rest of this turn the Democrat must reveal the card they will play this Action Round before the Communist player plays a card`)
+ vm_next()
+}
+
+function vm_stand_fast() {
+ add_to_persistent_events(C_STAND_FAST)
+ if (game.active === DEM) {
+ logi(`-1 Modifier to Support Checks in Democratic controlled spaces for the rest of this turn`)
+ game.stand_fast = DEM
+ } else {
+ logi(`-1 Modifier to Support Checks in Communist controlled spaces for the rest of this turn`)
+ game.stand_fast = COM}
+ vm_next()
+}
+
+function vm_systematization() {
+ game.state = 'vm_systematization'
+}
+
+function vm_tank_column() {
+ if (game.active === DEM) {
+ game.dem_tst_position++
+ game.dem_tst_attempted = 0
+ } else {
+ game.com_tst_position++
+ game.com_tst_attempted = 0
+ }
+ // Check if TST Awards occur
+ if (game.active === DEM) {
+ if (game.dem_tst_position === 3 && game.com_tst_position < 3) {
+ game.vm_event = 203
+ goto_vm(game.vm_event)
+ return
+ }
+ else if (game.dem_tst_position === 4 && game.com_tst_position < 4) {
+ game.vm_event = 204
+ goto_vm(game.vm_event)
+ return
+ }
+
+ } else {
+ if (game.com_tst_position === 3 && game.dem_tst_position < 3) {
+ game.vm_event = 203
+ goto_vm(game.vm_event)
+ return
+ }
+ else if (game.com_tst_position === 4 && game.dem_tst_position < 4) {
+ game.vm_event = 204
+ goto_vm(game.vm_event)
+ return
+ }
+ }
+ vm_next()
+}
+
+function vm_tear_gas () {
+ add_to_persistent_events(C_TEAR_GAS)
+ logi(`+1 modifier to the next Communist Support Check in a Student space`)
+ vm_next()
+}
+
+function vm_the_baltic_way_prep() {
+ game.playable_cards.push(C_BREAKAWAY_BALTIC_REPUBLICS)
+ game.stability++
+ log('+3 VP')
+ game.vp += 3
+ if (check_vp()) {
+ return
+ }
+ log(`Allows play of C${C_BREAKAWAY_BALTIC_REPUBLICS} for the event`)
+ vm_next()
+}
+
+function vm_the_baltic_way() {
+ if (!check_dem_control(S_HARGHITA_COVASNA) && game.systematization !== S_HARGHITA_COVASNA) {game.valid_spaces.push(S_HARGHITA_COVASNA)}
+ if (!check_dem_control(S_RAZGRAD) ) {game.valid_spaces.push(S_RAZGRAD)}
+ vm_next()
+}
+
+function vm_the_chinese_solution() {
+ game.state = 'vm_the_chinese_solution'
+}
+
+function vm_the_crowd_turns_against_ceausescu() {
+ add_to_persistent_events(C_THE_CROWD_TURNS_AGAINST_CEAUSESCU)
+ logi(`Power Struggle: Romania. Democrat draws 15 Power Struggle cards and takes 1 Action Round using Ops 3 times the number of Rallies. Allows play of C${C_THE_TYRANT_IS_GONE}`)
+ game.playable_cards.push(C_THE_TYRANT_IS_GONE)
+ vm_next()
+}
+
+function vm_the_monday_demonstrations() {
+ if (!check_dem_control(S_LUTHERAN_CHURCH)) {game.valid_spaces.push(S_LUTHERAN_CHURCH)}
+ if (!check_dem_control(S_LEIPZIG)) {game.valid_spaces.push(S_LEIPZIG)}
+ vm_next()
+}
+
+function vm_the_sinatra_doctrine() {
+ add_to_persistent_events(C_THE_SINATRA_DOCTRINE)
+ logi(`+1 Ops value for cards played by the Democrat for the rest of this turn`)
+ vm_next()
+}
+
+function vm_the_third_way() {
+ log('-2VP')
+ game.vp -= 2
+ if (check_vp()) {
+ return
+ }
+ vm_next()
+}
+
+function vm_the_tyrant_is_gone() {
+ permanently_remove(C_THE_CROWD_TURNS_AGAINST_CEAUSESCU)
+ game.persistent_events.push(THE_TYRANT_IS_GONE_OCCURRED)
+ game.valid_spaces = []
+ for (let i = 0; i < spaces.length; i++) {
+ let space = spaces[i]
+ if (game.demInfl[i] === 0 && space.country === 'Romania') {
+ if (space.space_id === game.systematization) {continue}
+ game.valid_spaces.push(space.space_id)
+ }
+ }
+ game.state = 'vm_the_tyrant_is_gone'
+}
+
+function vm_the_tyrant_is_gone_prep() {
+ add_to_persistent_events(C_THE_TYRANT_IS_GONE)
+ logi(`After C${C_THE_CROWD_TURNS_AGAINST_CEAUSESCU} occurs, remove 4 Commuist SPs from the Romanian Elite space. The Democrats choose where the Ceausescus flee to`)
+ vm_next()
+}
+
+function vm_tyrant_block() {
+ logi(`Has no effect after C${C_THE_TYRANT_IS_GONE}`)
+ vm_next()
+}
+
+function vm_the_wall () {
+ add_to_persistent_events(C_THE_WALL)
+ logi(`Cancels the modifier for any Democratic controlled spaces for the next Communist Support Check in East Germany`)
+ vm_next()
+}
+
+function vm_the_wall_must_go() {
+ game.the_wall_must_go = {}
+ game.the_wall_must_go['dem_wins'] = 0
+ game.the_wall_must_go['com_wins'] = 0
+ game.the_wall_must_go['dem_roll'] = 0
+ game.the_wall_must_go['com_roll'] = 0
+ game.state = 'vm_the_wall_must_go'
+}
+
+function vm_warsaw_pact_summit() {
+ game.state = 'vm_warsaw_pact_summit'
+}
+
+function vm_we_are_the_people() {
+ if (game.demInfl[S_LUTHERAN_CHURCH] > 0) {game.valid_spaces = [S_LUTHERAN_CHURCH]}
+ add_to_persistent_events(C_WE_ARE_THE_PEOPLE)
+ logi(`The Communist may no longer make Support Checks in Leipzig`)
+ if (!game.vm_influence_added) {
+ game.vm_influence_added = {};
+ }
+ game.vm_influence_added[S_LUTHERAN_CHURCH] = 0
+ game.vm_available_ops = 4
+ game.state = 'vm_we_are_the_people_remove'
+}
+
+function vm_workers_revolt() {
+ if (game.active === DEM) {
+ for (let space of spaces) {
+ let country = space.country
+ if (!game.revolutions[find_country_index(country)] && game.comInfl[space.space_id] > 0 && space.socio === 4) {
+ game.valid_spaces.push(space.space_id);
+ }
+ }
+ } else {
+ for (let space of spaces) {
+ let country = space.country
+ if (game.revolutions[find_country_index(country)] && game.demInfl[space.space_id] > 0 && space.socio === 4) {
+ game.valid_spaces.push(space.space_id);
+ }
+ }
+ }
+ game.state = 'vm_workers_revolt'
+}
+
+function vm_yakovlev_counsels_gorbachev() {
+ add_to_persistent_events(C_YAKOVLEV_COUNSELS_GORBACHEV)
+ logi(`The Democrat receives a +1 modifier to the Support Loss and Victory Point die rolls if they wins the next Power Struggle`)
+ vm_next()
+}
+
+function vm_permanently_remove () {
+ // Check if the event is being played as the result of another card, e.g. Dash for the West, is a card which should be removed, and which hasn't already been removed!
+ if (game.vm_event !== 0 && cards[game.vm_event].remove && !game.strategy_removed.includes(game.vm_event)) {
+ permanently_remove(game.vm_event)
+ }
+ if (cards[game.played_card].remove && !game.strategy_removed.includes(game.played_card)) {
+ permanently_remove(game.played_card)
+ } /*This means the card that called the event being played is also removed if relevant. Think this makes sense */
+ vm_next()
+}
+
+function discarded_card() {
+ return game.temp > 0
+}
+
+// =================== TIANANMEN SQUARE TRACK FUNCTIONS ====================
+
+function vm_tst_3() {
+ log_gap('Tiananmen Square Track Award')
+ game.state = 'vm_tst_3_prep'
+}
+
+function vm_tst_4() {
+ log_gap('Tiananmen Square Track Award')
+ game.vm_available_ops = 2
+ game.remove_opponent_infl = true
+ game.state = 'vm_tst_4'
+}
+function vm_tst_6() {
+ log_h3('Tiananmen Square Track Award')
+ game.vm_available_ops = 1
+ game.temp = 1 //Set temp to 1, so that Card 1 is called during the support check, which has 2 ops
+ game.state = 'vm_tst_6'
+}
+
+function vm_tst_8() {
+ game.state = 'vm_goodbye_lenin_ops' // Use this to resolve ops.
+}
+
+// ==================== POWER STRUGGLE FUNCTIONS ======================
+
+function vm_scare_tactics() {
+ game.vm_active_country = game.pwr_struggle_in
+ vm_next()
+}
+function vm_support_surges() {
+ game.state = 'vm_support_surges_1'
+}
+
+function vm_support_falters() {
+ game.vm_available_ops = 2
+ game.return === game.active
+ log(`P${PC_SUPPORT_FALTERS}:`)
+ game.state = 'vm_support_falters'
+}
+
+function vm_kremlin_coup_elite() {
+ game.valid_spaces=[]
+ elite_spaces.forEach(space => {
+ if (spaces[space].country === game.vm_active_country && !check_com_control(space)) {
+ game.valid_spaces.push(space);
+ }
+ })
+ game.state = 'vm_kremlin_coup_take_control'
+}
+
+/* ================== VM STATES ============================== */
+
+states.vm_end_event = {
+ get inactive() {
+ return `resolve ${clean_name(cards[this_card()].name)}.`
+ },
+ prompt () {
+ view.prompt = `${clean_name(cards[this_card()].name)}: done.`
+ if (game.vm_infl_to_do || game.return_state === 'vm_tst_8') {
+ gen_action('done')
+ } else {
+ gen_action('end_round')
+ }
+ },
+ done() {
+ push_undo()
+ vm_end_event()
+ },
+ end_round() {
+ push_undo()
+ game.return_state = ''
+ vm_end_event()
+ }
+}
+
+states.vm_take_control = {
+ get inactive() {
+ return `resolve ${clean_name(cards[game.played_card].name)}.`
+ },
+ prompt () {
+ if (game.vm_available_ops > 0 && game.valid_spaces.length === 0) {
+ view.prompt = `${clean_name(cards[this_card()].name)}: all spaces controlled. Continue.`
+ gen_action('done')
+ } else if (game.vm_available_ops > 0 ) {
+ view.prompt = `${clean_name(cards[this_card()].name)}: take control of ${event_prompt()}.`
+ for (let space_id of game.valid_spaces) {
+ gen_action_space(space_id);
+ }
+ } else {
+ view.prompt = `${clean_name(cards[this_card()].name)}. Take control: done.`
+ if (game.vm_infl_to_do) {
+ gen_action('done')
+ } else {
+ gen_action('end_round')
+ }
+ }
+ },
+ space(space) {
+ push_undo()
+ vm_take_control(space)
+ game.vm_available_ops--
+ if (game.vm_available_ops === 0) {
+ game.valid_spaces = []
+ vm_next()
+ }
+ },
+ done() {
+ push_undo()
+ vm_next()
+ },
+ end_round() {
+ push_undo()
+ vm_next()
+ }
+}
+
+states.vm_add_infl = {
+ inactive: 'add Support Points.',
+ prompt () {
+ if (game.vm_available_ops > 0 && game.valid_spaces.length === 0 ) {
+ view.prompt = `${clean_name(cards[this_card()].name)}. No available spaces remaining. Add SPs: done.`
+ gen_action('done')
+ }
+ else if (game.vm_available_ops > 0 ) {
+ view.prompt = `${clean_name(cards[this_card()].name)}: add ${pluralize(game.vm_available_ops,'SP')}${event_prompt()}.`
+
+ for (let space_id of game.valid_spaces) {
+ gen_action_space(space_id)
+ }
+ } else {
+ get_end_infl_prompt()
+ }
+ },
+ space(space) {
+ add_infl(space, 'vm_available_ops')
+ if (game.vm_available_ops === 0) {
+ game.valid_spaces = []
+ do_log_summary()
+ game.vm_event_done = true
+ vm_next()
+ }
+ },
+ done () {
+ push_undo()
+ do_log_summary()
+ game.vm_event_done = true
+ vm_next()
+ },
+ end_round() {
+ push_undo()
+ do_log_summary()
+ game.vm_event_done = true
+ vm_next()
+ }
+}
+
+states.vm_add_infl_free = {
+ get inactive() {
+ return `resolve ${clean_name(cards[this_card()].name)}: add SPs.`
+ },
+ prompt () {
+ if (game.vm_available_ops > 0 && game.valid_spaces.length === 0 ) {
+ view.prompt = `${clean_name(cards[this_card()].name)}. No available spaces remaining. Add SPs: done.`
+ gen_action('done')
+ } else if (game.vm_available_ops > 0 ) {
+ view.prompt = `${clean_name(cards[this_card()].name)}: add ${game.vm_available_ops} SPs to ${event_prompt()}.`
+
+ for (let space_id of game.valid_spaces) {
+ gen_action_space(space_id);
+ }
+ } else {
+ get_end_infl_prompt()
+ }
+ },
+ space(space) {
+ vm_do_add_infl_free(space)
+ if (game.vm_available_ops === 0) {
+ game.valid_spaces = []
+ do_log_summary()
+ game.vm_event_done = true
+ vm_next()
+ }
+ },
+ done () {
+ push_undo()
+ game.valid_spaces = []
+ game.vm_event_done = true
+ do_log_summary()
+ vm_next()
+ },
+ end_round () {
+ push_undo()
+ game.valid_spaces = []
+ game.vm_event_done = true
+ do_log_summary()
+ vm_next()
+ }
+}
+
+states.vm_add_x_infl = {
+ get inactive() {
+ return `resolve ${clean_name(cards[this_card()].name)}: add Support Points.`
+ },
+ prompt () {
+ if (game.vm_event === 101 && game.valid_spaces.length === 0) {
+ view.prompt = `${clean_name(cards[this_card()].name)}: the Romanian Elite space no longer exists.`
+ gen_action('done')
+ }
+ else if (game.vm_available_ops > 0 ) {
+ view.prompt = `${clean_name(cards[this_card()].name)}: Add ${game.vm_available_ops} SPs to ${event_prompt()}.`
+
+ for (let space_id of game.valid_spaces) {
+ gen_action_space(space_id)
+ }
+ }
+ },
+ space(space) {
+ push_undo()
+ vm_do_add_x_infl(space)
+ if (game.vm_available_ops === 0) {
+ game.vm_event_done = true
+ vm_next()
+ }
+ },
+ done () {
+ push_undo()
+ game.vm_event_done = true
+ vm_next()
+ }
+}
+
+states.vm_add_limited_infl = {
+ get inactive() {
+ return `resolve ${clean_name(cards[this_card()].name)}: add Support Points.`
+ },
+ prompt () {
+ if (game.vm_available_ops > 0 && game.valid_spaces.length > 0) {
+ if (game.vm_max_infl === 1) {
+ view.prompt = `${clean_name(cards[this_card()].name)}: add ${pluralize(game.vm_max_infl,'SP')} ${event_prompt()}.`
+ }
+ else {
+ view.prompt = `${clean_name(cards[this_card()].name)}: add ${pluralize(game.vm_available_ops,'SP')} to ${event_prompt()}.`
+ }
+ for (let space_id of game.valid_spaces) {
+ gen_action_space(space_id);
+ }
+ }
+ },
+ space(space) {
+ vm_do_add_limited_infl(space, game.vm_max_infl)
+ if (game.vm_available_ops === 0 || game.valid_spaces.length === 0) {
+ game.valid_spaces = []
+ do_log_summary()
+ game.vm_event_done = true
+ vm_next()
+ }
+ },
+}
+
+states.vm_remove_infl = {
+ inactive: 'remove Support Points.',
+ prompt () {
+ // Keep this so that there is an undo option in, e.g., Scare Tactics
+ if (game.valid_spaces.length === 0 && game.vm_available_ops > 0) {
+ view.prompt = `${clean_name(cards[this_card()].name)}: no further SPs to remove.`
+ gen_action('done')
+ return
+ }
+ if (game.vm_available_ops === 0 ) {
+ view.prompt = `${clean_name(cards[this_card()].name)}. Remove SPs: done.`
+ gen_action('done')
+ return
+ }
+ if (game.remove_opponent_infl) {
+ view.prompt = `${clean_name(cards[this_card()].name)}: remove ${pluralize(game.vm_available_ops, 'opponent SP')}${event_prompt()}.`
+ }
+ else {
+ view.prompt = `${clean_name(cards[this_card()].name)}: remove ${pluralize(game.vm_available_ops,'SP')}${event_prompt()}.`
+ }
+ for (let space_id of game.valid_spaces) {
+ gen_action_space(space_id);
+ }
+ },
+ space(space) {
+ remove_infl(space, 'vm_available_ops')
+ game.vm_active_country = spaces[space].country
+ let require_done = [C_INFLATIONARY_CURRENCY, C_THE_WALL_MUST_GO]
+ if (!require_done.includes(game.vm_event)) {
+ if (game.vm_available_ops === 0 ) {
+ do_log_summary()
+ vm_next()
+ }
+ }
+ },
+ done() {
+ if (game.summary.length > 0) {
+ pop_summary()
+ log_br()
+ } else {
+ log('No influence to remove')
+ }
+ vm_next()
+ }
+}
+
+
+states.vm_remove_x_infl = {
+ get inactive() {
+ return `resolve ${clean_name(cards[this_card()].name)}: remove SP from ${event_prompt()}.`
+ },
+ prompt () {
+ if (game.valid_spaces.length === 0 && game.vm_available_ops > 0) {
+ view.prompt = `${clean_name(cards[this_card()].name)}: no SPs to remove.`
+ gen_action('done')
+ } else if (game.vm_available_ops > 0) {
+
+ view.prompt = `${clean_name(cards[this_card()].name)}: remove ${pluralize(game.vm_available_ops,'SP')} from ${event_prompt()}.`
+ for (let space_id of game.valid_spaces) {
+ gen_action_space(space_id);
+ }
+ }
+ },
+ space(space) {
+ vm_do_remove_x_infl(space)
+ if (game.vm_available_ops === 0) {
+ game.vm_event_done = true
+ vm_next()
+ }
+ },
+ done () {
+ game.vm_event_done = true
+ vm_next()
+ }
+}
+
+states.vm_remove_limited_infl = {
+ inactive: 'remove SP.',
+ prompt () {
+ if (game.vm_available_ops > 0 && game.valid_spaces.length > 0) {
+ view.prompt = `${clean_name(cards[this_card()].name)}: remove ${pluralize(game.vm_available_ops,'SP')}${event_prompt()}, no more than ${game.vm_max_infl} per space.`
+
+ for (let space_id of game.valid_spaces) {
+ gen_action_space(space_id);
+ }
+ } else if (game.valid_spaces.length === 0 && game.vm_available_ops > 0) {
+ view.prompt = `${clean_name(cards[this_card()].name)}: no further SP to remove.`
+ gen_action('done')
+ }
+ },
+ space(space) {
+ vm_do_remove_limited_infl(space, game.vm_max_infl)
+ if (game.vm_available_ops === 0) {
+ game.vm_event_done = true
+ do_log_summary()
+ vm_next()
+ }
+ },
+ done () {
+ game.vm_event_done = true
+ do_log_summary()
+ vm_next()
+ }
+}
+
+states.vm_remove_all_infl = {
+ inactive: 'remove Support Points',
+ prompt () {
+ if (game.valid_spaces.length === 0 && game.vm_available_ops > 0) {
+ view.prompt = `${clean_name(cards[this_card()].name)}: no SPs to remove.`
+ gen_action('pass')
+ } else if (game.vm_available_ops > 0) {
+ view.prompt = `${clean_name(cards[this_card()].name)}: remove all SPs from ${event_prompt()}.`
+ for (let space_id of game.valid_spaces) {
+ gen_action_space(space_id);
+ }
+ }
+ },
+ space(space) {
+ vm_do_remove_all_infl(space)
+ game.vm_active_country = spaces[space].country
+ if (game.vm_available_ops === 0) {
+ vm_next()
+ }
+ },
+ pass() {
+ push_undo()
+ vm_next()
+ }
+}
+
+states.vm_support_check_prep = {
+ inactive: 'do support checks.',
+ prompt () {
+ if (game.valid_spaces.length === 0) {
+ view.prompt = `${clean_name(cards[this_card()].name)}: no valid targets for support check.`
+ gen_action('done')
+ } else {
+ view.prompt = `${clean_name(cards[this_card()].name)}: ${event_prompt()}. ${pluralize(game.vm_available_ops, 'support check')} remaining.`
+ for (let space_id of game.valid_spaces) {
+ gen_action_space(space_id);
+ }
+ }
+ },
+ space(space) {
+ push_undo()
+ game.selected_space = space
+
+ // Check for Austria-Hungary Border Reopened - check on first support check only
+ //First check for Monday Demonstrations - support checks will always be in East Germany
+ if (game.vm_event === C_THE_MONDAY_DEMONSTRATIONS && game.persistent_events.includes(C_AUSTRIA_HUNGARY_BORDER_REOPENED)) {
+ game.austria_hungary_border_reopened_tracker = true
+ game.state = 'vm_do_support_check'
+ return
+ }
+
+ //Then check Austria-Hungary Border Reopened normally
+ if (game.persistent_events.includes(C_AUSTRIA_HUNGARY_BORDER_REOPENED)) {
+ if (game.active === DEM && game.vm_available_ops > 1) {
+ if (spaces[game.selected_space].country === 'East_Germany' && game.persistent_events.includes(C_AUSTRIA_HUNGARY_BORDER_REOPENED) && game.active === DEM) {
+ game.state = 'vm_austria_hungary_border_reopened_check'
+ return
+ }
+ }
+ }
+ game.state = 'vm_do_support_check'
+ },
+ done () {
+ push_undo()
+ game.vm_available_ops = 0
+ vm_next ()
+ }
+}
+
+states.vm_ceh_support_check_prep = {
+ inactive: 'do support checks.',
+ prompt () {
+ if (game.vm_available_ops > 0) {
+ view.prompt = `Select a space. ${pluralize(game.vm_available_ops, 'support check')} remaining.`
+
+ for (let space_id of game.valid_spaces) {
+ gen_action_space(space_id)
+ }
+ }
+ },
+ space(space) {
+ push_undo()
+ game.selected_space = space
+
+ //Then check Austria-Hungary Border Reopened normally
+ if (game.persistent_events.includes(C_AUSTRIA_HUNGARY_BORDER_REOPENED)) {
+ if (game.active === DEM && game.vm_available_ops > 1) {
+ if (spaces[game.selected_space].country === 'East_Germany' && game.persistent_events.includes(58) && game.active === DEM) {
+ game.state = 'vm_austria_hungary_border_reopened_check'
+ return
+ }
+ }
+ }
+ game.state = 'vm_ceh_do_support_check'
+ },
+}
+
+
+states.vm_ceh_do_support_check = {
+ inactive: 'do support checks.',
+ prompt () {
+ view.prompt = `Support check: ${spaces[game.selected_space].name_unique}. Roll a die.`
+ gen_action('roll')
+ },
+ roll() {
+ clear_undo()
+ do_sc(game.selected_space)
+ game.vm_available_ops--
+ if (game.vm_available_ops === 0) {
+ game.valid_spaces = []
+ vm_next()
+ } else {
+ game.state = 'vm_ceh_support_check_prep'
+ return
+ }
+ }
+}
+
+states.vm_austria_hungary_border_reopened_check = {
+ inactive: 'decide Austria-Hungary Border Reopened',
+ prompt() {
+ view.prompt = 'Austria-Hungary Border Reopened: will all support checks be in East Germany?'
+ gen_action('yes')
+ gen_action('no')
+ },
+ yes() {
+ game.austria_hungary_border_reopened_tracker = true
+ game.state = 'vm_do_support_check'
+ },
+ no() {
+ game.state = 'vm_do_support_check'
+ }
+}
+
+states.vm_1_support_check_prep = {
+ inactive: 'do support checks.',
+ prompt () {
+ if (game.valid_spaces.length === 0) {
+ view.prompt = `${clean_name(cards[this_card()].name)}: no valid targets for support check.`
+ gen_action('done')
+ } else {
+ view.prompt = `${clean_name(cards[this_card()].name)}: ${event_prompt()}.`
+ for (let space_id of game.valid_spaces) {
+ gen_action_space(space_id);
+ }
+ }
+ },
+ space(space) {
+ push_undo()
+ game.selected_space = space
+ game.state = 'vm_do_support_check'
+ },
+ done () {
+ push_undo()
+ game.vm_available_ops = 0
+ vm_next ()
+ }
+}
+
+states.vm_do_support_check = {
+ inactive: 'do support checks.',
+ prompt () {
+ view.prompt = `Support check: ${spaces[game.selected_space].name_unique}. Roll a die.`
+ gen_action('roll')
+ },
+ roll() {
+ clear_undo()
+ do_sc(game.selected_space)
+ game.vm_available_ops--
+ if (check_vp()) {
+ return
+ } else if (game.vm_available_ops === 0) {
+ game.valid_spaces = []
+ vm_next()
+ return
+ } else {
+ game.state = 'vm_support_check_prep'
+ return
+ }
+ }
+}
+
+states.vm_tiananmen_square_attempt = {
+ inactive: 'do Tiananmen Square',
+ prompt () {
+ view.prompt = 'Tiananmen Square: roll a die'
+ gen_action('roll')
+ },
+ roll() {
+ clear_undo()
+ do_tst_attempt ()
+ },
+}
+
+//================================== EVENT SPECIFIC STATES ======================================
+
+states.vm_adamec = {
+ get inactive() {
+ return `resolve ${clean_name(cards[C_ADAMEC].name)}.`
+ },
+ prompt() {
+ view.prompt = 'Adamec: roll a die.'
+ gen_action('roll')
+ },
+ roll() {
+ clear_undo()
+ let roll = roll_d6()
+ log(`Roll: D${roll}`)
+ let worker_spaces = spaces.filter(space => space && space.country === 'Czechoslovakia' && space.socio === 4 && check_dem_control(space.space_id)).length
+ if (worker_spaces > 0) {
+ logi(`-${worker_spaces} from Democrat controlled worker spaces`)
+ roll -= worker_spaces
+ }
+ log(`Modified roll: ${Math.max(roll, 0)}`)
+ if (roll > 2) {
+ log_msg_gap('Adamec succeeds')
+ vm_next()
+ return
+ }
+ log('Adamec fails: 3 or more required')
+ permanently_remove(C_ADAMEC)
+ vm_return()
+ }
+}
+
+states.vm_brought_in_for_questioning = {
+ inactive: 'discard a card.',
+ prompt() {
+ if (game.democrat_hand.length === 0) {
+ view.prompt = 'Brought in for Questioning. No cards to discard.'
+ gen_action('pass')
+ } else {
+ view.prompt = 'Brought in for Questioning: you must discard a random card.'
+ gen_action('discard')
+ }
+ },
+ discard() {
+ clear_undo()
+ log(`C${C_BROUGHT_IN_FOR_QUESTIONING}:`)
+ game.vm_event = discard_card(game.democrat_hand)
+ game.phase = 1
+ if (cards[game.vm_event].side === 'C' && (cards[game.vm_event].playable || game.playable_cards.includes(game.vm_event))) {
+ if (!game.vm_infl_to_do) {
+ if(game.round_player === DEM) {
+ game.return = COM
+ } else {
+ game.return = DEM
+ }
+ }
+ if (!is_auto_resolve(game.vm_event) && !switch_events.includes(game.vm_event)) {
+ next_player()
+ }
+ log(`C${game.vm_event}:`)
+ goto_vm(game.vm_event)
+ } else {
+ logi('Event does not occur')
+ game.return = DEM
+ vm_return()
+ }
+ },
+ pass() {
+ log('No cards to discard')
+ vm_return()
+ },
+}
+
+states.vm_central_committee_reshuffle = {
+ get inactive() {
+ return `resolve ${clean_name(cards[C_CENTRAL_COMMITTEE_RESHUFFLE].name)}.`
+ },
+ prompt() {
+ if (game.revolutions.every(n => n === true)) {
+ view.prompt = 'Central Committee Reshuffle: no countries to choose.'
+ gen_action('pass')
+ } else {
+ view.prompt = 'Central Committee Reshuffle: choose a country to add SPs.'
+ if (!game.revolutions[0]) {gen_action('poland')}
+ if (!game.revolutions[1]) {gen_action('hungary')}
+ if (!game.revolutions[2]) {gen_action('east_germany')}
+ if (!game.revolutions[3]) {gen_action('bulgaria')}
+ if (!game.revolutions[4]) {gen_action('czechoslovakia')}
+ if (!game.revolutions[5]) {gen_action('romania')}
+ }
+ },
+ east_germany() {
+ push_undo()
+ game.vm_active_country = "East_Germany"
+ log(`Chose ${country_name(game.vm_active_country)}`)
+ game.valid_spaces = [...S_EAST_GERMANY]
+ vm_next()
+ },
+ poland() {
+ push_undo()
+ game.vm_active_country = "Poland"
+ log(`Chose ${country_name(game.vm_active_country)}`)
+ game.valid_spaces = [...S_POLAND]
+ vm_next()
+ },
+ czechoslovakia() {
+ push_undo()
+ game.vm_active_country = "Czechoslovakia"
+ log(`Chose ${country_name(game.vm_active_country)}`)
+ game.valid_spaces = [...S_CZECHOSLOVAKIA]
+ vm_next()
+ },
+ hungary() {
+ push_undo()
+ game.vm_active_country = "Hungary"
+ log(`Chose ${country_name(game.vm_active_country)}`)
+ game.valid_spaces = [...S_HUNGARY]
+ vm_next()
+ },
+ romania() {
+ push_undo()
+ game.vm_active_country = "Romania"
+ log(`Chose ${country_name(game.vm_active_country)}`)
+ game.valid_spaces = [...S_ROMANIA]
+ game.valid_spaces = game.valid_spaces.filter(space => space !== game.systematization)
+ vm_next()
+ },
+ bulgaria () {
+ push_undo()
+ game.vm_active_country = "Bulgaria"
+ log(`Chose ${country_name(game.vm_active_country)}`)
+ game.valid_spaces = [...S_BULGARIA]
+ vm_next()
+ },
+ pass() {
+ log('Passed')
+ vm_return()
+ }
+}
+
+states.vm_common_european_home_choose = {
+ get inactive() {
+ return `resolve ${clean_name(cards[game.played_card].name)}.`
+ },
+ prompt() {
+ view.prompt = `Common European Home: play an opponent's card, event does not occur.`
+ for (let card of game.valid_cards) {
+ gen_action_card(card)
+ }
+ },
+ card(card) {
+ push_undo()
+ game.valid_cards = []
+ silent_discard(card)
+ game.vm_event = card
+ game.state = 'vm_common_european_home_play'
+ }
+}
+
+states.vm_common_european_home_play = {
+ get inactive() {
+ return `resolve ${clean_name(cards[this_card()].name)}.`
+ },
+ prompt() {
+ view.prompt = `Play ${clean_name(cards[this_card()].name)} for:`
+ gen_action('influence')
+ gen_action('support_check')
+ if (game.active === DEM && game.vm_event === C_KOHL_PROPOSES_REUNIFICATION ) {
+ return /*Special condition if card is actually Kohl Proposes Reunification*/
+ }
+ },
+ influence(){
+ push_undo()
+ log_gap(`Played C${game.vm_event} to place SPs`)
+ game.vm_available_ops = get_card_ops(game.vm_event)
+ valid_spaces_infl()
+ // If ABHR - Set AHBR tracker to true
+ if (game.persistent_events.includes(C_AUSTRIA_HUNGARY_BORDER_REOPENED)) {
+ game.austria_hungary_border_reopened_tracker = true
+ }
+ game.state = 'vm_add_infl'
+ },
+ support_check() {
+ push_undo()
+ log_gap(`Played C${game.vm_event} for support checks`)
+ game.vm_available_ops = 2
+ game.state = 'vm_ceh_support_check_prep'
+ valid_spaces_sc()
+ },
+ tst() {
+ push_undo()
+ log_gap(`Played C${game.vm_event} to the Tiananmen Square Track`)
+ game.state = 'vm_tiananmen_square_attempt'
+ }
+}
+
+states.vm_dash_for_the_west = {
+ get inactive() {
+ return `resolve ${clean_name(cards[C_DASH_FOR_THE_WEST].name)}.`
+ },
+ prompt() {
+ view.prompt = 'Dash for the West: roll a die'
+ gen_action('roll')
+ },
+ roll() {
+ clear_undo()
+ let roll = roll_d6()
+ log(`Roll: D${roll}`)
+ let com_control = check_presence('East_Germany').com_spaces
+
+ if (roll > com_control) {
+ log(`Success. More than the ${com_control} Communist controlled spaces in East Germany`)
+ log('+1 VP')
+ game.vp++
+ if (check_vp()) {
+ return
+ }
+ game.discard = true
+ game.state = 'vm_play_event_from_discard'
+ } else {
+ log(`Fail: more than a ${com_control} required`)
+ vm_next()
+ }
+ },
+}
+
+states.vm_play_event_from_discard = {
+ get inactive() {
+ return `resolve ${clean_name(cards[this_card()].name)}.`
+ },
+ prompt() {
+ if (game.valid_cards.length === 0) {
+ view.prompt = `${clean_name(cards[this_card()].name)}: no valid cards in discard.`
+ gen_action('pass')
+ } else {
+ view.prompt = `${event_prompt()}.`
+ for (let card of game.valid_cards) {
+ gen_action('pass')
+ gen_action_card(card)
+ }
+ }
+ },
+ card(card) {
+ push_undo()
+ log(`C${this_card()}:`)
+ log(`Chose C${card}`)
+ game.vm_event = card
+ game.vm_available_ops = cards[card].ops
+ game.discard = false
+ if (switch_events.includes(card)) {next_player()}
+ goto_vm(card)
+ },
+ pass(){
+ push_undo()
+ if (game.valid_cards.length === 0) {
+ log('No valid cards to choose')
+ } else{
+ log('Did not choose a card')
+ }
+ vm_next()
+ },
+}
+
+states.vm_deutsche_marks_prep = {
+ inactive: 'choose a card.',
+ prompt() {
+ if (game.valid_cards.length === 0) {
+ view.prompt = 'Deutsche Marks: no cards to give.'
+ gen_action('pass')
+ } else {
+ view.prompt = 'Deutsche Marks: choose a card to give.'
+ for (let card of game.valid_cards) {
+ gen_action_card(card)
+ }
+ }
+ },
+ card(card) {
+ push_undo()
+ log(`Gave C${card}`)
+ game.valid_cards = []
+ silent_discard(card)
+ game.state = 'vm_deutsche_marks_confirm'
+ game.vm_event = card
+ },
+ pass() {
+ push_undo()
+ vm_next()
+ }
+}
+
+states.vm_deutsche_marks_confirm = {
+ inactive: 'choose a card.',
+ prompt() {
+ view.prompt = `Deutsche Marks: gave ${cards[game.vm_event].name}.`
+ gen_action('done')
+ },
+ done() {
+ if (cards[game.vm_event].side === "C" && (is_auto_resolve(game.vm_event) || switch_events.includes(game.vm_event))) {
+ goto_vm(game.vm_event)
+ } else {
+ next_player()
+ game.state = 'vm_deutsche_marks'
+ }
+ }
+}
+
+states.vm_deutsche_marks = {
+ get inactive() {
+ return `resolve ${clean_name(cards[C_DEUTSCHE_MARKS].name)}.`
+ },
+ prompt() {
+ if(cards[game.vm_event].side === 'C' && (cards[game.vm_event].playable || game.playable_cards.includes(game.vm_event))) {
+ view.prompt = `Deutsche Marks: you must play ${clean_name(cards[this_card()].name)} for the event.`
+ gen_action('event')
+ } else {
+ view.prompt = `Deutsche Marks: play ${clean_name(cards[this_card()].name)} for:`
+ gen_action('influence')
+ gen_action('support_check')
+ if (game.com_tst_attempted_this_turn === 0) {
+ gen_action('tst')
+ }
+ }
+ },
+ event() {
+ push_undo()
+ log(`Played C${game.vm_event} for the event`)
+ if (!game.vm_infl_to_do) {
+ game.return = game.active
+ }
+ goto_vm(game.vm_event)
+ },
+ influence() {
+ push_undo()
+ log(`Played C${game.vm_event} to place SPs`)
+ game.vm_available_ops = get_card_ops(game.vm_event)
+ valid_spaces_infl()
+ game.state = 'vm_add_infl'
+ },
+ support_check() {
+ push_undo()
+ log_gap(`Played C${game.vm_event} for support checks`)
+ game.vm_available_ops = 2
+ game.state='vm_support_check_prep'
+ valid_spaces_sc()
+ },
+ tst() {
+ push_undo()
+ log_gap(`Played C${game.vm_event} to the Tiananmen Square Track`)
+ game.state='vm_tiananmen_square_attempt'
+ }
+}
+
+states.vm_exit_visas = {
+ get inactive() {
+ return `resolve ${clean_name(cards[C_EXIT_VISAS].name)}.`
+ },
+ prompt() {
+ view.prompt = 'Exit Visas: you may discard cards from your hand and draw replacements.'
+ for (let card of game.democrat_hand) {
+ gen_action_card(card)
+ }
+ if (game.temp === 0) {
+ gen_action('pass')
+ } else {
+ gen_action('done')
+ }
+ },
+ card(card){
+ push_undo()
+ discard(card)
+ game.temp++
+ },
+ pass() {
+ push_undo()
+ log('Did not discard')
+ game.state = 'vm_exit_visas_finish'
+ },
+ done() {
+ push_undo()
+ game.state = 'vm_exit_visas_finish'
+ }
+}
+
+states.vm_exit_visas_finish = {
+ get inactive() {
+ return `resolve ${clean_name(cards[C_EXIT_VISAS].name)}.`
+ },
+ prompt() {
+ if (game.temp > 0 ) {
+ view.prompt = 'Exit Visas: draw replacement cards.'
+ gen_action('draw')
+ } else {
+ view.prompt = 'Exit Visas: done.'
+ gen_action('done')
+ }
+ },
+ draw() {
+ clear_undo()
+ draw_cards(game.strategy_deck, game.democrat_hand, game.communist_hand, game.democrat_hand.length + game.temp, game.communist_hand.length)
+ game.temp = 0
+ vm_next()
+ },
+ done() {
+ vm_next()
+ }
+}
+
+states.vm_foreign_currency_debt_burden = {
+ get inactive() {
+ return `resolve ${clean_name(cards[game.played_card].name)}.`
+ },
+ prompt() {
+ view.prompt = 'Choose a country. The Communist may not make support checks there for the rest of the turn.'
+ gen_action('east_germany')
+ gen_action('poland')
+ gen_action('czechoslovakia')
+ gen_action('hungary')
+ gen_action('bulgaria')
+ },
+ east_germany() {
+ push_undo()
+ game.foreign_currency_debt_burden = 'East_Germany'
+ log('Selected East Germany')
+ vm_next()
+ },
+ poland() {
+ push_undo()
+ game.foreign_currency_debt_burden = 'Poland'
+ log('Selected Poland')
+ vm_next()
+ },
+ czechoslovakia() {
+ push_undo()
+ game.foreign_currency_debt_burden = 'Czechoslovakia'
+ log('Selected Czechoslovakia')
+ vm_next()
+ },
+ hungary() {
+ push_undo()
+ game.foreign_currency_debt_burden = 'Hungary'
+ log('Selected Hungary')
+ vm_next()
+ },
+ bulgaria() {
+ push_undo()
+ game.foreign_currency_debt_burden = 'Bulgaria'
+ log('Selected Bulgaria')
+ vm_next()
+ }
+}
+
+states.vm_goodbye_lenin = {
+ get inactive() {
+ return `resolve ${clean_name(cards[game.played_card].name)}.`
+ },
+ prompt() {
+ if (game.valid_cards.length > 0 ) {
+ view.prompt = `Play a red event from your opponent's hand, or play Goodbye Lenin for operations.`
+ for (let card of game.valid_cards) {
+ gen_action_card(card)
+ gen_action('ops')
+ }
+ } else {
+ view.prompt = 'Communist has no red events. Play Goodbye Lenin for operations.'
+ gen_action('ops')
+ }
+ },
+ card(card) {
+ push_undo()
+ log(`Chose to play C${card} for the event`)
+ let card_index = game.communist_hand.indexOf(card)
+ game.communist_hand.splice(card_index, 1)
+ game.vm_event = card
+ game.view_opp_hand = false
+ goto_vm(card)
+ },
+ ops() {
+ push_undo()
+ if (game.valid_cards.length === 0) {
+ logi('No red events')
+ }
+ log('C46 played for operations')
+ game.view_opp_hand = false
+ game.state = 'vm_goodbye_lenin_ops'
+ }
+}
+
+states.vm_goodbye_lenin_ops = {
+ get inactive() {
+ return `resolve ${clean_name(cards[this_card()].name)}.`
+ },
+ prompt() {
+ view.prompt = `Play ${clean_name(cards[this_card()].name)} for:`
+ gen_action('influence')
+ gen_action('support_check')
+ if ((game.active === DEM && game.dem_tst_attempted_this_turn === 0 ) || (game.active === COM && game.com_tst_attempted_this_turn === 0 )) {
+ gen_action('tst')
+ }
+ },
+ influence(){
+ push_undo()
+ game.vm_available_ops = get_card_ops(this_card())
+ valid_spaces_infl()
+
+ // If ABHR - Set AHBR tracker to true
+ if (game.persistent_events.includes(58)) {
+ game.austria_hungary_border_reopened_tracker = true
+ }
+ game.state = 'vm_add_infl'
+ },
+ support_check() {
+ push_undo()
+ game.vm_available_ops = 2
+ game.state = 'vm_support_check_prep'
+ valid_spaces_sc()
+ },
+ tst() {
+ push_undo()
+ game.state = 'vm_tiananmen_square_attempt'
+ }
+}
+
+states.vm_honecker = {
+ get inactive() {
+ return `resolve ${clean_name(cards[game.played_card].name)}.`
+ },
+ prompt() {
+ if (game.valid_cards.length === 0 && game.temp === 0) {
+ view.prompt = 'Honecker: no valid cards to choose.'
+ gen_action('pass')
+ } else
+ if (game.temp === 0) {view.prompt = 'Honecker: choose a card to add to your hand.'
+ for (let card of game.valid_cards) {
+ gen_action_card(card)
+ gen_action('pass')
+ }
+ }
+ },
+ card(card) {
+ push_undo()
+ game.valid_cards = []
+ log(`Took C${card} into hand`)
+ game.temp = card
+ let card_index = game.strategy_discard.indexOf(card)
+ game.strategy_discard.splice(card_index, 1)
+ game.communist_hand.push(card)
+ vm_next()
+ },
+ pass(){
+ log('Did not take a card')
+ game.discard = false
+ vm_next()
+ },
+}
+
+states.vm_inflationary_currency = {
+ get inactive() {
+ return `resolve ${clean_name(cards[game.played_card].name)}.`
+ },
+ prompt() {
+ if ((game.active === COM && game.revolutions.every(n => n === false)) || (game.active === DEM && game.revolutions.every(n => n === true))) {
+ view.prompt = 'Inflationary Currency: no countries to choose.'
+ gen_action('pass')
+ } else {
+ view.prompt = 'Inflationary Currency: choose a country where your opponent has power.'
+ if (game.active === DEM) {
+ if (!game.revolutions[0]) {gen_action('poland')}
+ if (!game.revolutions[1]) {gen_action('hungary')}
+ if (!game.revolutions[2]) {gen_action('east_germany')}
+ if (!game.revolutions[3]) {gen_action('bulgaria')}
+ if (!game.revolutions[4]) {gen_action('czechoslovakia')}
+ if (!game.revolutions[5]) {gen_action('romania')}
+ } else {
+ if (game.revolutions[0]) {gen_action('poland')}
+ if (game.revolutions[1]) {gen_action('hungary')}
+ if (game.revolutions[2]) {gen_action('east_germany')}
+ if (game.revolutions[3]) {gen_action('bulgaria')}
+ if (game.revolutions[4]) {gen_action('czechoslovakia')}
+ if (game.revolutions[5]) {gen_action('romania')}
+ }
+ }
+ },
+ east_germany() {
+ push_undo()
+ game.vm_active_country = 'East_Germany'
+ log(`Chose ${country_name(game.vm_active_country)}`)
+ vm_next()
+ },
+ poland() {
+ push_undo()
+ game.vm_active_country = 'Poland'
+ log(`Chose ${country_name(game.vm_active_country)}`)
+ vm_next()
+ },
+ czechoslovakia() {
+ push_undo()
+ game.vm_active_country = 'Czechoslovakia'
+ log(`Chose ${country_name(game.vm_active_country)}`)
+ vm_next()
+ },
+ hungary() {
+ push_undo()
+ game.vm_active_country = 'Hungary'
+ log(`Chose ${country_name(game.vm_active_country)}`)
+ vm_next()
+ },
+ romania() {
+ push_undo()
+ game.vm_active_country = 'Romania'
+ log(`Chose ${country_name(game.vm_active_country)}`)
+ vm_next()
+ },
+ bulgaria () {
+ push_undo()
+ game.vm_active_country = 'Bulgaria'
+ log(`Chose ${country_name(game.vm_active_country)}`)
+ vm_next()
+ },
+ pass() {
+ log('Passed')
+ vm_return()
+ }
+}
+
+states.vm_inflationary_currency_discard = {
+ get inactive() {
+ return `resolve ${clean_name(cards[game.played_card].name)}.`
+ },
+ prompt() {
+ if (game.valid_cards.length === 0 ) {
+ view.prompt = 'Inflationary Currency: no valid cards to discard. You must pass.'
+ gen_action('pass')
+ } else {
+ view.prompt = 'Inflationary Currency: you may discard a 3 op or higher value card to cancel the support check.'
+ gen_action('pass')
+ for (let card of game.valid_cards) {
+ gen_action_card(card)
+ }
+ }
+ },
+ card(card) {
+ push_undo()
+ discard(card)
+ game.temp = card
+ if (!game.vm_infl_to_do) {
+ if(game.round_player === DEM) {
+ game.return = COM
+ } else {
+ game.return = DEM
+ }
+ }
+ vm_next()
+ },
+ pass() {
+ push_undo()
+ log('Did not discard')
+ next_player()
+ game.vm_available_ops = 1
+ vm_next()
+ },
+}
+
+
+states.vm_kiss_of_death = {
+ get inactive() {
+ return `resolve ${clean_name(cards[game.played_card].name)}.`
+ },
+ prompt() {
+ if (game.communist_hand.length === 0) {
+ view.prompt = 'Kiss of Death. No cards to discard.'
+ gen_action('pass')
+ } else {
+ view.prompt = 'Kiss of Death: you must randomly discard a card.'
+ gen_action('discard')
+ }
+ },
+ discard() {
+ clear_undo()
+ log(`C${C_KISS_OF_DEATH}:`)
+ game.vm_event = discard_card(game.communist_hand)
+ //Change player before checking if event is playable. Common European Home is not playable here
+ change_player()
+ // Special check for the Reformer Rehabilitated
+ if (game.vm_event === C_REFORMER_REHABILITATED && game.dem_tst_position > game.com_tst_position) {
+ log_side()
+ log(`C${game.vm_event}:`)
+ game.state = 'vm_kiss_of_death_finish'
+ } else if (cards[game.vm_event].side !== "C" && event_is_playable(game.vm_event) && game.vm_event !== C_COMMON_EUROPEAN_HOME) {
+ if (is_auto_resolve(game.vm_event)) {
+ change_player()
+ game.state = 'vm_kiss_of_death_finish'
+ } else {
+ log_side()
+ log(`C${game.vm_event}:`)
+ game.state = 'vm_kiss_of_death_finish'
+ }
+ } else {
+ change_player()
+ logi('Event does not occur')
+ vm_next()
+ }
+ },
+ pass() {
+ log('No card to discard')
+ vm_next()
+ }
+}
+
+states.vm_kiss_of_death_finish = {
+ get inactive() {
+ return `resolve ${clean_name(cards[game.played_card].name)}.`
+ },
+ prompt() {
+ view.prompt = `Play ${clean_name(cards[game.vm_event].name)} for the event.`
+ gen_action('event')
+ },
+ event() {
+ goto_vm(game.vm_event)
+ },
+}
+
+states.vm_kremlin_coup_choose_country = {
+ get inactive() {
+ return `resolve ${clean_name(cards[this_card()].name)}.`
+ },
+ prompt() {
+ if (game.temp.length > 0) {
+ view.prompt = 'Kremlin Coup! Select a country where the Communist retains power.'
+ for (let country of countries) {
+ if (game.temp.includes(country)) {
+ gen_action(`${country.toLowerCase()}`)
+ }
+ }
+ } else {
+ view.prompt = 'Kremlin Coup! There are no countries where the Communist retains power.'
+ gen_action('done')
+ }
+ },
+ east_germany() {
+ push_undo()
+ game.vm_active_country = 'East_Germany'
+ game.temp = game.temp.filter(country => country !== game.vm_active_country)
+ log(`${country_name(game.vm_active_country)}:`)
+ vm_kremlin_coup_elite()
+ },
+ poland() {
+ push_undo()
+ game.vm_active_country = 'Poland'
+ log(`${country_name(game.vm_active_country)}:`)
+ game.temp = game.temp.filter(country => country !== game.vm_active_country)
+ vm_kremlin_coup_elite()
+ },
+ czechoslovakia() {
+ push_undo()
+ game.vm_active_country = 'Czechoslovakia'
+ log(`${country_name(game.vm_active_country)}:`)
+ game.temp = game.temp.filter(country => country !== game.vm_active_country)
+ vm_kremlin_coup_elite()
+ },
+ hungary() {
+ push_undo()
+ game.vm_active_country = 'Hungary'
+ log(`${country_name(game.vm_active_country)}:`)
+ game.temp = game.temp.filter(country => country !== game.vm_active_country)
+ vm_kremlin_coup_elite()
+ },
+ romania() {
+ push_undo()
+ game.vm_active_country = 'Romania'
+ log(`${country_name(game.vm_active_country)}:`)
+ game.temp = game.temp.filter(country => country !== game.vm_active_country)
+ vm_kremlin_coup_elite()
+ },
+ bulgaria () {
+ push_undo()
+ game.vm_active_country = 'Bulgaria'
+ log(`${country_name(game.vm_active_country)}:`)
+ game.temp = game.temp.filter(country => country !== game.vm_active_country)
+ vm_kremlin_coup_elite()
+ },
+ done() {
+ game.temp = 0
+ vm_next()
+ }
+}
+
+states.vm_kremlin_coup_take_control = {
+ get inactive() {
+ return `resolve ${clean_name(cards[game.played_card].name)}.`
+ },
+ prompt() {
+ if (game.valid_spaces.includes(game.systematization)) {
+ view.prompt = `Kremlin Coup! ${country_name(game.vm_active_country)}'s Elite space no longer exists.`
+ gen_action('done')
+ }
+ else if (game.valid_spaces.length === 0){
+ view.prompt = `Kremlin Coup! ${country_name(game.vm_active_country)}'s Elite space is already controlled.`
+ gen_action('done')
+ } else {
+ view.prompt = `Kremlin Coup! Take control of the Elite space in ${country_name(game.vm_active_country)}.`
+ for (let space_id of game.valid_spaces) {
+ gen_action_space(space_id);
+ }
+ }
+ },
+ space(space) {
+ push_undo()
+ vm_take_control(space)
+ if (game.vm_active_country === 'East_Germany') {game.selected_space = S_BERLIN }
+ if (game.vm_active_country === 'Poland') {game.selected_space = S_WARSZAWA}
+ if (game.vm_active_country === 'Czechoslovakia') {game.selected_space = S_PRAHA}
+ if (game.vm_active_country === 'Hungary') {game.selected_space = S_BUDAPEST}
+ if (game.vm_active_country === 'Romania') {game.selected_space = S_BUCURESTI}
+ if (game.vm_active_country === 'Bulgaria') {game.selected_space = S_SOFIA}
+ game.state = 'vm_kremlin_coup_sc_prep'
+ },
+ done() {
+ push_undo()
+ if (game.vm_active_country === 'East_Germany') {game.selected_space = S_BERLIN }
+ if (game.vm_active_country === 'Poland') {game.selected_space = S_WARSZAWA}
+ if (game.vm_active_country === 'Czechoslovakia') {game.selected_space = S_PRAHA}
+ if (game.vm_active_country === 'Hungary') {game.selected_space = S_BUDAPEST}
+ if (game.vm_active_country === 'Romania') {game.selected_space = S_BUCURESTI}
+ if (game.vm_active_country === 'Bulgaria') {game.selected_space = S_SOFIA}
+ game.state = 'vm_kremlin_coup_sc_prep'
+ }
+}
+
+states.vm_kremlin_coup_sc_prep = {
+ get inactive() {
+ return `resolve ${clean_name(cards[game.played_card].name)}.`
+ },
+ prompt() {
+ view.prompt = `Kremlin Coup! Conduct a support check in ${country_name(game.vm_active_country)}'s Bureaucratic space.`
+ gen_action_space(game.selected_space);
+ },
+ space(space) {
+ push_undo()
+ game.state = 'vm_kremlin_coup_sc'
+ }
+}
+
+states.vm_kremlin_coup_sc = {
+ inactive: 'do support checks',
+ prompt () {
+ view.prompt = `Support check: ${spaces[game.selected_space].name_unique}. Roll a die.`
+ gen_action('roll')
+ },
+ roll() {
+ clear_undo()
+ do_sc(game.selected_space)
+ if (game.temp.length > 0 ){
+ game.state = 'vm_kremlin_coup_choose_country'
+ } else {
+ vm_next()
+ }
+ }
+}
+
+states.vm_laszlo_tokes = {
+ get inactive() {
+ return `resolve ${clean_name(cards[game.played_card].name)}.`
+ },
+ prompt() {
+ view.prompt = `Laszlo Tokes. Choose to:`
+ gen_action('influence')
+ gen_action('support_check')
+ },
+ influence(){
+ push_undo()
+ game.vm_available_ops = get_card_ops(C_LASZLO_TOKES)
+ valid_spaces_infl()
+ game.valid_spaces = game.valid_spaces.filter(space_id => spaces[space_id].country === 'Romania')
+ game.phase = 3
+ vm_next()
+ },
+ support_check() {
+ push_undo()
+ game.vm_available_ops = 2
+ valid_spaces_sc()
+ game.valid_spaces = game.valid_spaces.filter(space_id => spaces[space_id].country === 'Romania')
+ vm_next()
+ }
+}
+
+states.vm_switch_infl = {
+ get inactive() {
+ return `resolve ${clean_name(cards[game.played_card].name)}.`
+ },
+ prompt() {
+ if (game.valid_spaces.length === 0) {
+ view.prompt = `${clean_name(cards[this_card()].name)}: No SPs to remove.`
+ gen_action('pass')
+ } else {
+ view.prompt = `${clean_name(cards[game.played_card].name)}: ${event_prompt()}.`
+ for (let space_id of game.valid_spaces) {
+ gen_action_space(space_id);
+ }
+ }
+ },
+ space(space) {
+ push_undo()
+ if (game.vm_event === C_BETRAYAL) {
+ game.vm_available_ops = game.demInfl[space]
+ }
+ vm_switch_infl(space)
+ if (game.vm_available_ops === 0) {
+ game.valid_spaces = []
+ }
+ vm_next()
+ },
+ pass() {
+ vm_next()
+ }
+}
+
+states.vm_malta_summit = {
+ get inactive() {
+ return `resolve ${clean_name(cards[game.played_card].name)}.`
+ },
+ prompt() {
+ view.prompt = 'Malta Summit: roll a die.'
+ gen_action('roll')
+},
+ roll() {
+ clear_undo()
+ let roll = roll_d6()
+ log(`Roll: D${roll}`)
+ if (game.stability > 0) {
+ logi(`+${Math.min(game.stability, 3)} from USSR Stability Track`)
+ log(`Modified roll: ${roll + Math.min(game.stability, 3)}`)
+ }
+ if (roll + game.stability > 3) {
+ log('Summit successful')
+ game.vp += 3
+ log('+3 VP')
+ if (check_vp()) {
+ return
+ }
+ if (game.comInfl[S_DRESDEN] > 0 ) {game.valid_spaces.push(S_DRESDEN)}
+ if (game.comInfl[S_BYDGOSZCZ] > 0 ) {game.valid_spaces.push(S_BYDGOSZCZ)}
+ if (game.comInfl[S_PLZEN] > 0 ) {game.valid_spaces.push(S_PLZEN)}
+ if (game.comInfl[S_SZOMBATHELY] > 0 ) {game.valid_spaces.push(S_SZOMBATHELY)}
+ if (game.comInfl[S_CLUJ_NAPOCA] > 0 ) {game.valid_spaces.push(S_CLUJ_NAPOCA)}
+ if (game.comInfl[S_STARA_ZAGORA] > 0 ) {game.valid_spaces.push(S_STARA_ZAGORA)}
+ game.remove_opponent_infl = true
+ vm_next()
+ }
+ else {
+ log('Summit failed. Required 4 or more')
+ vm_return()
+ }
+ },
+}
+
+states.vm_modrow = {
+ get inactive() {
+ return `resolve ${clean_name(cards[game.played_card].name)}.`
+ },
+ prompt() {
+ view.prompt = `Modrow: roll a die.`
+ gen_action('roll')
+ },
+ roll(){
+ clear_undo()
+ let roll = roll_d6()
+ let dem_spaces = spaces.filter(space => space && space.country === 'East_Germany' && check_dem_control(space.space_id)).length
+ if (roll > dem_spaces) {
+ log(`Roll: D${roll}`)
+ log(`Success. More than the ${dem_spaces} Democratically controlled spaces`)
+ vm_next()
+ } else {
+ log(`Roll: D${roll}`)
+ log(`Fail. More than ${dem_spaces} required`)
+ permanently_remove(C_MODROW)
+ vm_return()
+ }
+ }
+}
+
+states.vm_nepotism = {
+ get inactive() {
+ return `resolve ${clean_name(cards[game.played_card].name)}.`
+ },
+ prompt() {
+ view.prompt = 'Nepotism: roll a die.'
+ gen_action('roll')
+ },
+ roll() {
+ clear_undo()
+ let roll = roll_d6()
+ if (roll < 3) {
+ log(`Roll: D${roll} adds 4 SPs`)
+ game.vm_available_ops = 4}
+ else if (roll < 5 ) {
+ log(`Roll: D${roll} adds 3 SPs`)
+ game.vm_available_ops = 3}
+ else {
+ log(`Roll: D${roll} adds 1 SP`)
+ game.vm_available_ops = 1}
+ vm_next()
+ },
+}
+
+states.vm_new_years_eve_party = {
+ get inactive() {
+ return `resolve ${clean_name(cards[C_NEW_YEARS_EVE_PARTY].name)}.`
+ },
+ prompt() {
+ view.prompt = 'Choose whether the game ends at the end of this turn.'
+ gen_action('end')
+ gen_action('continue')
+ },
+ end() {
+ push_undo()
+ game.persistent_events.push(C_NEW_YEARS_EVE_PARTY)
+ log('Chooses to end the game. There will be no final scoring')
+ let power = game.revolutions.filter(value => value === false).length
+ if (power > 3) {
+ log(`Communist holds power in ${pluralize(power, 'country', 's')}. -3 VP`)
+ game.vp -= 3
+ } else {
+ log(`Communist holds power in ${pluralize(power, 'country', 's')}. +3 VP`)
+ game.vp += 3
+ }
+ if (check_vp()) {
+ return
+ }
+ vm_next()
+ },
+ continue() {
+ push_undo()
+ log('Chooses to continue')
+ permanently_remove(C_NEW_YEARS_EVE_PARTY)
+ vm_next()
+ }
+}
+
+states.vm_nomenklatura = {
+ get inactive() {
+ return `resolve ${clean_name(cards[game.played_card].name)}.`
+ },
+ prompt() {
+ view.prompt = 'Nomenklatura: choose to remove all Democratic SPs from Elite spaces or add 3 SPs to any Elite space(s).'
+ gen_action('remove')
+ gen_action('add')
+ },
+ remove() {
+ push_undo()
+ game.valid_spaces = []
+ for (let i = 0; i < spaces.length; i++) {
+ let space = spaces[i]
+
+ if (space.socio === 1 && game.demInfl[i] > 0) {
+ game.valid_spaces.push(space.space_id)
+ }
+ }
+ game.vm_available_ops = game.valid_spaces.length
+ game.remove_opponent_infl = true
+ game.state = 'vm_nomenklatura_remove'
+ },
+ add() {
+ push_undo()
+ game.valid_spaces = []
+ for (let space of spaces) {
+ if (space.socio === 1) {
+ game.valid_spaces.push(space.space_id)
+ }
+ }
+ check_systematization()
+ game.vm_available_ops = 3
+ game.state = 'vm_nomenklatura_add'
+ }
+}
+
+states.vm_nomenklatura_remove = {
+ get inactive() {
+ return `resolve ${clean_name(cards[game.played_card].name)}.`
+ },
+ prompt() {
+ if (game.valid_spaces.length === 0 ) {
+ view.prompt = 'Nomenklatura. No SPs to remove: pass.'
+ gen_action('pass')
+ } else {
+ view.prompt = 'Nomenklatura: remove all Democratic SPs from Elite spaces.'
+
+ for (let space_id of game.valid_spaces) {
+ gen_action_space(space_id);
+ }
+ }
+ },
+ space(space) {
+ push_undo()
+ vm_do_remove_all_infl(space)
+ if (game.valid_spaces.length === 0) {
+ vm_next()
+ }
+ },
+ pass() {
+ push_undo()
+ vm_next()
+ }
+}
+
+states.vm_nomenklatura_add = {
+ get inactive() {
+ return `resolve ${clean_name(cards[game.played_card].name)}.`
+ },
+ prompt() {
+ view.prompt = `Nomenklatura: add 3 SPs to any Elite space(s). ${pluralize(game.vm_available_ops, 'SP')} remaining.`
+ for (let space_id of game.valid_spaces) {
+ gen_action_space(space_id);
+ }
+ },
+ space(space) {
+ vm_do_add_infl_free(space)
+ if (game.vm_available_ops === 0 ) {
+ game.valid_spaces = []
+ do_log_summary()
+ vm_next()
+ }
+ },
+}
+
+states.vm_samizdat = {
+ get inactive() {
+ return `resolve ${clean_name(cards[game.played_card].name)}.`
+ },
+ prompt() {
+ view.prompt = 'Samizdat: you may set aside a card from your hand and draw a replacement.'
+ for (let card of game.democrat_hand) {
+ gen_action_card(card)
+ }
+ gen_action('pass')
+ },
+ card(card) {
+ push_undo()
+ game.samizdat_card = card
+ game.democrat_hand = game.democrat_hand.filter(c => c !== card)
+ log('Set aside a card')
+ game.state = 'vm_samizdat_finish'
+ },
+ pass() {
+ push_undo()
+ log('Did not set aside a card')
+ vm_next()
+ }
+}
+
+states.vm_samizdat_finish = {
+ get inactive() {
+ return `resolve ${clean_name(cards[game.played_card].name)}.`
+ },
+ prompt() {
+ view.prompt = 'Draw a replacement card.'
+ gen_action('draw')
+ },
+ draw() {
+ clear_undo()
+ game.democrat_hand.push(draw_card(game.strategy_deck))
+ vm_next()
+ },
+}
+
+states.vm_shock_therapy = {
+ get inactive() {
+ return `resolve ${clean_name(cards[game.played_card].name)}.`
+ },
+ prompt() {
+ if (game.revolutions.every(n => n === false)) {
+ view.prompt = 'Shock Therapy: no countries to choose.'
+ gen_action('pass')
+ } else {
+ if (!game.vm_active_country || game.vm_active_country === '' ) {
+ view.prompt = 'Shock Therapy: choose a country where you hold Power:'
+ if (game.revolutions[0]) {gen_action('poland')}
+ if (game.revolutions[1]) {gen_action('hungary')}
+ if (game.revolutions[2]) {gen_action('east_germany')}
+ if (game.revolutions[3]) {gen_action('bulgaria')}
+ if (game.revolutions[4]) {gen_action('czechoslovakia')}
+ if (game.revolutions[5]) {gen_action('romania')}
+ }
+ else {
+ view.prompt = 'Shock Therapy: roll a die.'
+ gen_action('roll')
+ }
+ }
+ },
+ east_germany() {
+ push_undo()
+ game.vm_active_country = 'East_Germany'
+ log(`Chose ${country_name(game.vm_active_country)}`)
+ },
+ poland() {
+ push_undo()
+ game.vm_active_country = 'Poland'
+ log(`Chose ${country_name(game.vm_active_country)}`)
+ },
+ czechoslovakia() {
+ push_undo()
+ game.vm_active_country = 'Czechoslovakia'
+ log(`Chose ${country_name(game.vm_active_country)}`)
+ },
+ hungary() {
+ push_undo()
+ game.vm_active_country = 'Hungary'
+ log(`Chose ${country_name(game.vm_active_country)}`)
+ },
+ romania() {
+ push_undo()
+ game.vm_active_country = 'Romania'
+ log(`Chose ${country_name(game.vm_active_country)}`)
+ },
+ bulgaria () {
+ push_undo()
+ game.vm_active_country = 'Bulgaria'
+ log(`Chose ${country_name(game.vm_active_country)}`)
+ },
+ roll() {
+ clear_undo()
+ let roll = roll_d6()
+ let worker_farmer = 0
+ for (let space of spaces) {
+ if (space && space.country === game.vm_active_country && check_com_control(space.space_id) && (space.socio === 3 || space.socio === 4)) {
+ worker_farmer++
+ }
+ }
+ log(`Roll: D${roll}`)
+ logi(`-${worker_farmer} from Communist controlled Worker and Farmer spaces`)
+ log(`Modified roll: ${Math.max(roll - worker_farmer, 0)}`)
+ if ((roll - worker_farmer) > 2) {
+ log(`C${C_SHOCK_THERAPY} is successful. +3 VP`)
+ game.vp += 3
+ if (check_vp()) {
+ return
+ }
+ vm_next()
+ } else {
+ log('C93 is unsuccessful. Required 3 or more')
+ permanently_remove(C_SHOCK_THERAPY)
+ vm_return()
+ }
+ },
+ pass() {
+ log('Passed')
+ vm_return()
+ }
+}
+
+states.vm_social_democratic_platform_adopted = {
+ get inactive() {
+ return `resolve ${clean_name(cards[game.played_card].name)}.`
+ },
+ prompt() {
+ if (game.revolutions.every(n => n === false)) {
+ view.prompt = 'Social Democratic Platform Adopted: no countries to choose.'
+ gen_action('pass')
+ } else {
+ view.prompt = 'Select a country where the Democrat holds Power.'
+ if (game.revolutions[0]) {gen_action('poland')}
+ if (game.revolutions[1]) {gen_action('hungary')}
+ if (game.revolutions[2]) {gen_action('east_germany')}
+ if (game.revolutions[3]) {gen_action('bulgaria')}
+ if (game.revolutions[4]) {gen_action('czechoslovakia')}
+ if (game.revolutions[5]) {gen_action('romania')}
+ }
+ },
+ east_germany() {
+ push_undo()
+ game.vm_active_country = 'East_Germany'
+ log(`Selected ${country_name(game.vm_active_country)}`)
+ vm_next()
+ },
+ poland() {
+ push_undo()
+ game.vm_active_country = 'Poland'
+ log(`Selected ${country_name(game.vm_active_country)}`)
+ vm_next()
+ },
+ czechoslovakia() {
+ push_undo()
+ game.vm_active_country = 'Czechoslovakia'
+ log(`Selected ${country_name(game.vm_active_country)}`)
+ vm_next()
+ },
+ hungary() {
+ push_undo()
+ game.vm_active_country = 'Hungary'
+ log(`Selected ${country_name(game.vm_active_country)}`)
+ vm_next()
+ },
+ romania() {
+ push_undo()
+ game.vm_active_country = 'Romania'
+ log(`Selected ${country_name(game.vm_active_country)}`)
+ vm_next()
+ },
+ bulgaria () {
+ push_undo()
+ game.vm_active_country = 'Bulgaria'
+ log(`Selected ${country_name(game.vm_active_country)}`)
+ vm_next()
+ },
+ pass() {
+ log('Passed')
+ vm_return()
+ }
+}
+
+states.vm_systematization = {
+ get inactive() {
+ return `resolve ${clean_name(cards[game.played_card].name)}.`
+ },
+ prompt() {
+ view.prompt = 'Systematization: eliminate a space in Romania.'
+ for (let space_id of game.valid_spaces) {
+ gen_action_space(space_id);
+ }
+ },
+ space(space) {
+ push_undo()
+ vm_eliminate(space)
+ game.valid_spaces = []
+ game.systematization = space
+ add_to_persistent_events(C_SYSTEMATIZATION)
+ vm_next()
+ },
+}
+
+states.vm_the_chinese_solution = {
+ get inactive() {
+ return `resolve ${clean_name(cards[game.played_card].name)}.`
+ },
+ prompt() {
+ view.prompt = 'The Chinese Solution: you may give up 3 VP to conduct support checks in a country where you hold power.'
+ if (!game.revolutions[0]) {gen_action('poland')}
+ if (!game.revolutions[1]) {gen_action('hungary')}
+ if (!game.revolutions[2]) {gen_action('east_germany')}
+ if (!game.revolutions[3]) {gen_action('bulgaria')}
+ if (!game.revolutions[4]) {gen_action('czechoslovakia')}
+ if (!game.revolutions[5]) {gen_action('romania')}
+ gen_action('pass')
+ },
+ east_germany() {
+ push_undo()
+ game.vm_active_country = 'East_Germany'
+ log(`Chose ${country_name(game.vm_active_country)}`)
+ log('+3 VP')
+ game.vp += 3
+ if (check_vp()) {
+ return
+ }
+ vm_next()
+ },
+ poland() {
+ push_undo()
+ game.vm_active_country = 'Poland'
+ log(`Chose ${country_name(game.vm_active_country)}`)
+ log('+3 VP')
+ game.vp += 3
+ if (check_vp()) {
+ return
+ }
+ vm_next()
+ },
+ czechoslovakia() {
+ push_undo()
+ game.vm_active_country = 'Czechoslovakia'
+ log(`Chose ${country_name(game.vm_active_country)}`)
+ log('+3 VP')
+ game.vp += 3
+ if (check_vp()) {
+ return
+ }
+ vm_next()
+ },
+ hungary() {
+ push_undo()
+ game.vm_active_country = 'Hungary'
+ log(`Chose ${country_name(game.vm_active_country)}`)
+ log('+3 VP')
+ game.vp += 3
+ if (check_vp()) {
+ return
+ }
+ vm_next()
+ },
+ romania() {
+ push_undo()
+ game.vm_active_country = 'Romania'
+ log(`Chose ${country_name(game.vm_active_country)}`)
+ log('+3 VP')
+ game.vp += 3
+ if (check_vp()) {
+ return
+ }
+ vm_next()
+ },
+ bulgaria () {
+ push_undo()
+ game.vm_active_country = 'Bulgaria'
+ log(`Chose ${country_name(game.vm_active_country)}`)
+ log('+3 VP')
+ game.vp += 3
+ if (check_vp()) {
+ return
+ }
+ vm_next()
+ },
+ pass() {
+ push_undo()
+ logi(`Chose not to conduct support checks`)
+ permanently_remove(C_THE_CHINESE_SOLUTION)
+ vm_return()
+ }
+}
+
+states.vm_the_tyrant_is_gone = {
+ get inactive() {
+ return `resolve ${clean_name(cards[game.played_card].name)}.`
+ },
+ prompt() {
+ if (!game.the_tyrant_is_gone) {
+ view.prompt = 'The Tyrant is Gone: Select a space in Romania for the Ceausescus to flee to.'
+ for (let space_id of game.valid_spaces) {
+ if (!space_id) continue
+ gen_action_space(space_id);
+ }
+ } else {
+ view.prompt = 'The Tyrant is Gone: done.'
+ gen_action('done')
+ }
+ },
+ space(space) {
+ push_undo()
+ log(`The Ceausescus flee to %${space}`)
+ game.the_tyrant_is_gone = space
+ game.valid_spaces = []
+ },
+ done () {
+ vm_next()
+ }
+}
+
+states.vm_the_wall_must_go = {
+ get inactive() {
+ return `resolve ${clean_name(cards[this_card()].name)}.`
+ },
+ prompt() {
+ view.prompt = ('The Wall Must Go! Roll a die.')
+ gen_action('roll')
+ },
+ roll() {
+ clear_undo()
+ let attempt = game.the_wall_must_go['dem_wins'] + game.the_wall_must_go['com_wins']
+ if (game.the_wall_must_go['dem_roll'] === 0 && game.the_wall_must_go['com_roll'] === 0) {
+ log_h3(`Round ${attempt+1}`)
+ }
+
+ let roll = roll_d6()
+ log(`Roll: D${roll}`)
+ if (game.active === DEM) {
+ let controlled_spaces = spaces.filter(space => space && space.country === 'East_Germany' && check_dem_control(space.space_id)).length
+ if (controlled_spaces > 0) {
+ logi(`+${controlled_spaces} from controlled spaces in East Germany`)
+ log(`Modified roll: ${roll + controlled_spaces}`)
+ roll += controlled_spaces
+ }
+ game.the_wall_must_go['dem_roll'] = roll
+ } else {
+ let controlled_spaces = spaces.filter(space => space && space.country === 'East_Germany' && check_com_control(space.space_id)).length
+ if (controlled_spaces > 0) {
+ logi(`+${controlled_spaces} from controlled spaces in East Germany`)
+ log(`Modified roll: ${roll + controlled_spaces}`)
+ roll += controlled_spaces
+ }
+ game.the_wall_must_go['com_roll'] = roll
+
+ }
+ if (game.the_wall_must_go['dem_roll'] > 0 && game.the_wall_must_go['com_roll'] > 0) {
+ if (game.the_wall_must_go['dem_roll'] > game.the_wall_must_go['com_roll'] ) {
+ log('Democrat wins')
+ game.the_wall_must_go['dem_wins']++
+ } else if (game.the_wall_must_go['dem_roll'] === game.the_wall_must_go['com_roll'] ) {
+ log('Tie. Re-roll')
+ } else {
+ log('Communist wins')
+ game.the_wall_must_go['com_wins']++
+ }
+
+ log(`Democrat: ${game.the_wall_must_go['dem_wins']}, Communist: ${game.the_wall_must_go['com_wins']}`)
+ }
+ if (game.the_wall_must_go['dem_wins'] === 2) {
+ log('The Democrat wins C86')
+ finish_the_wall()
+ return
+ }
+ if (game.the_wall_must_go['com_wins'] === 2) {
+ log('The Communist wins C86')
+ finish_the_wall()
+ return
+ }
+ if (game.the_wall_must_go['dem_roll'] === 0 || game.the_wall_must_go['com_roll'] === 0) {
+ next_player()
+ } else {
+ game.the_wall_must_go['dem_roll'] = 0
+ game.the_wall_must_go['com_roll'] = 0
+ }
+ },
+}
+
+states.vm_warsaw_pact_summit = {
+ get inactive() {
+ return `resolve ${clean_name(cards[game.played_card].name)}.`
+ },
+ prompt() {
+ view.prompt = 'Choose to play for support checks or place SPs.'
+ gen_action('influence')
+ gen_action('support_check')
+ },
+ influence(){
+ push_undo()
+ for (let i = 0; i < spaces.length; i++) {
+ let space = spaces[i]
+ if (game.demInfl[i] === 0) {
+ game.valid_spaces.push(space.space_id);
+ }
+ }
+ game.vm_available_ops = 4
+ game.phase = 3
+ vm_next()
+ },
+ support_check(){
+ push_undo()
+ for (let i = 0; i < spaces.length; i++) {
+ let space = spaces[i]
+ if (game.demInfl[i] > 0 && (space.socio === 5 || space.socio === 6)) {
+ game.valid_spaces.push(space.space_id)
+ }
+ }
+ game.vm_available_ops = 2
+ vm_next()
+ }
+}
+
+states.vm_we_are_the_people_remove = {
+ get inactive() {
+ return `resolve ${clean_name(cards[game.played_card].name)}.`
+ },
+ prompt() {
+ if (game.demInfl[S_LUTHERAN_CHURCH] === 0 && game.vm_available_ops > 0) {
+ view.prompt = '"We are the People!": no SPs to remove.'
+ gen_action('done')
+ } else if (game.vm_available_ops > 0 ) {
+ view.prompt = '"We are the People!": remove up to 4 SPs from the Lutherian Church.'
+ gen_action('done')
+ for (let space_id of game.valid_spaces) {
+ gen_action_space(space_id);
+ }
+ } else {
+ view.prompt = '"We are the People!" Remove SPs: done.'
+ gen_action('done')
+ }
+ },
+ space(space) {
+ remove_infl(space, 'vm_available_ops')
+ if (game.vm_influence_added[S_LUTHERAN_CHURCH] === 4) {
+ game.valid_spaces = [...S_EAST_GERMANY]
+ game.state = 'vm_we_are_the_people_add'
+ }
+ },
+ done() {
+ do_log_summary()
+ if (!game.vm_influence_added[S_LUTHERAN_CHURCH]) {
+ log('No SPs removed')
+ vm_next()
+ } else {
+ game.valid_spaces = [...S_EAST_GERMANY]
+ game.state = 'vm_we_are_the_people_add'
+ }
+ }
+}
+states.vm_we_are_the_people_add = {
+ get inactive() {
+ return `resolve ${clean_name(cards[game.played_card].name)}.`
+ },
+ prompt() {
+ view.prompt = `"We are the People!": you must add the ${pluralize(game.vm_influence_added[S_LUTHERAN_CHURCH],'SP')} to spaces in Germany.`
+ for (let space_id of game.valid_spaces) {
+ gen_action_space(space_id);
+ }
+ },
+ space(space) {
+ vm_do_add_infl_free(space)
+ game.vm_influence_added[S_LUTHERAN_CHURCH]--
+ if (game.vm_influence_added[S_LUTHERAN_CHURCH] === 0 ) {
+ game.valid_spaces = []
+ do_log_summary()
+ vm_next()
+ }
+ },
+}
+
+states.vm_workers_revolt = {
+ get inactive() {
+ return `resolve ${clean_name(cards[game.played_card].name)}.`
+ },
+ prompt() {
+ if (game.valid_spaces.length === 0 ) {
+ view.prompt = 'Workers Revolt: no valid spaces to select.'
+ gen_action('pass')
+ return
+ }
+ view.prompt = 'Workers Revolt: select a Worker Space in a country your opponent has power.'
+ for (let space_id of game.valid_spaces) {
+ gen_action_space(space_id)
+ }
+ },
+ pass() {
+ push_undo()
+ vm_next()
+ },
+ space(space) {
+ push_undo()
+ game.selected_space = space
+ log(`Chose %${game.selected_space}`)
+ game.state = 'vm_workers_revolt_finish'
+ }
+}
+
+states.vm_workers_revolt_finish = {
+ get inactive() {
+ return `resolve ${clean_name(cards[game.played_card].name)}.`
+ },
+ prompt() {
+ view.prompt = `Target: ${spaces[game.selected_space].name_unique}. Roll a die.`
+ gen_action('roll')
+ },
+ roll() {
+ clear_undo()
+ let roll = roll_d6()
+ log(`Roll: D${roll}`)
+ let adj = count_adj(game.selected_space)
+ if (game.active === DEM) {
+ logi(`-${adj.com_adj} from opponent controlled spaces`)
+ roll -= adj.com_adj
+ } else {
+ logi(`-${adj.dem_adj} from opponent controlled spaces`)
+ roll -= adj.dem_adj
+ }
+ log(`Modified roll: ${Math.max(roll, 0)}`)
+ if (roll >= 4) {
+ log('Workers Revolt successful')
+ vm_replace_all_infl(game.selected_space)
+ } else {log('Workers Revolt fails. Required 4 or more')}
+ delete game.selected_space
+ vm_next()
+ },
+}
+// ==================== TIANANMEN SQUARE TRACK STATES =====================
+
+states.vm_tst_3_prep = {
+ inactive: 'resolve Tiananmen Square Track award.',
+ prompt() {
+ view.prompt = 'Tiananmen Square Track award: draw 3 cards.'
+ gen_action('draw')
+ },
+ draw() {
+ if (game.active === DEM) {
+ game.temp = game.democrat_hand.length
+ draw_cards(game.strategy_deck, game.democrat_hand, game.communist_hand, game.democrat_hand.length + 3, game.communist_hand.length)
+ game.valid_cards = [game.democrat_hand[game.temp], game.democrat_hand[game.temp + 1], game.democrat_hand[game.temp + 2]]
+ } else {
+ game.temp = game.communist_hand.length
+ draw_cards(game.strategy_deck, game.democrat_hand, game.communist_hand, game.democrat_hand.length, game.communist_hand.length + 3)
+ game.valid_cards = [game.communist_hand[game.temp], game.communist_hand[game.temp + 1], game.communist_hand[game.temp + 2]]
+ }
+ game.temp = 0
+ game.state = 'vm_tst_3'
+ }
+}
+
+states.vm_tst_3 = {
+ inactive: 'resolve Tiananmen Square Track bonus.',
+ prompt() {
+ if (game.temp < 2) {
+ view.prompt = `Discard 2 of the drawn cards.`
+ for (let card of game.valid_cards) {
+ gen_action_card(card)
+ }
+ }
+ },
+ card(card) {
+ push_undo()
+ discard(card)
+ game.temp ++
+ if (game.temp === 2) {
+ game.valid_cards = []
+ vm_next()
+ }
+ },
+}
+
+states.vm_tst_4 = {
+ inactive: 'remove SPs',
+ prompt () {
+ if (game.vm_available_ops === 0 || game.valid_spaces.length === 0) {
+ view.prompt = 'Tiananmen Square Track award. Remove SPs: done.'
+ gen_action('done')
+ return
+ }
+ view.prompt = `Tiananmen Square Track award: remove ${pluralize(game.vm_available_ops,'SP')}.`
+
+ for (let space_id of game.valid_spaces) {
+ gen_action_space(space_id);
+ }
+ },
+ space(space) {
+ remove_infl(space, 'vm_available_ops')
+ if (game.vm_available_ops === 0) {
+ do_log_summary()
+ vm_next()
+ }
+ },
+ done() {
+ do_log_summary()
+ vm_next()
+ }
+}
+
+states.vm_tst_6 = {
+ inactive: 'make their free support check.',
+ prompt() {
+ view.prompt = 'Tiananmen Square Track award: you have a free 2 Ops support check.'
+ for (let space_id of game.valid_spaces) {
+ if (space_id) {
+ gen_action_space(space_id);
+ }
+ }
+ },
+ space(space) {
+ push_undo()
+ game.selected_space = space
+ if (game.active === DEM && game.persistent_events.includes(C_AUSTRIA_HUNGARY_BORDER_REOPENED) && spaces[space].country === "East_Germany") {
+ game.austria_hungary_border_reopened_tracker = true
+ }
+ game.state = 'vm_tst_6_sc'
+ },
+}
+
+states.vm_tst_6_sc = {
+ inactive: 'do support check.',
+ prompt () {
+ view.prompt = `Support check: ${spaces[game.selected_space].name_unique}. Roll a die`
+ gen_action('roll')
+ },
+ roll() {
+ clear_undo()
+ do_sc(game.selected_space)
+ game.vm_available_ops--
+ game.valid_spaces = []
+ game.state = 'vm_tst_6'
+ vm_next()
+ return
+ }
+}
+
+states.vm_tst_8 = {
+ inactive: 'use Tiananmen Square Track award.',
+ prompt() {
+ if (game.vm_event_to_do && game.vm_infl_to_do) {
+ view.prompt = 'Choose whether to play for event or operations first.'
+ gen_action('event')
+ gen_action('ops')
+ }
+ else if (!game.vm_event_to_do && game.vm_infl_to_do) {
+ view.prompt = 'Event resolved. Use card for operations.'
+ gen_action('ops')
+ }
+ else if (game.vm_event_to_do && !game.vm_infl_to_do) {
+ view.prompt = 'Operations resolved. Use card for event.'
+ gen_action('event')
+ }
+ else if (!game.vm_event_to_do && !game.vm_infl_to_do) {
+ view.prompt = 'Event and operations: done.'
+ gen_action('end_round')
+ }
+ },
+ event() {
+ push_undo()
+ log(`C${game.played_card}:`)
+ game.vm_event_to_do = false
+ game.return_state = 'vm_tst_8'
+ game.return = game.active
+ game.vm_event = game.played_card
+ goto_vm(game.vm_event)
+ },
+ ops() {
+ push_undo()
+ log('Operations')
+ game.vm_infl_to_do = false
+ game.return = game.active
+ game.return_state = 'vm_tst_8'
+ goto_vm(208)
+ },
+ end_round() {
+ push_undo()
+ game.tst_8 = true
+ end_round()
+ }
+}
+
+states.vm_tst_8_ops = {
+ inactive: 'play card for operations.',
+ prompt() {
+ view.prompt = `Play ${clean_name(cards[game.played_card].name)} for:`
+ gen_action('influence')
+ gen_action('support_check')
+ if ((game.active === DEM && game.dem_tst_attempted_this_turn === 0 ) || (game.active === COM && game.com_tst_attempted_this_turn === 0 )) {
+ gen_action('tst')
+ }
+ },
+ influence(){
+ push_undo()
+ game.vm_available_ops = cards[game.played_card].ops
+ valid_spaces_infl()
+ // If ABHR - Set AHBR tracker to true
+ if (game.persistent_events.includes(C_AUSTRIA_HUNGARY_BORDER_REOPENED)) {
+ game.austria_hungary_border_reopened_tracker = true
+ }
+ game.state = 'vm_add_infl'
+ },
+ support_check() {
+ push_undo()
+ game.vm_available_ops = 2
+ game.state = 'vm_support_check_prep'
+ },
+ tst() {
+ push_undo()
+ game.state = 'vm_tiananmen_square_attempt'
+ }
+}
+
+// ========================= POWER STRUGGLE STATES ========================
+
+states.vm_scare_tactics = {
+ inactive: 'remove a Support Point.',
+ prompt () {
+ if (game.valid_spaces.length === 0 && game.vm_available_ops > 0) {
+ view.prompt = `${clean_name(cards[this_card()].name)}: no SPs to remove.`
+ gen_action('done')
+ return
+ }
+ if (game.vm_available_ops === 0 ) {
+ view.prompt = `${clean_name(cards[this_card()].name)}. Remove SPs: done.`
+ gen_action('done')
+ return
+ }
+ view.prompt = `${clean_name(cards[this_card()].name)}: remove ${pluralize(game.vm_available_ops, 'opponent SP')}${event_prompt()}.`
+ for (let space_id of game.valid_spaces) {
+ gen_action_space(space_id);
+ }
+ },
+ space(space) {
+ push_undo()
+ remove_infl(space, 'vm_available_ops')
+ },
+ done() {
+ do_log_summary()
+ vm_next()
+ }
+}
+
+states.vm_support_surges_1 = {
+ inactive: 'draw cards.',
+ prompt() {
+ view.prompt = 'Support Surges: draw a card.'
+ gen_action('draw')
+ },
+ draw() {
+ if (game.active === DEM) {
+ draw_cards(game.power_struggle_deck, game.dem_pwr_hand, game.com_pwr_hand, game.dem_pwr_hand.length+1, game.com_pwr_hand.length)
+ game.temp = game.dem_pwr_hand[game.dem_pwr_hand.length-1]
+ } else {
+ draw_cards(game.power_struggle_deck, game.dem_pwr_hand, game.com_pwr_hand, game.dem_pwr_hand.length, game.com_pwr_hand.length+1)
+ game.temp = game.com_pwr_hand[game.com_pwr_hand.length-1]
+ }
+ game.state = 'vm_support_surges_2'
+ }
+}
+
+states.vm_support_surges_2 = {
+ inactive: 'draw cards.',
+ prompt() {
+ if (wildcards.includes(game.temp)) {
+ view.prompt = `Support Surges: you drew ${power_cards[game.temp].name}. Draw a second card.`
+ }
+ else if (elite_leaders.includes(game.temp)) {
+ view.prompt = `Support Surges: you drew an ${power_cards[game.temp].name}. Draw a second card.`
+ }
+ else if (numberless_cards.includes(game.temp)) {
+ view.prompt = `Support Surges: you drew a ${power_cards[game.temp].name}. Draw a second card.`
+ } else {
+ view.prompt = `Support Surges: you drew a ${power_cards[game.temp].name} ${power_cards[game.temp].value}. Draw a second card.`
+ }
+ gen_action('draw')
+ },
+ draw() {
+ if (game.active === DEM) {
+ draw_cards(game.power_struggle_deck, game.dem_pwr_hand, game.com_pwr_hand, game.dem_pwr_hand.length+1, game.com_pwr_hand.length)
+ game.temp = game.dem_pwr_hand[game.dem_pwr_hand.length - 1]
+ } else {
+ draw_cards(game.power_struggle_deck, game.dem_pwr_hand, game.com_pwr_hand, game.dem_pwr_hand.length, game.com_pwr_hand.length+1)
+ game.temp = game.com_pwr_hand[game.com_pwr_hand.length - 1]
+ }
+ game.state = 'vm_support_surges_3'
+ }
+}
+
+states.vm_support_surges_3 = {
+ inactive: 'draw cards.',
+ prompt() {
+ if (wildcards.includes(game.temp)) {
+ view.prompt = `Support Surges: you drew ${power_cards[game.temp].name}. Done.`
+ }
+ else if (elite_leaders.includes(game.temp)) {
+ view.prompt = `Support Surges: you drew an ${power_cards[game.temp].name}. Done.`
+ }
+ else if (numberless_cards.includes(game.temp)) {
+ view.prompt = `Support Surges: you drew a ${power_cards[game.temp].name}. Done.`
+ } else {
+ view.prompt = `Support Surges: you drew a ${power_cards[game.temp].name} ${power_cards[game.temp].value}. Done.`
+ }
+ gen_action('done')
+ },
+ done() {
+ game.phase = 0
+ delete game.temp
+ log('Drew 2 cards')
+ log('Surrenders initiative')
+ vm_next()
+ }
+}
+
+states.vm_support_falters = {
+ inactive: 'discard cards.',
+ prompt() {
+ if ((game.active === DEM && game.dem_pwr_hand.length === 0) || (game.active === COM && game.com_pwr_hand.length === 0)) {
+ view.prompt = 'Support Falters: no remaining cards to discard.'
+ gen_action('pass')
+ } else if (game.vm_available_ops > 0) {
+ view.prompt = 'Support Falters: discard a card.'
+ gen_action('discard')
+ } else {
+ view.prompt = 'Support Falters: done.'
+ gen_action('done')
+ }
+ },
+ discard() {
+ if (game.active === DEM) {discard_card(game.dem_pwr_hand)}
+ else {discard_card(game.com_pwr_hand)}
+ game.vm_available_ops --
+ },
+ pass() {
+ log_msg_gap('Takes initiative')
+ game.return = game.active
+ vm_next()
+ },
+ done() {
+ log_gap('Takes initiative')
+ game.return = game.active
+ vm_next()
+ }
+}
+
+/* =================== EVENTS ================================ */
+
+// #region GENERATED EVENT CODE
+const CODE = []
+
+CODE[1] = [ // Legacy of Martial Law*
+ [ vm_permanently_remove ],
+ [ vm_valid_spaces_country_opp, 'Poland' ],
+ [ vm_prompt, 'replace 1 Democratic SP in Poland with a Communist SP' ],
+ [ vm_legacy_of_martial_law ],
+ [ vm_valid_spaces_country_sc, 'Poland' ],
+ [ vm_prompt, 'make a Support Check in Poland' ],
+ [ vm_1_support_check ],
+ [ vm_return ],
+]
+
+CODE[2] = [ // Solidarity Legalised*
+ [ vm_solidarity_legalised ],
+ [ vm_valid_spaces_solidarity_legalised ],
+ [ vm_prompt, 'to every uncontrolled Worker and Farmer space in Poland' ],
+ [ vm_add_limited_infl, 9, 1 ],
+ [ vm_return ],
+]
+
+CODE[3] = [ // Walesa
+ [ vm_permanently_remove ],
+ [ vm_valid_spaces_country, 'Poland' ],
+ [ vm_prompt, 'any space(s) in Poland' ],
+ [ vm_add_infl_free, 4 ],
+ [ vm_valid_spaces_country_sc, 'Poland' ],
+ [ vm_prompt, 'make Support Checks in Poland' ],
+ [ vm_support_check, 2 ],
+ [ vm_return ],
+]
+
+CODE[4] = [ // Michnik
+ [ vm_permanently_remove ],
+ [ vm_valid_spaces, 'Polish Writers' ],
+ [ vm_prompt, 'the Polish Intellectuals space' ],
+ [ vm_add_x_infl, 3 ],
+ [ vm_return ],
+]
+
+CODE[5] = [ // General strike
+ [ vm_general_strike ],
+ [ vm_return ],
+]
+
+CODE[6] = [ // Brought in for Questioning
+ [ vm_if, ()=>!is_auto_resolve(C_BROUGHT_IN_FOR_QUESTIONING) ],
+ [ vm_brought_in_for_questioning ],
+ [ vm_endif ],
+ [ vm_return ],
+]
+
+CODE[7] = [ // State Run Media*
+ [ vm_permanently_remove ],
+ [ vm_valid_spaces_opponent ],
+ [ vm_remove_limited_opp_infl, 4, 2 ],
+ [ vm_return ],
+]
+
+CODE[8] = [ // Prudence
+ [ vm_prudence ],
+ [ vm_return ],
+]
+
+CODE[9] = [ // The Wall*
+ [ vm_the_wall ],
+ [ vm_return ],
+]
+
+CODE[10] = [ // Cult of Personality
+ [ vm_permanently_remove ],
+ [ vm_if, ()=>!game.persistent_events.includes(THE_TYRANT_IS_GONE_OCCURRED) ],
+ [ vm_valid_spaces_country_socio_2, 'Romania', 3, 4 ],
+ [ vm_prompt, 'Worker or Farmer spaces in Romania, no more than 2 per space' ],
+ [ vm_add_limited_infl, 4, 2 ],
+ [ vm_else ],
+ [ vm_tyrant_block ],
+ [ vm_endif ],
+ [ vm_return ],
+]
+
+CODE[11] = [ // Dissident arrested
+ [ vm_if, ()=>!is_auto_resolve(C_DISSIDENT_ARRESTED) ],
+ [ vm_valid_spaces_opponent_socio, 5 ],
+ [ vm_prompt, 'any Intellectuals space' ],
+ [ vm_remove_x_opp_infl, 2 ],
+ [ vm_endif ],
+ [ vm_return ],
+]
+
+CODE[12] = [ // Apparatchicks
+ [ vm_permanently_remove ],
+ [ vm_valid_spaces_socio, 2 ],
+ [ vm_prompt, ' to any Bureaucratic space(s)' ],
+ [ vm_add_infl_free, 3 ],
+ [ vm_return ],
+]
+
+CODE[13] = [ // Stasi
+ [ vm_stasi ],
+ [ vm_return ],
+]
+
+CODE[14] = [ // Gorbachev Charms the West
+ [ vm_valid_spaces_opponent ],
+ [ vm_remove_opp_infl, 2 ],
+ [ vm_valid_spaces_sc ],
+ [ vm_prompt, 'select a space for the Support Check' ],
+ [ vm_1_support_check ],
+ [ vm_return ],
+]
+
+CODE[15] = [ // Honecker
+ [ vm_honecker ],
+ [ vm_return ],
+]
+
+CODE[16] = [ // Nomenklatura*
+ [ vm_permanently_remove ],
+ [ vm_nomenklatura ],
+ [ vm_return ],
+]
+
+CODE[17] = [ // Roundtable talks
+ [ vm_roundtable_talks ],
+ [ vm_return ],
+]
+
+CODE[18] = [ // Poszgay Defends the Revolution
+ [ vm_permanently_remove ],
+ [ vm_poszgay ],
+ [ vm_prompt, 'to 4 spaces in Hungary not under Democratic control' ],
+ [ vm_add_limited_infl, 4, 1 ],
+ [ vm_return ],
+]
+
+CODE[19] = [ // Papal vist
+ [ vm_permanently_remove ],
+ [ vm_valid_spaces, 'Catholic Church, Poland', 'Catholic Church, Czechoslovakia', 'Catholic Church, Hungary' ],
+ [ vm_prompt, 'any Catholic Church space' ],
+ [ vm_add_x_infl, 3 ],
+ [ vm_return ],
+]
+
+CODE[20] = [ // Deutsche Marks*
+ [ vm_permanently_remove ],
+ [ vm_if, ()=>!is_auto_resolve(C_DEUTSCHE_MARKS) ],
+ [ vm_deutsche_marks ],
+ [ vm_endif ],
+ [ vm_return ],
+]
+
+CODE[21] = [ // Common European Home
+ [ vm_common_european_home ],
+ [ vm_return ],
+]
+
+CODE[22] = [ // Power Struggle - Poland
+ [ vm_power_struggle ],
+ [ vm_return ],
+]
+
+CODE[23] = [ // Power Struggle - Hungary
+ [ vm_power_struggle ],
+ [ vm_return ],
+]
+
+CODE[24] = [ // St Nicolas Church
+ [ vm_if, ()=>!check_dem_control(S_LUTHERAN_CHURCH) ],
+ [ vm_valid_spaces, 'Lutheran Church' ],
+ [ vm_prompt, 'the Lutheran Church' ],
+ [ vm_take_control_prep, 1 ],
+ [ vm_endif ],
+ [ vm_st_nicholas_church ],
+ [ vm_return ],
+]
+
+CODE[25] = [ // Perestroika
+ [ vm_perestroika ],
+ [ vm_return ],
+]
+
+CODE[26] = [ // Helsinki Final Act*
+ [ vm_helsinki_final_act ],
+ [ vm_return ],
+]
+
+CODE[27] = [ // Consumerism
+ [ vm_valid_spaces_opponent_socio, 4 ],
+ [ vm_prompt, ' from a Worker space' ],
+ [ vm_remove_opp_infl, 1 ],
+ [ vm_valid_spaces_opponent_socio, 4 ],
+ [ vm_active_country ],
+ [ vm_prompt, ()=>`make a support check in a Worker space in ${country_name(game.vm_active_country)}` ],
+ [ vm_1_support_check ],
+ [ vm_return ],
+]
+
+CODE[28] = [ // Factory Party Cells
+ [ vm_valid_spaces_opponent_socio, 4 ],
+ [ vm_prompt, ' from Worker spaces' ],
+ [ vm_remove_limited_opp_infl, 3, 2 ],
+ [ vm_return ],
+]
+
+CODE[29] = [ // Jan Palach Week*
+ [ vm_permanently_remove ],
+ [ vm_valid_spaces, 'Charles University' ],
+ [ vm_prompt, 'the Charles University space' ],
+ [ vm_add_x_infl, 6 ],
+ [ vm_return ],
+]
+
+CODE[30] = [ // Tear Gas
+ [ vm_tear_gas ],
+ [ vm_return ],
+]
+
+CODE[31] = [ // Intelligentsia
+ [ vm_valid_spaces_socio, 5 ],
+ [ vm_prompt, 'Intellectual spaces, no more than 2 per space' ],
+ [ vm_add_limited_infl, 4, 2 ],
+ [ vm_return ],
+]
+
+CODE[32] = [ // Peasant Parties*
+ [ vm_permanently_remove ],
+ [ vm_valid_spaces_socio, 3 ],
+ [ vm_prompt, 'Farmer spaces, no more than 2 per space' ],
+ [ vm_add_limited_infl, 4, 2 ],
+ [ vm_return ],
+]
+
+CODE[33] = [ // Sajudis*
+ [ vm_permanently_remove ],
+ [ vm_sajudis ],
+ [ vm_if, ()=>!is_auto_resolve(C_SAJUDIS) ],
+ [ vm_sajudis_check ],
+ [ vm_prompt, 'any Minorities space' ],
+ [ vm_take_control_prep, 1 ],
+ [ vm_endif ],
+ [ vm_return ],
+]
+
+CODE[34] = [ // Fidesz*
+ [ vm_permanently_remove ],
+ [ vm_valid_spaces, 'Eotvos Lorand University' ],
+ [ vm_prompt, 'the Hungary students space' ],
+ [ vm_add_x_infl, 5 ],
+ [ vm_return ],
+]
+
+CODE[35] = [ // Heal our Bleeding Wounds*
+ [ vm_permanently_remove ],
+ [ vm_heal_our_bleeding_wounds ],
+ [ vm_return ],
+]
+
+CODE[36] = [ // Dash for the West*
+ [ vm_permanently_remove ],
+ [ vm_prompt, 'Dash for the West: select any Democratic Event with an asterix(*) from the discard pile. Event occurs immediately' ],
+ [ vm_dash_for_the_west ],
+ [ vm_return ],
+]
+
+CODE[37] = [ // Nagy Reburied*
+ [ vm_permanently_remove ],
+ [ vm_nagy_reburied ],
+ [ vm_prompt, 'the Hungary Elite space' ],
+ [ vm_remove_all_infl, 1 ],
+ [ vm_valid_spaces_country, 'Hungary' ],
+ [ vm_prompt, 'Hungary, no more than 2 per space' ],
+ [ vm_add_limited_infl, 4, 2 ],
+ [ vm_return ],
+]
+
+CODE[38] = [ // July Concept
+ [ vm_permanently_remove ],
+ [ vm_valid_spaces_country, 'Bulgaria' ],
+ [ vm_prompt, 'Bulgaria' ],
+ [ vm_add_infl_free, 3 ],
+ [ vm_return ],
+]
+
+CODE[39] = [ // Eco-Glasnost*
+ [ vm_valid_spaces, 'Ruse' ],
+ [ vm_prompt, 'Ruse' ],
+ [ vm_add_x_infl, 4 ],
+ [ vm_eco_glasnost ],
+ [ vm_return ],
+]
+
+CODE[40] = [ // Hungarian Democratic Forum
+ [ vm_permanently_remove ],
+ [ vm_valid_spaces_country, 'Hungary' ],
+ [ vm_prompt, 'Hungary' ],
+ [ vm_add_infl_free, 3 ],
+ [ vm_valid_spaces_country_sc, 'Hungary' ],
+ [ vm_prompt, 'make a Support Check in Hungary' ],
+ [ vm_1_support_check ],
+ [ vm_return ],
+]
+
+CODE[41] = [ // Ceausescu*
+ [ vm_permanently_remove ],
+ [ vm_if, ()=>game.persistent_events.includes(THE_TYRANT_IS_GONE_OCCURRED) ],
+ [ vm_tyrant_block ],
+ [ vm_else ],
+ [ vm_if, ()=>!is_auto_resolve(C_CEAUSESCU) ],
+ [ vm_valid_spaces_country_opp, 'Romania' ],
+ [ vm_prompt, ' from Romania' ],
+ [ vm_remove_opp_infl, 3 ],
+ [ vm_valid_spaces_country_sc, 'Romania' ],
+ [ vm_prompt, 'make a support check in Romania' ],
+ [ vm_1_support_check ],
+ [ vm_prompt, ' from Bucharesti' ],
+ [ vm_ceausescu ],
+ [ vm_endif ],
+ [ vm_return ],
+]
+
+CODE[42] = [ // Power Struggle - East Germany
+ [ vm_power_struggle ],
+ [ vm_return ],
+]
+
+CODE[43] = [ // Power Struggle - Bulgaria
+ [ vm_power_struggle ],
+ [ vm_return ],
+]
+
+CODE[44] = [ // Inflationary Currency
+ [ vm_permanently_remove ],
+ [ vm_inflationary_currency ],
+ [ vm_valid_spaces_country_opp ],
+ [ vm_prompt, ()=>` from ${country_name(game.vm_active_country)}` ],
+ [ vm_remove_opp_infl, 2 ],
+ [ vm_inflationary_currency_discard ],
+ [ vm_if, ()=>!discarded_card() ],
+ [ vm_valid_spaces_country_sc ],
+ [ vm_prompt, ()=>`make a Support Check in ${country_name(game.vm_active_country)}` ],
+ [ vm_1_support_check ],
+ [ vm_endif ],
+ [ vm_return ],
+]
+
+CODE[45] = [ // Soviet Troop Withdrawals*
+ [ vm_permanently_remove ],
+ [ vm_valid_spaces_region_opp, 'Eastern Europe' ],
+ [ vm_prompt, ' from Eastern Europe' ],
+ [ vm_remove_limited_opp_infl, 5, 2 ],
+ [ vm_return ],
+]
+
+CODE[46] = [ // Goodbye Lenin!*
+ [ vm_permanently_remove ],
+ [ vm_goodbye_lenin ],
+ [ vm_return ],
+]
+
+CODE[47] = [ // Bulgarian Turks Expelled*
+ [ vm_permanently_remove ],
+ [ vm_bulgarian_turks_expelled ],
+ [ vm_if, ()=>!is_auto_resolve(C_BULGARIAN_TURKS_EXPELLED) ],
+ [ vm_valid_spaces, 'Razgrad' ],
+ [ vm_prompt, 'Razgrad' ],
+ [ vm_remove_all_infl, 1 ],
+ [ vm_endif ],
+ [ vm_return ],
+]
+
+CODE[48] = [ // We are the People!*
+ [ vm_if, ()=>!is_auto_resolve(C_WE_ARE_THE_PEOPLE) ],
+ [ vm_we_are_the_people ],
+ [ vm_endif ],
+ [ vm_return ],
+]
+
+CODE[49] = [ // Foreign Currency Debt Burden*
+ [ vm_foreign_currency_debt_burden ],
+ [ vm_logi, ()=>`Communist cannot make Support Checks in ${country_name(game.foreign_currency_debt_burden)} for the rest of the turn` ],
+ [ vm_return ],
+]
+
+CODE[50] = [ // The Sinatra Doctrine*
+ [ vm_the_sinatra_doctrine ],
+ [ vm_return ],
+]
+
+CODE[51] = [ // 40th Anniversary Celebration*
+ [ vm_permanently_remove ],
+ [ vm_40th_anniversary_celebration ],
+ [ vm_valid_spaces_country, 'East_Germany' ],
+ [ vm_prompt, 'East Germany' ],
+ [ vm_add_infl_free ],
+ [ vm_40th_anniversary_celebration_vp ],
+ [ vm_return ],
+]
+
+CODE[52] = [ // Normalization
+ [ vm_permanently_remove ],
+ [ vm_if, ()=>!is_auto_resolve(C_NORMALIZATION) ],
+ [ vm_normalization ],
+ [ vm_prompt, 'the Czechoslovakia Elite and Bureaucrat Spaces' ],
+ [ vm_remove_all_infl, 2 ],
+ [ vm_endif ],
+ [ vm_return ],
+]
+
+CODE[53] = [ // Li Peng*
+ [ vm_li_peng ],
+ [ vm_return ],
+]
+
+CODE[54] = [ // The Crowd Turns Against Ceausescu*
+ [ vm_the_crowd_turns_against_ceausescu ],
+ [ vm_return ],
+]
+
+CODE[55] = [ // Power Struggle - Czechoslovakia
+ [ vm_power_struggle ],
+ [ vm_return ],
+]
+
+CODE[56] = [ // Foreign Television
+ [ vm_permanently_remove ],
+ [ vm_foreign_television ],
+ [ vm_remove_limited_opp_infl, 4, 2 ],
+ [ vm_return ],
+]
+
+CODE[57] = [ // Central Committee Reshuffle*
+ [ vm_permanently_remove ],
+ [ vm_central_committee_reshuffle ],
+ [ vm_prompt, ()=>`${country_name(game.vm_active_country)}` ],
+ [ vm_add_infl_free, 3 ],
+ [ vm_return ],
+]
+
+CODE[58] = [ // Austria-Hungary Border Reopened*
+ [ vm_austria_hungary_border_reopened ],
+ [ vm_return ],
+]
+
+CODE[59] = [ // Grenztruppen*
+ [ vm_grenztruppen ],
+ [ vm_return ],
+]
+
+CODE[60] = [ // Toxic Waste*
+ [ vm_permanently_remove ],
+ [ vm_valid_spaces_socio, 4 ],
+ [ vm_prompt, 'any Worker space(s)' ],
+ [ vm_add_infl_free, 3 ],
+ [ vm_return ],
+]
+
+CODE[61] = [ // The Monday Demonstrations*
+ [ vm_permanently_remove ],
+ [ vm_the_monday_demonstrations ],
+ [ vm_prompt, 'the Lutheran Church Space and Leipzig' ],
+ [ vm_take_control_prep, 2 ],
+ [ vm_valid_spaces_country_sc, 'East_Germany' ],
+ [ vm_prompt, 'make 5 Support Checks in East Germany' ],
+ [ vm_support_check, 5 ],
+ [ vm_return ],
+]
+
+CODE[62] = [ // Yakovlev Counsels Gorbachev*
+ [ vm_yakovlev_counsels_gorbachev ],
+ [ vm_return ],
+]
+
+CODE[63] = [ // Genscher*
+ [ vm_genscher ],
+ [ vm_return ],
+]
+
+CODE[64] = [ // Legacy of 1968*
+ [ vm_permanently_remove ],
+ [ vm_legacy_of_1968 ],
+ [ vm_prompt, 'all spaces in Czechoslovakia not controlled by the Communist Player' ],
+ [ vm_add_limited_infl, 11, 1 ],
+ [ vm_return ],
+]
+
+CODE[65] = [ // Presidential Visit*
+ [ vm_presidential_visit ],
+ [ vm_return ],
+]
+
+CODE[66] = [ // New Forum
+ [ vm_permanently_remove ],
+ [ vm_valid_spaces_country, 'East_Germany' ],
+ [ vm_prompt, '3 spaces in East Germany' ],
+ [ vm_add_limited_infl, 3, 1 ],
+ [ vm_return ],
+]
+
+CODE[67] = [ // Reformer Rehabilitated*
+ [ vm_prompt, 'Reformer Rehabilitated: chose any non-scoring card in the discard pile. Event takes place immediately' ],
+ [ vm_reformer_rehabilitated ],
+ [ vm_return ],
+]
+
+CODE[68] = [ // Klaus and Komarek*
+ [ vm_permanently_remove ],
+ [ vm_klaus_and_komarek ],
+ [ vm_prompt, 'Prague' ],
+ [ vm_remove_x_opp_infl, 2 ],
+ [ vm_valid_spaces, 'Praha' ],
+ [ vm_add_x_infl, 2 ],
+ [ vm_return ],
+]
+
+CODE[69] = [ // Systematization*
+ [ vm_if, ()=>!game.persistent_events.includes(THE_TYRANT_IS_GONE_OCCURRED) ],
+ [ vm_valid_spaces_country, 'Romania' ],
+ [ vm_systematization ],
+ [ vm_else ],
+ [ vm_tyrant_block ],
+ [ vm_endif ],
+ [ vm_return ],
+]
+
+CODE[70] = [ // Securitate*
+ [ vm_if, ()=>!game.persistent_events.includes(C_ARMY_BACKS_REVOLUTION) ],
+ [ vm_securitate ],
+ [ vm_else ],
+ [ vm_army_block ],
+ [ vm_endif ],
+ [ vm_return ],
+]
+
+CODE[71] = [ // Kiss of Death*
+ [ vm_permanently_remove ],
+ [ vm_if, ()=>!is_auto_resolve(C_KISS_OF_DEATH) ],
+ [ vm_kiss_of_death ],
+ [ vm_endif ],
+ [ vm_return ],
+]
+
+CODE[72] = [ // Peasant Parties Revolt
+ [ vm_peasant_parties_revolt ],
+ [ vm_return ],
+]
+
+CODE[73] = [ // Laszlo Tokes*
+ [ vm_valid_spaces, 'Timisoara', 'Harghita/Covasna' ],
+ [ vm_prompt, 'in Timisoara and Harghita/Covasna' ],
+ [ vm_add_limited_infl, 2, 1 ],
+ [ vm_laszlo_tokes ],
+ [ vm_if, ()=>game.phase === 3 ],
+ [ vm_prompt, ' in Romania' ],
+ [ vm_add_infl ],
+ [ vm_else ],
+ [ vm_prompt, 'make 2 Support Checks in Romania' ],
+ [ vm_support_check, 2 ],
+ [ vm_endif ],
+ [ vm_return ],
+]
+
+CODE[74] = [ // FRG Embassies
+ [ vm_frg_embassies ],
+ [ vm_return ],
+]
+
+CODE[75] = [ // Exit Visas*
+ [ vm_permanently_remove ],
+ [ vm_if, ()=>!is_auto_resolve(C_EXIT_VISAS) ],
+ [ vm_exit_visas ],
+ [ vm_endif ],
+ [ vm_return ],
+]
+
+CODE[76] = [ // Warsaw Pact Summit
+ [ vm_permanently_remove ],
+ [ vm_warsaw_pact_summit ],
+ [ vm_if, ()=>game.phase === 3 ],
+ [ vm_prompt, ' spaces with no Democratic SPs' ],
+ [ vm_add_infl_free, 4 ],
+ [ vm_else ],
+ [ vm_prompt, 'Select a Student or Intellectual space' ],
+ [ vm_valid_spaces_country_socio_2, 3, 4 ],
+ [ vm_support_check_modified, 2, 2 ],
+ [ vm_endif ],
+ [ vm_return ],
+]
+
+CODE[77] = [ // Samizdat
+ [ vm_permanently_remove ],
+ [ vm_if, ()=>!is_auto_resolve(C_SAMIZDAT) ],
+ [ vm_samizdat ],
+ [ vm_endif ],
+ [ vm_return ],
+]
+
+CODE[78] = [ // Workers Revolt
+ [ vm_workers_revolt ],
+ [ vm_return ],
+]
+
+CODE[79] = [ // The Third Way*
+ [ vm_permanently_remove ],
+ [ vm_the_third_way ],
+ [ vm_valid_spaces, 'German Writers' ],
+ [ vm_prompt, 'the East German Writers space' ],
+ [ vm_add_x_infl, 3 ],
+ [ vm_return ],
+]
+
+CODE[80] = [ // Nepotism*
+ [ vm_permanently_remove ],
+ [ vm_nepotism ],
+ [ vm_valid_spaces_region_socio, 'Balkans', 4 ],
+ [ vm_prompt, 'Worker spaces in the Balkans' ],
+ [ vm_add_infl_free ],
+ [ vm_return ],
+]
+
+CODE[81] = [ // The Baltic Way*
+ [ vm_permanently_remove ],
+ [ vm_the_baltic_way_prep ],
+ [ vm_if, ()=>!is_auto_resolve(C_THE_BALTIC_WAY) ],
+ [ vm_the_baltic_way ],
+ [ vm_prompt, 'any Minorities space' ],
+ [ vm_take_control_prep, 1 ],
+ [ vm_endif ],
+ [ vm_return ],
+]
+
+CODE[82] = [ // Spitzel*
+ [ vm_permanently_remove ],
+ [ vm_if, ()=>!is_auto_resolve(C_SPITZEL) ],
+ [ vm_valid_spaces_country_opp, 'East_Germany' ],
+ [ vm_prompt, ' from East Germany' ],
+ [ vm_remove_opp_infl, 2 ],
+ [ vm_endif ],
+ [ vm_return ],
+]
+
+CODE[83] = [ // Modrow*
+ [ vm_modrow ],
+ [ vm_valid_spaces_country, 'East_Germany' ],
+ [ vm_prompt, 'East Germany, no more than 2 per space' ],
+ [ vm_add_limited_infl, 4, 2 ],
+ [ vm_return ],
+]
+
+CODE[84] = [ // Breakaway Baltic Republics*
+ [ vm_permanently_remove ],
+ [ vm_breakaway_baltic_republics ],
+ [ vm_prompt, 'any Minorities space' ],
+ [ vm_take_control_prep, 1 ],
+ [ vm_valid_spaces_sc ],
+ [ vm_prompt, 'select a space for the support check' ],
+ [ vm_1_support_check ],
+ [ vm_return ],
+]
+
+CODE[85] = [ // Tank Column/Tank Man*
+ [ vm_permanently_remove ],
+ [ vm_tank_column ],
+ [ vm_return ],
+]
+
+CODE[86] = [ // The Wall Must Go!*
+ [ vm_the_wall_must_go ],
+ [ vm_remove_infl, 3 ],
+ [ vm_return ],
+]
+
+CODE[87] = [ // Kohl Proposes Reunification*
+ [ vm_permanently_remove ],
+ [ vm_kohl_proposes_reunification_prep ],
+ [ vm_if, ()=>!is_auto_resolve(C_KOHL_PROPOSES_REUNIFICATION) ],
+ [ vm_kohl_proposes_reunification ],
+ [ vm_else ],
+ [ vm_logi, ()=>`C${C_THE_WALL_MUST_GO} has not been successfully played for the event.` ],
+ [ vm_endif ],
+ [ vm_return ],
+]
+
+CODE[88] = [ // Adamec*
+ [ vm_permanently_remove ],
+ [ vm_adamec ],
+ [ vm_valid_spaces_country, 'Czechoslovakia' ],
+ [ vm_prompt, 'Czechoslovakia' ],
+ [ vm_add_limited_infl, 4, 2 ],
+ [ vm_return ],
+]
+
+CODE[89] = [ // Domino Theory*
+ [ vm_permanently_remove ],
+ [ vm_if, ()=>!is_auto_resolve(C_DOMINO_THEORY) ],
+ [ vm_prompt, 'Domino Theory: choose a Power Struggle card to play from the discard pile' ],
+ [ vm_domino_theory ],
+ [ vm_else ],
+ [ vm_domino_theory_pass ],
+ [ vm_endif ],
+ [ vm_return ],
+]
+
+CODE[90] = [ // Civic Forum*
+ [ vm_permanently_remove ],
+ [ vm_civic_forum_prep ],
+ [ vm_valid_spaces_country, 'Czechoslovakia' ],
+ [ vm_prompt, 'Czechoslovakia' ],
+ [ vm_add_infl_free, 4 ],
+ [ vm_civic_forum ],
+ [ vm_valid_spaces_country_sc, 'Czechoslovakia' ],
+ [ vm_prompt, 'Select a space in Czechoslovakia' ],
+ [ vm_support_check, 2 ],
+ [ vm_return ],
+]
+
+CODE[91] = [ // My First Banana*
+ [ vm_permanently_remove ],
+ [ vm_if, ()=>!is_auto_resolve(C_MY_FIRST_BANANA) ],
+ [ vm_valid_spaces_country_opp, 'East_Germany' ],
+ [ vm_prompt, ' from East Germany' ],
+ [ vm_remove_opp_infl, 2 ],
+ [ vm_valid_spaces_country_sc, 'East_Germany' ],
+ [ vm_prompt, 'select a space in East Germany' ],
+ [ vm_support_check, 2 ],
+ [ vm_endif ],
+ [ vm_return ],
+]
+
+CODE[92] = [ // Betrayal
+ [ vm_permanently_remove ],
+ [ vm_if, ()=>!is_auto_resolve(C_BETRAYAL) ],
+ [ vm_prompt, 'choose any Orthodox Church space. Replace all Democratic SPs with Communist SPs' ],
+ [ vm_betrayal ],
+ [ vm_endif ],
+ [ vm_return ],
+]
+
+CODE[93] = [ // Shock Therapy*
+ [ vm_permanently_remove ],
+ [ vm_shock_therapy ],
+ [ vm_valid_spaces_country ],
+ [ vm_prompt, ()=>` ${country_name(game.vm_active_country)}` ],
+ [ vm_add_infl_free, 3 ],
+ [ vm_return ],
+]
+
+CODE[94] = [ // Union of Democratic Forces*
+ [ vm_permanently_remove ],
+ [ vm_if, ()=>!is_auto_resolve(C_UNION_OF_DEMOCRATIC_FORCES) ],
+ [ vm_valid_spaces_country_opp, 'Bulgaria' ],
+ [ vm_prompt, ' from Bulgaria' ],
+ [ vm_remove_limited_opp_infl, 4, 2 ],
+ [ vm_valid_spaces_country_sc, 'Bulgaria' ],
+ [ vm_prompt, 'Make 2 Support Checks in Bulgaria' ],
+ [ vm_support_check, 2 ],
+ [ vm_endif ],
+ [ vm_return ],
+]
+
+CODE[95] = [ // Power Struggle - Romania
+ [ vm_power_struggle ],
+ [ vm_return ],
+]
+
+CODE[96] = [ // The Chinese Solution*
+ [ vm_permanently_remove ],
+ [ vm_the_chinese_solution ],
+ [ vm_valid_spaces_country_sc ],
+ [ vm_prompt, ()=>`make 5 Support Checks in ${country_name(game.vm_active_country)}` ],
+ [ vm_support_check_modified, 5, 3 ],
+ [ vm_return ],
+]
+
+CODE[97] = [ // The Tyrant is Gone*
+ [ vm_if, ()=>game.persistent_events.includes(THE_CROWD_TURNS_AGAINST_CEAUSESCU_OCCURRED) ],
+ [ vm_cluj_check ],
+ [ vm_prompt, 'the Romanian Elite Space' ],
+ [ vm_remove_x_opp_infl, 4 ],
+ [ vm_the_tyrant_is_gone ],
+ [ vm_permanently_remove ],
+ [ vm_else ],
+ [ vm_the_tyrant_is_gone_prep ],
+ [ vm_endif ],
+ [ vm_return ],
+]
+
+CODE[98] = [ // Politburo Intrigue*
+ [ vm_permanently_remove ],
+ [ vm_if, ()=>!is_auto_resolve(C_POLITBURO_INTRIGUE) ],
+ [ vm_valid_spaces_country_opp, 'Bulgaria' ],
+ [ vm_prompt, ' from Bulgaria' ],
+ [ vm_remove_limited_opp_infl, 3, 2 ],
+ [ vm_valid_spaces_country_sc, 'Bulgaria' ],
+ [ vm_prompt, 'make a support check in Bulgaria' ],
+ [ vm_1_support_check ],
+ [ vm_endif ],
+ [ vm_return ],
+]
+
+CODE[99] = [ // Ligachev*
+ [ vm_ligachev ],
+ [ vm_return ],
+]
+
+CODE[100] = [ // Stand Fast*
+ [ vm_stand_fast ],
+ [ vm_return ],
+]
+
+CODE[101] = [ // Elena*
+ [ vm_if, ()=>!game.persistent_events.includes(THE_TYRANT_IS_GONE_OCCURRED) ],
+ [ vm_valid_spaces, 'Cluj-Napoca' ],
+ [ vm_prompt, 'the Romania Elite Space' ],
+ [ vm_add_x_infl, 2 ],
+ [ vm_elena ],
+ [ vm_else ],
+ [ vm_tyrant_block ],
+ [ vm_endif ],
+ [ vm_return ],
+]
+
+CODE[102] = [ // National Salvation Front*
+ [ vm_national_salvation_front ],
+ [ vm_return ],
+]
+
+CODE[103] = [ // Government Resigns*
+ [ vm_permanently_remove ],
+ [ vm_if, ()=>!is_auto_resolve(C_GOVERNMENT_RESIGNS) ],
+ [ vm_government_resigns ],
+ [ vm_prompt, 'any uncontrolled Elite space' ],
+ [ vm_remove_all_infl, 1 ],
+ [ vm_endif ],
+ [ vm_return ],
+]
+
+CODE[104] = [ // New Year's Eve Party*
+ [ vm_new_years_eve_party ],
+ [ vm_return ],
+]
+
+CODE[105] = [ // Public Against Violence*
+ [ vm_permanently_remove ],
+ [ vm_valid_spaces, 'Kosice' ],
+ [ vm_prompt, 'Kosice' ],
+ [ vm_add_x_infl, 2 ],
+ [ vm_valid_spaces, 'Presov' ],
+ [ vm_prompt, 'Presov' ],
+ [ vm_add_x_infl, 2 ],
+ [ vm_public_against_violence ],
+ [ vm_prompt, 'Make a Support Check in Bratislava' ],
+ [ vm_support_check_modified, 1, 2 ],
+ [ vm_return ],
+]
+
+CODE[106] = [ // Social Democratic Platform Adopted*
+ [ vm_permanently_remove ],
+ [ vm_social_democratic_platform_adopted ],
+ [ vm_valid_spaces_country ],
+ [ vm_prompt, ()=>`${country_name(game.vm_active_country)}` ],
+ [ vm_add_infl_free, 2 ],
+ [ vm_valid_spaces_country_sc ],
+ [ vm_prompt, ()=>`make a Support Check in ${country_name(game.vm_active_country)}` ],
+ [ vm_1_support_check ],
+ [ vm_return ],
+]
+
+CODE[107] = [ // Massacre in Timisoara*
+ [ vm_permanently_remove ],
+ [ vm_if, ()=>!game.persistent_events.includes(THE_TYRANT_IS_GONE_OCCURRED) ],
+ [ vm_massacre_in_timisoara ],
+ [ vm_valid_spaces_country_sc, 'Romania' ],
+ [ vm_prompt, 'Make Support Checks in Romania' ],
+ [ vm_support_check_modified, 2, 2 ],
+ [ vm_else ],
+ [ vm_tyrant_block ],
+ [ vm_endif ],
+ [ vm_return ],
+]
+
+CODE[108] = [ // Army Backs Revolution*
+ [ vm_army_backs_revolution ],
+ [ vm_return ],
+]
+
+CODE[109] = [ // Kremlin Coup*
+ [ vm_permanently_remove ],
+ [ vm_kremlin_coup ],
+ [ vm_return ],
+]
+
+CODE[110] = [ // Malta Summit*
+ [ vm_permanently_remove ],
+ [ vm_malta_summit ],
+ [ vm_prompt, ' from Elite spaces' ],
+ [ vm_remove_opp_infl, 5 ],
+ [ vm_return ],
+]
+
+CODE[203] = [ // Tiananmen Square space 3 award
+ [ vm_tst_3 ],
+ [ vm_return ],
+]
+
+CODE[204] = [ // Tiananmen Square space 4 award
+ [ vm_valid_spaces_opponent ],
+ [ vm_tst_4 ],
+ [ vm_return ],
+]
+
+CODE[206] = [ // Tiananmen Square space 6
+ [ vm_valid_spaces_sc ],
+ [ vm_tst_6 ],
+ [ vm_return ],
+]
+
+CODE[208] = [ // Tiananmen Square space 8 event
+ [ vm_tst_8 ],
+ [ vm_return ],
+]
+
+CODE[349] = [ // Support Falters
+ [ vm_support_falters ],
+ [ vm_return ],
+]
+
+CODE[350] = [ // Support Surges
+ [ vm_support_surges ],
+ [ vm_return ],
+]
+
+CODE[351] = [ // Scare Tactics
+ [ vm_scare_tactics ],
+ [ vm_valid_spaces_country_opp ],
+ [ vm_prompt, ()=>` from ${country_name(game.vm_active_country)}` ],
+ [ vm_remove_opp_infl, 1 ],
+ [ vm_return ],
+]
+// #endregion