diff options
Diffstat (limited to 'rules.js')
-rw-r--r-- | rules.js | 354 |
1 files changed, 307 insertions, 47 deletions
@@ -10,9 +10,9 @@ let game = {}; var view = {}; const role_ids = [data_1.ANARCHISTS_ID, data_1.COMMUNISTS_ID, data_1.MODERATES_ID]; const faction_player_map = { - [data_1.ANARCHISTS_ID]: data_1.ANARCHIST, - [data_1.COMMUNISTS_ID]: data_1.COMMUNIST, - [data_1.MODERATES_ID]: data_1.MODERATE, + a: data_1.ANARCHIST, + c: data_1.COMMUNIST, + m: data_1.MODERATE, }; const player_faction_map = { [data_1.ANARCHIST]: data_1.ANARCHISTS_ID, @@ -160,6 +160,22 @@ const engine_functions = { start_year, resolve_fascist_test, resolve_final_bid, + card1_event2, + card3_event2, + card10_event2, + card16_event2, + card17_event3, + card20_event3, + card22_event3, + card23_event1, + card26_event1, + card29_event2, + card35_event2, + card42_event3, + card45_event2, + card50_event2, + card53_event2, + card54_event1, }; function get_active(engine) { for (let i of engine) { @@ -287,21 +303,22 @@ function setup(seed, _scenario, _options) { seed: seed, state: null, active: data_1.ANARCHIST, + active_abilities: [], bag_of_glory: [data_1.ANARCHISTS_ID, data_1.COMMUNISTS_ID, data_1.MODERATES_ID], blank_markers: [[], [], [], [], []], bonuses: [data_1.ON, data_1.ON], current_events: [], discard: { - [data_1.ANARCHISTS_ID]: [], - [data_1.COMMUNISTS_ID]: [], - [data_1.MODERATES_ID]: [], + a: [], + c: [], + m: [], f: [], }, engine: [], final_bid: { - [data_1.ANARCHISTS_ID]: [], - [data_1.COMMUNISTS_ID]: [], - [data_1.MODERATES_ID]: [], + a: [], + c: [], + m: [], }, fronts: { a: { @@ -327,38 +344,38 @@ function setup(seed, _scenario, _options) { }, glory: [], hands: { - [data_1.ANARCHISTS_ID]: [], - [data_1.COMMUNISTS_ID]: [], - [data_1.MODERATES_ID]: [], + a: [], + c: [], + m: [], }, hero_points: { - [data_1.ANARCHISTS_ID]: 2, - [data_1.COMMUNISTS_ID]: 2, - [data_1.MODERATES_ID]: 0, + a: 2, + c: 2, + m: 0, pool: 14, }, chosen_cards: { - [data_1.ANARCHISTS_ID]: null, - [data_1.COMMUNISTS_ID]: null, - [data_1.MODERATES_ID]: null, + a: null, + c: null, + m: null, }, initiative: data_1.MODERATES_ID, medallions: { - [data_1.ANARCHISTS_ID]: [], - [data_1.COMMUNISTS_ID]: [], - [data_1.MODERATES_ID]: [], + a: [], + c: [], + m: [], pool: [], }, tableaus: { - [data_1.ANARCHISTS_ID]: [], - [data_1.COMMUNISTS_ID]: [], - [data_1.MODERATES_ID]: [], + a: [], + c: [], + m: [], }, tracks: [5, 5, 6, 3, 3], trash: { - [data_1.ANARCHISTS_ID]: [], - [data_1.COMMUNISTS_ID]: [], - [data_1.MODERATES_ID]: [], + a: [], + c: [], + m: [], }, triggered_track_effects: [], log: [], @@ -409,7 +426,7 @@ function start_turn() { log_h2('Fascist Event', 'fascist'); log(card.title); game.engine = card.effects.map((effect) => resolve_effect(effect)); - if (game.year === 3 && game.turn === 1) { + if (game.year === 3 && game.turn === 4) { game.engine.push(create_function_node('setup_final_bid')); } else { @@ -548,6 +565,23 @@ states.activate_icon = { resolve_active_and_proceed(); }, }; +states.add_card_to_tableau = { + inactive: 'add a card to their tableau', + prompt() { + view.prompt = 'Choose a card to add to your tableau'; + for (const c of game.hands[get_active_faction()]) { + gen_action_card(c); + } + }, + card(c) { + const faction_id = get_active_faction(); + const card = cards[c]; + array_remove(game.hands[faction_id], game.hands[faction_id].indexOf(c)); + game.tableaus[faction_id].push(c); + logi(`${faction_player_map[faction_id]} adds ${card.title} to their tableau`); + resolve_active_and_proceed(); + }, +}; states.add_glory = { inactive: 'add tokens to the Bag of Glory', prompt() { @@ -872,14 +906,24 @@ states.gain_hero_points = { inactive: 'gain Hero Points', prompt() { const value = get_active_node_args().v; - view.prompt = value > 1 ? `Gain ${value} Hero Points` : 'Gain 1 Hero Point'; - gen_action('gain_hp'); + if (game.hero_points.pool > 0) { + view.prompt = + value > 1 ? `Gain ${value} Hero Points` : 'Gain 1 Hero Point'; + gen_action('gain_hp'); + } + else { + view.prompt = 'No Hero Points available in pool. You must skip'; + gen_action('skip'); + } }, gain_hp() { const value = get_active_node_args().v; gain_hero_points(get_active_faction(), value); resolve_active_and_proceed(); }, + skip() { + resolve_active_and_proceed(); + }, }; states.game_over = { get inactive() { @@ -917,13 +961,21 @@ states.lose_hero_points = { resolve_active_and_proceed(); }, }; +states.move_attacks = { + inactive: 'move attacks', + prompt() { + view.prompt = 'Choose a Front'; + }, +}; states.move_track = { inactive: 'move a Track', prompt() { const node = get_active_node(); const track = node.a.t; const value = node.a.v; - const name = tracks[track].name; + const name = track === data_1.LIBERTY_OR_COLLECTIVIZATION + ? 'Liberty OR Collectivization' + : tracks[track].name; view.prompt = `Move ${name} ${value > 0 ? 'up' : 'down'}`; if (track === data_1.GOVERNMENT && value === data_1.TOWARDS_CENTER) { view.prompt = `Move ${name} towards center`; @@ -931,7 +983,13 @@ states.move_track = { else if (track === data_1.GOVERNMENT && value === data_1.AWAY_FROM_CENTER) { view.prompt = `Move ${name} away from center`; } - gen_action_standee(track); + if (track === data_1.LIBERTY_OR_COLLECTIVIZATION) { + gen_action_standee(data_1.LIBERTY); + gen_action_standee(data_1.COLLECTIVIZATION); + } + else { + gen_action_standee(track); + } }, standee(s) { const node = get_active_node(); @@ -964,6 +1022,12 @@ states.move_track_up_or_down = { resolve_active_and_proceed(); }, }; +states.peek_fascist_cards = { + inactive: 'peek at Fascist cards', + prompt() { + view.prompt = 'Choose one card to return to the top of the deck'; + }, +}; states.player_turn = { inactive: 'play their turn', prompt() { @@ -1039,6 +1103,18 @@ states.remove_blank_marker = { resolve_active_and_proceed(); }, }; +states.remove_attack_from_fronts = { + inactive: 'remove attacks', + prompt() { + view.prompt = 'Choose a front to remove an attack'; + }, +}; +states.return_card = { + inactive: 'return a card', + prompt() { + view.prompt = 'Choose a card to return'; + }, +}; states.spend_hero_points = { inactive: 'spend Hero points', prompt() { @@ -1134,6 +1210,23 @@ states.spend_hero_points = { resolve_active_and_proceed(); }, }; +states.swap_card_tableau_hand = { + inactive: 'swap cards', + prompt() { + view.prompt = 'Choose cards'; + const faction = get_active_faction(); + for (const c of game.hands[faction]) { + gen_action_card(c); + } + }, + card(c) { }, +}; +states.take_hero_points = { + inactive: 'take Hero Points', + prompt() { + view.prompt = 'Choose a player to take Hero Points from'; + }, +}; states.use_organization_medallion = { inactive: 'use Organization Medallion', prompt() { @@ -1179,6 +1272,87 @@ states.use_strategy_medallion = { resolve_active_and_proceed(); }, }; +function card1_event2() { + const value = game.tracks[data_1.FOREIGN_AID] >= 6 ? 3 : 2; + insert_after_active_node(resolve_effect((0, data_1.create_effect)('track', data_1.FOREIGN_AID, value))); + resolve_active_and_proceed(); +} +function card3_event2() { + const value = game.tracks[data_1.FOREIGN_AID] >= 8 ? 2 : 1; + insert_after_active_node(resolve_effect((0, data_1.create_effect)('track', data_1.GOVERNMENT, value))); + resolve_active_and_proceed(); +} +function card10_event2() { + if (game.tracks[data_1.FOREIGN_AID] >= 6) { + resolve_effect((0, data_1.create_effect)('draw_card', data_1.SELF, 2)); + } + resolve_active_and_proceed(); +} +function card16_event2() { + const value = game.tracks[data_1.GOVERNMENT] >= 6 ? 4 : 3; + insert_after_active_node(resolve_effect((0, data_1.create_effect)('track', data_1.FOREIGN_AID, value))); + resolve_active_and_proceed(); +} +function card17_event3() { + const value = game.tracks[data_1.GOVERNMENT] >= 6 ? -4 : -3; + insert_after_active_node(resolve_effect((0, data_1.create_effect)('track', data_1.COLLECTIVIZATION, value))); + resolve_active_and_proceed(); +} +function card20_event3() { + const value = game.tracks[data_1.SOVIET_SUPPORT] >= 6 ? 2 : 1; + insert_after_active_node(create_seq_node([ + resolve_effect((0, data_1.create_effect)('front', data_1.MADRID, value)), + resolve_effect((0, data_1.create_effect)('front', data_1.SOUTHERN, value)), + ])); + resolve_active_and_proceed(); +} +function card22_event3() { + const value = game.tracks[data_1.SOVIET_SUPPORT] >= 8 ? -3 : -3; + insert_after_active_node(resolve_effect((0, data_1.create_effect)('track', data_1.GOVERNMENT, value))); + resolve_active_and_proceed(); +} +function card23_event1() { + const value = game.tracks[data_1.SOVIET_SUPPORT] >= 6 ? 4 : 3; + insert_after_active_node(resolve_effect((0, data_1.create_effect)('front', data_1.ANY, value))); + resolve_active_and_proceed(); +} +function card26_event1() { + game.active_abilities.push(data_1.COMMUNIST_EXTRA_HERO_POINT); +} +function card29_event2() { + const value = game.tracks[data_1.GOVERNMENT] <= 5 ? -3 : -2; + insert_after_active_node(resolve_effect((0, data_1.create_effect)('track', data_1.LIBERTY, value))); + resolve_active_and_proceed(); +} +function card35_event2() { + const value = game.tracks[data_1.GOVERNMENT] <= 5 ? 2 : 1; + insert_after_active_node(resolve_effect((0, data_1.create_effect)('track', data_1.SOVIET_SUPPORT, value))); + resolve_active_and_proceed(); +} +function card42_event3() { + game.active_abilities.push(data_1.ANARCHIST_EXTRA_HERO_POINT); +} +function card45_event2() { + if (game.tracks[data_1.LIBERTY] >= 6) { + insert_after_active_node(resolve_effect((0, data_1.create_effect)('track', data_1.COLLECTIVIZATION, 1))); + } + resolve_active_and_proceed(); +} +function card50_event2() { + const value = game.tracks[data_1.COLLECTIVIZATION] >= 8 ? 3 : 2; + insert_after_active_node(resolve_effect((0, data_1.create_effect)('front', data_1.ARAGON, value))); + resolve_active_and_proceed(); +} +function card53_event2() { + const value = game.tracks[data_1.LIBERTY] >= 8 ? 3 : 2; + insert_after_active_node(resolve_effect((0, data_1.create_effect)('front', data_1.ANY, value))); + resolve_active_and_proceed(); +} +function card54_event1() { + const value = game.tracks[data_1.COLLECTIVIZATION] >= 8 ? 3 : 2; + insert_after_active_node(resolve_effect((0, data_1.create_effect)('track', data_1.LIBERTY, value))); + resolve_active_and_proceed(); +} function add_glory(faction, amount, indent = false) { for (let i = 0; i < amount; ++i) { game.bag_of_glory.push(get_active_faction()); @@ -1260,6 +1434,7 @@ function end_of_turn() { Object.keys(game.fronts).forEach((front_id) => { game.fronts[front_id].contributions = []; }); + game.active_abilities = []; game.used_medallions = []; if (game.turn === 4) { end_of_year(); @@ -1283,9 +1458,9 @@ function end_of_year() { } const glory_to_draw = [0, 1, 2, 5]; const glory_this_year = { - [data_1.ANARCHISTS_ID]: false, - [data_1.COMMUNISTS_ID]: false, - [data_1.MODERATES_ID]: false, + a: false, + c: false, + m: false, }; for (let i = 0; i < glory_to_draw[game.year]; ++i) { const index = random(game.bag_of_glory.length); @@ -1315,6 +1490,12 @@ function gain_hero_points(faction_id, value) { if (game.hero_points.pool === 0) { return; } + if ((faction_id === data_1.ANARCHISTS_ID && + (game.active_abilities || []).includes(data_1.ANARCHIST_EXTRA_HERO_POINT)) || + (faction_id === data_1.COMMUNISTS_ID && + (game.active_abilities || []).includes(data_1.COMMUNIST_EXTRA_HERO_POINT))) { + value++; + } const gain = Math.min(game.hero_points.pool, value); game.hero_points.pool -= gain; game.hero_points[faction_id] += gain; @@ -1571,10 +1752,15 @@ function get_faction_to_resolve_effect(effect) { return effect.faction; } const effect_type_state_map = { + add_card_to_tableau: 'add_card_to_tableau', attack: 'attack_front', bonus: 'change_bonus', front: 'add_to_front', medallion: 'choose_medallion', + remove_blank_marker: 'remove_blank_marker', + return_card: 'return_card', + swap_card_tableau_hand: 'swap_card_tableau_hand', + take_hero_points: 'take_hero_points', track: 'move_track', }; function resolve_effect(effect) { @@ -1583,25 +1769,99 @@ function resolve_effect(effect) { v: effect.value, }; const faction = get_faction_to_resolve_effect(effect); + if (effect.type === 'function') { + return create_function_node(effect.target); + } + if (effect.type === 'state') { + return create_leaf_node(effect.target, faction, { + v: effect.value, + }); + } let state = effect_type_state_map[effect.type]; if (state !== undefined) { return create_leaf_node(state, faction, args); } - if (effect.type === 'hero_points' && - effect.target === data_1.PLAYER_WITH_MOST_HERO_POINTS) { - state = 'lose_hero_points'; - } - if (effect.type === 'hero_points' && effect.target === data_1.SELF) { - state = 'gain_hero_points'; - } - if (effect.type === 'draw_card' && effect.target === data_1.SELF) { - state = 'draw_card'; + const strategies = [ + { + condition: effect.type === 'hero_points' && + effect.target === data_1.PLAYER_WITH_MOST_HERO_POINTS, + resolve: () => { + return create_leaf_node('lose_hero_points', faction, args); + }, + }, + { + condition: effect.type === 'hero_points' && effect.target === data_1.ALL_PLAYERS, + resolve: () => { + return create_seq_node(get_player_order().map((faction) => create_leaf_node('gain_hero_points', faction, { + v: effect.value, + }))); + }, + }, + { + condition: effect.type === 'hero_points' && effect.target === data_1.SELF, + resolve: () => { + return create_leaf_node('gain_hero_points', faction, args); + }, + }, + { + condition: effect.type === 'hero_points' && + role_ids.includes(effect.target), + resolve: () => { + return create_leaf_node('gain_hero_points', effect.target, args); + }, + }, + { + condition: effect.type === 'hero_points' && effect.target === data_1.INITIATIVE_PLAYER, + resolve: () => { + return create_leaf_node('gain_hero_points', game.initiative); + }, + }, + { + condition: effect.type === 'draw_card' && effect.target === data_1.SELF, + resolve: () => { + return create_leaf_node('draw_card', faction, args); + }, + }, + { + condition: effect.type === 'draw_card' && effect.target === data_1.INITIATIVE_PLAYER, + resolve: () => { + return create_leaf_node('draw_card', game.initiative, args); + }, + }, + { + condition: effect.type === 'draw_card' && + role_ids.includes(effect.target), + resolve: () => { + return create_leaf_node('draw_card', effect.target, args); + }, + }, + { + condition: effect.type === 'draw_card' && effect.target === data_1.ALL_PLAYERS, + resolve: () => { + return create_seq_node(get_player_order(get_active_faction()).map((faction) => create_leaf_node('draw_card', faction, { + v: effect.value, + }))); + }, + }, + { + condition: effect.type === 'draw_card' && effect.target === data_1.OTHER_PLAYERS, + resolve: () => { + const leaf_nodes = get_player_order(get_active_faction()).map((faction) => create_leaf_node('draw_card', faction, { + v: effect.value, + })); + array_remove(leaf_nodes, 0); + return create_seq_node(leaf_nodes); + }, + }, + ]; + const strategy = strategies.find((strategy) => strategy.condition); + if (strategy) { + return strategy.resolve(); } - if (state === undefined) { + else { console.log('----UNRESOLVED EFFECT----', effect); - return null; + throw new Error('Unresolved effect'); } - return create_leaf_node(state, faction, args); } function win_final_bid(faction_id) { log_br(); |