diff options
Diffstat (limited to 'rules.js')
-rw-r--r-- | rules.js | 567 |
1 files changed, 362 insertions, 205 deletions
@@ -1,5 +1,7 @@ "use strict" +// TODO: no card menu + const COMMUNE = "Commune"; const VERSAILLES = "Versailles"; @@ -134,118 +136,118 @@ const BLUE_CRISIS_TRACK = [25, 26, 27, 28] const BLUE_BONUS_CUBES = [29, 30, 31] const PRUSSIAN_COLLABORATION = [32, 33, 34] -const S_NATIONAL_ASSEMBLY = 0 -const S_ROYALISTS = 1 -const S_REPUBLICANS = 2 +const NATIONAL_ASSEMBLY = 0 +const ROYALISTS = 1 +const REPUBLICANS = 2 -const S_PRESS = 3 -const S_CATHOLIC_CHURCH = 4 -const S_SOCIAL_MOVEMENTS = 5 +const PRESS = 3 +const CATHOLIC_CHURCH = 4 +const SOCIAL_MOVEMENTS = 5 -const S_MONT_VALERIEN = 6 -const S_FORT_D_ISSY = 7 -const S_CHATEAU_DE_VINCENNES = 8 +const MONT_VALERIEN = 6 +const FORT_D_ISSY = 7 +const CHATEAU_DE_VINCENNES = 8 -const S_BUTTE_MONTMARTRE = 9 -const S_BUTTE_AUX_CAILLES = 10 -const S_PERE_LACHAISE = 11 +const BUTTE_MONTMARTRE = 9 +const BUTTE_AUX_CAILLES = 10 +const PERE_LACHAISE = 11 -const S_PRUSSIAN_OCCUPIED_TERRITORY = 12 -const S_VERSAILLES_HQ = 13 +const PRUSSIAN_OCCUPIED_TERRITORY = 12 +const VERSAILLES_HQ = 13 -const first_space = S_NATIONAL_ASSEMBLY -const last_space = S_PERE_LACHAISE +const first_space = NATIONAL_ASSEMBLY +const last_space = PERE_LACHAISE const space_count = last_space + 1 const POLITICAL = [ - S_NATIONAL_ASSEMBLY, - S_ROYALISTS, - S_REPUBLICANS, - S_PRESS, - S_CATHOLIC_CHURCH, - S_SOCIAL_MOVEMENTS, + NATIONAL_ASSEMBLY, + ROYALISTS, + REPUBLICANS, + PRESS, + CATHOLIC_CHURCH, + SOCIAL_MOVEMENTS, ] const MILITARY = [ - S_MONT_VALERIEN, - S_FORT_D_ISSY, - S_CHATEAU_DE_VINCENNES, - S_BUTTE_MONTMARTRE, - S_BUTTE_AUX_CAILLES, - S_PERE_LACHAISE, + MONT_VALERIEN, + FORT_D_ISSY, + CHATEAU_DE_VINCENNES, + BUTTE_MONTMARTRE, + BUTTE_AUX_CAILLES, + PERE_LACHAISE, ] function is_political_space(s) { return ( - s === S_NATIONAL_ASSEMBLY || - s === S_ROYALISTS || - s === S_REPUBLICANS || - s === S_PRESS || - s === S_CATHOLIC_CHURCH || - s === S_SOCIAL_MOVEMENTS + s === NATIONAL_ASSEMBLY || + s === ROYALISTS || + s === REPUBLICANS || + s === PRESS || + s === CATHOLIC_CHURCH || + s === SOCIAL_MOVEMENTS ) } function is_military_space(s) { return ( - s === S_MONT_VALERIEN || - s === S_FORT_D_ISSY || - s === S_CHATEAU_DE_VINCENNES || - s === S_BUTTE_MONTMARTRE || - s === S_BUTTE_AUX_CAILLES || - s === S_PERE_LACHAISE + s === MONT_VALERIEN || + s === FORT_D_ISSY || + s === CHATEAU_DE_VINCENNES || + s === BUTTE_MONTMARTRE || + s === BUTTE_AUX_CAILLES || + s === PERE_LACHAISE ) } -const DIM_INSTITUTIONAL = [ S_NATIONAL_ASSEMBLY, S_ROYALISTS, S_REPUBLICANS ] -const DIM_PUBLIC_OPINION = [ S_PRESS, S_CATHOLIC_CHURCH, S_SOCIAL_MOVEMENTS ] +const INSTITUTIONAL = [ NATIONAL_ASSEMBLY, ROYALISTS, REPUBLICANS ] +const PUBLIC_OPINION = [ PRESS, CATHOLIC_CHURCH, SOCIAL_MOVEMENTS ] -const DIM_FORTS = [ S_MONT_VALERIEN, S_FORT_D_ISSY, S_CHATEAU_DE_VINCENNES ] -const DIM_PARIS = [ S_BUTTE_MONTMARTRE, S_BUTTE_AUX_CAILLES, S_PERE_LACHAISE ] +const FORTS = [ MONT_VALERIEN, FORT_D_ISSY, CHATEAU_DE_VINCENNES ] +const PARIS = [ BUTTE_MONTMARTRE, BUTTE_AUX_CAILLES, PERE_LACHAISE ] const ADJACENT_TO = [ - [ S_ROYALISTS, S_REPUBLICANS ], - [ S_PRESS, S_CATHOLIC_CHURCH ], - [ S_PRESS, S_SOCIAL_MOVEMENTS ], - [ S_ROYALISTS, S_REPUBLICANS, S_CATHOLIC_CHURCH, S_SOCIAL_MOVEMENTS ], - [ S_ROYALISTS, S_PRESS ], - [ S_REPUBLICANS, S_PRESS ], - [ S_BUTTE_MONTMARTRE, S_VERSAILLES_HQ ], - [ S_CHATEAU_DE_VINCENNES, S_BUTTE_AUX_CAILLES, S_VERSAILLES_HQ ], - [ S_FORT_D_ISSY, S_PERE_LACHAISE, S_PRUSSIAN_OCCUPIED_TERRITORY ], - [ S_MONT_VALERIEN, S_BUTTE_AUX_CAILLES, S_PERE_LACHAISE ], - [ S_FORT_D_ISSY, S_BUTTE_MONTMARTRE, S_PERE_LACHAISE ], - [ S_CHATEAU_DE_VINCENNES, S_BUTTE_MONTMARTRE, S_BUTTE_AUX_CAILLES, S_PRUSSIAN_OCCUPIED_TERRITORY ], - [ S_CHATEAU_DE_VINCENNES, S_PERE_LACHAISE ], - [ S_MONT_VALERIEN, S_FORT_D_ISSY ], + [ ROYALISTS, REPUBLICANS ], + [ PRESS, CATHOLIC_CHURCH ], + [ PRESS, SOCIAL_MOVEMENTS ], + [ ROYALISTS, REPUBLICANS, CATHOLIC_CHURCH, SOCIAL_MOVEMENTS ], + [ ROYALISTS, PRESS ], + [ REPUBLICANS, PRESS ], + [ BUTTE_MONTMARTRE, VERSAILLES_HQ ], + [ CHATEAU_DE_VINCENNES, BUTTE_AUX_CAILLES, VERSAILLES_HQ ], + [ FORT_D_ISSY, PERE_LACHAISE, PRUSSIAN_OCCUPIED_TERRITORY ], + [ MONT_VALERIEN, BUTTE_AUX_CAILLES, PERE_LACHAISE ], + [ FORT_D_ISSY, BUTTE_MONTMARTRE, PERE_LACHAISE ], + [ CHATEAU_DE_VINCENNES, BUTTE_MONTMARTRE, BUTTE_AUX_CAILLES, PRUSSIAN_OCCUPIED_TERRITORY ], + [ CHATEAU_DE_VINCENNES, PERE_LACHAISE ], + [ MONT_VALERIEN, FORT_D_ISSY ], ] const ADJACENT_FROM = [ [ ], - [ S_NATIONAL_ASSEMBLY, S_PRESS, S_CATHOLIC_CHURCH ], - [ S_NATIONAL_ASSEMBLY, S_PRESS, S_SOCIAL_MOVEMENTS ], - [ S_ROYALISTS, S_REPUBLICANS, S_CATHOLIC_CHURCH, S_SOCIAL_MOVEMENTS ], - [ S_ROYALISTS, S_PRESS ], - [ S_REPUBLICANS, S_PRESS ], - [ S_BUTTE_MONTMARTRE, S_VERSAILLES_HQ ], - [ S_CHATEAU_DE_VINCENNES, S_BUTTE_AUX_CAILLES, S_VERSAILLES_HQ ], - [ S_FORT_D_ISSY, S_PERE_LACHAISE, S_PRUSSIAN_OCCUPIED_TERRITORY ], - [ S_MONT_VALERIEN, S_BUTTE_AUX_CAILLES, S_PERE_LACHAISE ], - [ S_FORT_D_ISSY, S_BUTTE_MONTMARTRE, S_PERE_LACHAISE ], - [ S_CHATEAU_DE_VINCENNES, S_BUTTE_MONTMARTRE, S_BUTTE_AUX_CAILLES, S_PRUSSIAN_OCCUPIED_TERRITORY ], - [ S_CHATEAU_DE_VINCENNES, S_PERE_LACHAISE ], - [ S_MONT_VALERIEN, S_FORT_D_ISSY ], + [ NATIONAL_ASSEMBLY, PRESS, CATHOLIC_CHURCH ], + [ NATIONAL_ASSEMBLY, PRESS, SOCIAL_MOVEMENTS ], + [ ROYALISTS, REPUBLICANS, CATHOLIC_CHURCH, SOCIAL_MOVEMENTS ], + [ ROYALISTS, PRESS ], + [ REPUBLICANS, PRESS ], + [ BUTTE_MONTMARTRE, VERSAILLES_HQ ], + [ CHATEAU_DE_VINCENNES, BUTTE_AUX_CAILLES, VERSAILLES_HQ ], + [ FORT_D_ISSY, PERE_LACHAISE, PRUSSIAN_OCCUPIED_TERRITORY ], + [ MONT_VALERIEN, BUTTE_AUX_CAILLES, PERE_LACHAISE ], + [ FORT_D_ISSY, BUTTE_MONTMARTRE, PERE_LACHAISE ], + [ CHATEAU_DE_VINCENNES, BUTTE_MONTMARTRE, BUTTE_AUX_CAILLES, PRUSSIAN_OCCUPIED_TERRITORY ], + [ CHATEAU_DE_VINCENNES, PERE_LACHAISE ], + [ MONT_VALERIEN, FORT_D_ISSY ], ] // === GAME STATE === function discard_card(c) { - array_remove_item(player_hand(game.active), c) + array_remove_item(player_hand(), c) game.discard = c } function recycle_card(c) { - array_remove_item(player_hand(game.active), c) + array_remove_item(player_hand(), c) game.strategy_deck.unshift(c) } @@ -253,10 +255,6 @@ function is_objective_card(c) { return c >= 42 && c <= 53 } -function is_strategy_card(c) { - return !is_objective_card(c) && c !== 17 && c !== 34 -} - function is_commune_card(c) { return c >= 18 && c <= 34 } @@ -275,12 +273,18 @@ function enemy_player() { return COMMUNE } -function player_hand(current) { - if (current === COMMUNE) +function player_hand() { + if (game.active === COMMUNE) return game.red_hand return game.blue_hand } +function player_set_aside(current) { + if (game.active === COMMUNE) + return game.red_set_aside + return game.blue_set_aside +} + function is_space(s) { return s >= first_space && s <= last_space } @@ -332,13 +336,13 @@ function update_presence_and_control() { game.control = 0 // Permanent Presence - game.presence |= (1 << (S_PERE_LACHAISE)) - game.presence |= (1 << (S_SOCIAL_MOVEMENTS)) - game.presence |= (1 << (S_ROYALISTS + space_count)) + game.presence |= 1 << PERE_LACHAISE + game.presence |= 1 << SOCIAL_MOVEMENTS + game.presence |= 1 << (ROYALISTS + space_count) for (let s = first_space; s <= last_space; ++s) { - let c_bit = (1 << (s)) - let v_bit = (1 << (s + space_count)) + let c_bit = 1 << s + let v_bit = 1 << (s + space_count) if (c_count[s] > 0) game.presence |= c_bit if (v_count[s] > 0) @@ -348,47 +352,46 @@ function update_presence_and_control() { if (v_count[s] > c_count[s]) game.control |= v_bit } - } -function is_present(side, s) { - if (side === COMMUNE) +function is_present(s) { + if (game.active === COMMUNE) return game.presence & (1 << (s)) return game.presence & (1 << (s + space_count)) } function is_commune_control(s) { - if (s === S_VERSAILLES_HQ) + if (s === VERSAILLES_HQ) return false - if (s === S_PRUSSIAN_OCCUPIED_TERRITORY) + if (s === PRUSSIAN_OCCUPIED_TERRITORY) return false return game.control & (1 << (s)) } function is_versailles_control(s) { - if (s === S_VERSAILLES_HQ) + if (s === VERSAILLES_HQ) return true - if (s === S_PRUSSIAN_OCCUPIED_TERRITORY) + if (s === PRUSSIAN_OCCUPIED_TERRITORY) return game.blue_momentum === 3 return game.control & (1 << (s + space_count)) } -function is_control(side, s) { - if (side === COMMUNE) +function is_control(s) { + if (game.active === COMMUNE) return is_commune_control(s) return is_versailles_control(s) } -function is_adjacent_to_control(side, here) { +function is_adjacent_to_control(here) { for (let s of ADJACENT_TO[here]) - if (is_control(side, s)) + if (is_control(s)) return true return false } -function is_control_dimension(side, dim) { +function is_control_dimension(dim) { for (let s of dim) - if (!is_control(side, s)) + if (!is_control(s)) return false return true } @@ -433,6 +436,12 @@ function count_versailles_pieces(s) { return count_versailles_cubes(s) + count_versailles_discs(s) } +function count_friendly_cubes(s) { + if (game.active === COMMUNE) + return count_commune_cubes(s) + return count_versailles_cubes(s) +} + function count_enemy_pieces(s) { if (game.active === COMMUNE) return count_versailles_pieces(s) @@ -517,7 +526,14 @@ function is_disc(p) { function remove_piece(p) { if (is_commune_cube(p)) { - game.pieces[p] = RED_CUBE_POOL[0] // TODO... + if (game.red_momentum >= 1 && count_commune_cubes(RED_CUBE_POOL[0]) < 2) + game.pieces[p] = RED_CUBE_POOL[0] + else if (game.red_momentum >= 2 && count_commune_cubes(RED_CUBE_POOL[1]) < 1) + game.pieces[p] = RED_CUBE_POOL[1] + else if (game.red_momentum >= 3 && count_commune_cubes(RED_CUBE_POOL[2]) < 1) + game.pieces[p] = RED_CUBE_POOL[2] + else + game.pieces[p] = -1 } else if (is_versailles_cube(p)) { game.pieces[p] = BLUE_CUBE_POOL } else { @@ -525,6 +541,10 @@ function remove_piece(p) { } } +function remove_piece_from_play(p) { + game.pieces[p] = -1 +} + function place_piece(p, s) { game.pieces[p] = s } @@ -552,6 +572,7 @@ function find_available_cube() { return p } } + return -1 } function for_each_enemy_cube(s, f) { @@ -619,24 +640,24 @@ function versailles_political_vp() { states.choose_objective_card = { inactive: "choose an objective card", prompt(current) { - view.prompt = "Choose an Objective card." - for (let c of player_hand(current)) - if (is_objective_card(c)) + view.prompt = "Choose an Objective card to keep." + if (current === COMMUNE) + for (let c of game.red_objective) + gen_action_card(c) + else + for (let c of game.blue_objective) gen_action_card(c) }, card(c, current) { - if (current === COMMUNE) { - game.red_objective = c - game.red_hand = game.red_hand.filter(c => !is_objective_card(c)) - } else { - game.blue_objective = c - game.blue_hand = game.blue_hand.filter(c => !is_objective_card(c)) - } - if (game.red_objective > 0 && game.blue_objective > 0) + if (current === COMMUNE) + game.red_objective = [ c ] + else + game.blue_objective = [ c ] + if (game.red_objective.length === 1 && game.blue_objective.length === 1) end_choose_objective_card() - else if (game.red_objective > 0) + else if (game.red_objective.length === 1) game.active = VERSAILLES - else if (game.blue_objective > 0) + else if (game.blue_objective.length === 1) game.active = COMMUNE else game.active = "Both" @@ -660,9 +681,9 @@ function goto_initiative_phase() { } states.initiative_phase = { - inactive: "decide player order", + inactive: "decide initiative", prompt() { - view.prompt = "Decide player order." + view.prompt = "Decide who will have the initiative." view.actions.commune = 1 view.actions.versailles = 1 }, @@ -696,9 +717,8 @@ states.censorship_phase = { inactive: "censorship phase", prompt() { view.prompt = "Discard a card from your hand." - for (let c of player_hand(game.active)) - if (is_strategy_card(c)) - gen_action("card", c) + for (let c of player_hand()) + gen_action("card", c) }, card(c) { log(`Discarded #${c}.`) @@ -719,83 +739,195 @@ function goto_strategy_phase() { } function resume_strategy_phase() { - game.active = enemy_player() - goto_strategy_phase() + if (game.red_hand.length === 1 && game.blue_hand.length === 1) { + goto_set_aside_cards() + } else { + game.active = enemy_player() + goto_strategy_phase() + } +} + +function has_final_crisis_card() { + if (game.active === COMMUNE) + return game.red_final + return game.blue_final } states.strategy_phase = { inactive: "play a card", prompt() { view.prompt = "Play a card." - let hand = player_hand(game.active) - let n_strategy = 0 - for (let c of hand) - if (is_strategy_card(c)) - n_strategy += 1 - for (let c of hand) { - if (is_strategy_card(c)) { - if (can_play_event(c)) - gen_action("card_event", c) - gen_action("card_ops_political", c) - gen_action("card_ops_military", c) - if (game.discard > 0 && can_play_event(game.discard)) - gen_action("card_use_discarded", c) - if (can_advance_momentum()) - gen_action("card_advance_momentum", c) - } - if (c === 17 || c === 34) { - if (n_strategy > 0) { - gen_action("card_ops_political", c) - gen_action("card_ops_military", c) - } - } - } + for (let c of player_hand()) + gen_action_card(c) }, - card_event(c) { + card(c) { push_undo() - log(`Played #${c} for event.`) - discard_card(c) - goto_play_event() + log(`Played #${c}.`) + game.what = c + game.state = "play_card" }, - card_ops_political(c) { - push_undo() - if (c === 17 || c === 34) - return goto_final_crisis_discard(c, POLITICAL) - log(`Played #${c} for ${card_ops[c]} Political ops.`) - discard_card(c) - goto_operations(card_ops[c], POLITICAL) +} + +states.play_card = { + prompt() { + let c = game.what + + view.selected_card = game.what + + view.actions.political = 1 + view.actions.military = 1 + + if (can_play_event(c)) + view.actions.event = 1 + else + view.actions.event = 0 + + if (can_advance_momentum()) { + view.actions.momentum = 1 + if (game.active === COMMUNE) + view.actions.red_momentum = 1 + else + view.actions.blue_momentum = 1 + } + + if (game.discard > 0 && can_play_event(game.discard)) + gen_action_card(game.discard) + + let final = has_final_crisis_card() + if (final > 0) + gen_action_card(final) }, - card_ops_military(c) { - push_undo() - if (c === 17 || c === 34) - return goto_final_crisis_discard(c, MILITARY) - log(`Played #${c} for ${card_ops[c]} Military ops.`) - discard_card(c) - goto_operations(card_ops[c], MILITARY) + event() { + log("Event.") + discard_card(game.what) + goto_play_event(game.what) }, - card_advance_momentum(c) { - push_undo() - log(`Played #${c} to advance momentum.`) + political() { + log("Ops.") + discard_card(game.what) + goto_operations(card_ops[game.what], POLITICAL) + }, + military() { + log("Ops.") + discard_card(game.what) + goto_operations(card_ops[game.what], MILITARY) + }, + momentum() { + log(`Momentum.`) if (game.scenario === "Censorship") - recycle_card(c) + recycle_card(game.what) else - discard_card(c) + discard_card(game.what) if (game.active === COMMUNE) - game.red_momentum += 1 + advance_revolutionary_momentum(1) else - game.blue_momentum += 1 - // TODO: momentum trigger - resume_strategy_phase() + advance_prussian_collaboration(1) }, - card_use_discarded(c) { - push_undo() - log(`Discarded #${c} to play #${game.discard}.`) - let old_c = game.discard - discard_card(c) - goto_play_event(old_c) + red_momentum() { + this.momentum() + }, + blue_momentum() { + this.momentum() + }, + card(c) { + log(`Discarded for #${c}.`) + if (c === game.discard) { + discard_card(game.what) + game.what = c + goto_play_event(c) + } else { + discard_card(game.what) + game.what = c + game.state = "play_final" + } + }, +} + +states.play_final = { + prompt() { + view.prompt = card_names[game.what] + ": Use up to 4 Operations Points." + view.selected_card = game.what + view.actions.political = 1 + view.actions.military = 1 + }, + political() { + discard_final() + goto_operations(4, POLITICAL) + }, + military() { + discard_final() + goto_operations(4, MILITARY) + }, +} + +function discard_final() { + if (game.active === COMMUNE) + game.red_final = 0 + else + game.blue_final = 0 +} + +// === PLAYER MOMENTUM TRACKS === + +function advance_revolutionary_momentum(x) { + game.red_momentum += x + for (let i = game.red_momentum; i < 3; ++i) + for_each_commune_cube(RED_CUBE_POOL[i], p => game.pieces[p] = -1) + game.active = VERSAILLES + if (x > 0 && game.red_momentum >= 2) + game.state = "revolutionary_momentum_trigger" + else + end_momentum_trigger() +} + +function advance_prussian_collaboration(x) { + game.blue_momentum += x + for (let i = 0; i < game.blue_momentum; ++i) + for_each_versailles_cube(PRUSSIAN_COLLABORATION[i], p => game.pieces[p] = BLUE_CUBE_POOL) + game.active = COMMUNE + if (x > 0 && game.blue_momentum >= 2) + game.state = "prussian_collaboration_trigger" + else + end_momentum_trigger() +} + +states.revolutionary_momentum_trigger = { + prompt() { + view.prompt = "Revolutionary Momentum: Place a cube in an Institutional space." + for (let s of INSTITUTIONAL) + gen_action_space(s) + view.actions.skip = 1 + }, + space(s) { + place_piece(find_available_cube(), s) + end_momentum_trigger() + }, + skip() { + end_momentum_trigger() + }, +} + +states.prussian_collaboration_trigger = { + prompt() { + view.prompt = "Prussian Collaboration: Place a cube in a Public Opinion space." + for (let s of PUBLIC_OPINION) + gen_action_space(s) + view.actions.skip = 1 + }, + space(s) { + place_piece(find_available_cube(), s) + end_momentum_trigger() + }, + skip() { + end_momentum_trigger() }, } +function end_momentum_trigger() { + game.active = enemy_player() + resume_strategy_phase() +} + // === OPERATIONS === function goto_operations(count, spaces) { @@ -805,25 +937,24 @@ function goto_operations(count, spaces) { } function goto_final_crisis_discard(c, spaces) { + log("Played #" + c + ".") game.state = "discard_final_crisis" game.count = 4 game.spaces = spaces - array_remove_item(player_hand(game.active), c) } states.discard_final_crisis = { inactive: "discard a card to play final crisis", prompt() { view.prompt = "Discard a card to play Final Crisis card for ops." - let hand = player_hand(game.active) + let hand = player_hand() for (let c of hand) - if (is_strategy_card(c)) - gen_action("card", c) + gen_action("card", c) }, card(c) { push_undo() log(`Discarded #${c} to play Final Crisis card for ops.`) - array_remove_item(player_hand(game.active), c) + array_remove_item(player_hand(), c) game.discard = c goto_operations_remove() }, @@ -847,7 +978,7 @@ function can_operations_remove() { } function can_operations_remove_space(s) { - if (is_present(game.active, s) || is_adjacent_to_control(game.active, s)) { + if (is_present(s) || is_adjacent_to_control(s)) { let c = has_enemy_cube(s) let d = has_enemy_disc(s) if (c || d) { @@ -864,11 +995,11 @@ function can_operations_remove_space(s) { function military_strength(s) { let str = 0 for (let next of ADJACENT_FROM[s]) - if (is_control(game.active, next)) + if (is_control(next)) str += 1 - if (is_present(game.active, s)) + if (is_present(s)) str += 1 - if (is_control(game.active, s)) + if (is_control(s)) str += 1 return str } @@ -989,7 +1120,9 @@ function can_operations_place() { } function can_operations_place_space(s) { - if (is_present(game.active, s) || is_adjacent_to_control(game.active, s)) { + if (is_present(s) || is_adjacent_to_control(s)) { + if (count_friendly_cubes(s) >= 4) + return false let d = has_enemy_disc(s) if (!d || game.count >= 2) return true @@ -999,7 +1132,7 @@ function can_operations_place_space(s) { states.operations_place = { prompt() { - view.prompt = "Operations: Place cubes into Political spaces." + view.prompt = "Operations: Place cubes." for (let s of game.spaces) if (can_operations_place_space(s)) gen_action_space(s) @@ -1045,6 +1178,25 @@ function end_operations() { resume_strategy_phase() } +// === SET ASIDE CARDS === + +function goto_set_aside_cards() { + for (let c of game.red_hand) + game.red_set_aside.push(c) + game.red_hand = [] + + for (let c of game.blue_hand) + game.blue_set_aside.push(c) + game.blue_hand = [] + + goto_pivotal_space_bonus_actions() +} + +function goto_pivotal_space_bonus_actions() { + game.state = "pivotal_space_bonus_actions" + game.active = game.initiative +} + // === EVENTS === function goto_play_event(c) { @@ -1077,13 +1229,15 @@ exports.setup = function (seed, scenario, options) { objective_deck: [], discard: 0, - red_hand: [ 34 ], - red_final: [], - red_objective: 0, + red_final: 34, + red_hand: [], + red_set_aside: [], + red_objective: [], - blue_hand: [ 17 ], - blue_final: [], - blue_objective: 0, + blue_final: 17, + blue_hand: [], + blue_set_aside: [], + blue_objective: [], presence: 0, control: 0, @@ -1105,9 +1259,9 @@ exports.setup = function (seed, scenario, options) { RED_BONUS_CUBES[1], RED_BONUS_CUBES[2], RED_BONUS_CUBES[2], - S_PRESS, - S_SOCIAL_MOVEMENTS, - S_PERE_LACHAISE, + PRESS, + SOCIAL_MOVEMENTS, + PERE_LACHAISE, // Versailles cubes BLUE_CRISIS_TRACK[0], BLUE_CRISIS_TRACK[1], @@ -1119,14 +1273,14 @@ exports.setup = function (seed, scenario, options) { BLUE_BONUS_CUBES[1], BLUE_BONUS_CUBES[2], BLUE_BONUS_CUBES[2], - BLUE_CUBE_POOL, - BLUE_CUBE_POOL, - BLUE_CUBE_POOL, - BLUE_CUBE_POOL, - BLUE_CUBE_POOL, - BLUE_CUBE_POOL, - S_ROYALISTS, - S_PRESS, + PRUSSIAN_COLLABORATION[0], + PRUSSIAN_COLLABORATION[1], + PRUSSIAN_COLLABORATION[1], + PRUSSIAN_COLLABORATION[2], + PRUSSIAN_COLLABORATION[2], + PRUSSIAN_COLLABORATION[2], + ROYALISTS, + PRESS, // Commune discs -1, -1, // Versailles discs @@ -1155,14 +1309,14 @@ exports.setup = function (seed, scenario, options) { if (game.scenario === "Censorship") n = 5 - for (let i = 0; i < 5; ++i) { + for (let i = 0; i < n; ++i) { game.red_hand.push(game.strategy_deck.pop()) game.blue_hand.push(game.strategy_deck.pop()) } for (let i = 0; i < 2; ++i) { - game.red_hand.push(game.objective_deck.pop()) - game.blue_hand.push(game.objective_deck.pop()) + game.red_objective.push(game.objective_deck.pop()) + game.blue_objective.push(game.objective_deck.pop()) } return game @@ -1197,17 +1351,20 @@ exports.view = function(state, player) { discard: game.discard, hand: 0, final: 0, + set_aside: 0, objective: 0 } if (player === COMMUNE) { view.hand = game.red_hand view.final = game.red_final + view.set_aside = game.red_set_aside view.objective = game.red_objective } if (player === VERSAILLES) { view.hand = game.blue_hand view.final = game.blue_final + view.set_aside = game.blue_set_aside view.objective = game.blue_objective } |