diff options
Diffstat (limited to 'rules.ts')
-rw-r--r-- | rules.ts | 134 |
1 files changed, 112 insertions, 22 deletions
@@ -276,6 +276,9 @@ function setup_choose_card() { game.engine = player_order.map((faction_id) => create_leaf_node('choose_card', faction_id) ); + // Add extra confirm, otherwise first players card will be revealed + // before confirm + game.engine.push(create_leaf_node('confirm_turn', player_order[2])); game.engine.push(create_function_node('setup_player_turn')); next(); } @@ -329,6 +332,7 @@ function end_of_player_turn() { const { f: faction } = get_active_node_args(); if (get_next_faction_in_player_order(faction) === game.first_player) { game.engine = [ + create_leaf_node('change_active_player', game.initiative), create_function_node('resolve_fascist_test'), create_function_node('setup_bag_of_glory'), ]; @@ -352,6 +356,7 @@ const engine_functions: Record<string, Function> = { checkpoint, end_of_player_turn, end_of_turn, + end_of_year_cleanup, end_resolving_event_effects, setup_bag_of_glory, setup_choose_card, @@ -469,7 +474,10 @@ function insert_before_active_node( insert_before_or_after_active_node(node, 'before', engine); } -function next() { +function next(checkpoint = false) { + if (checkpoint) { + clear_undo(); + } const node = get_active_node(game.engine); if (node.t === function_node && engine_functions[node.f]) { const args = node.a; @@ -499,19 +507,16 @@ function next() { } } -function resolve_active_node(checkpoint = false) { +function resolve_active_node() { const next_node = get_active_node(game.engine); if (next_node !== null) { next_node.r = resolved; } - if (checkpoint) { - clear_undo(); - } } function resolve_active_and_proceed(checkpoint = false) { - resolve_active_node(checkpoint); - next(); + resolve_active_node(); + next(checkpoint); } // #endregion @@ -667,6 +672,7 @@ export function setup(seed: number, _scenario: string, _options: unknown) { top_of_events_deck: null, turn: 0, year: 0, + glory_current_year: null, }; // Randomly choose second player @@ -749,6 +755,13 @@ function start_turn() { // region STATES +function player_can_resolve_icon(icon: Icon): boolean { + if (icon === 'teamwork_on' && game.bonuses[TEAMWORK_BONUS] === ON) { + return false; + } + return true; +} + states.activate_icon = { inactive: 'activate an icon', prompt() { @@ -757,6 +770,9 @@ states.activate_icon = { const c = cards[game.played_card] as PlayerCard; for (const i of c.icons) { gen_action(i); + if (!player_can_resolve_icon(i)) { + view.actions[i] = 0; + } } }, spend_hp() { @@ -1059,6 +1075,21 @@ states.break_tie_winner = { }, }; +/** + * Change does not do anything, but it will change + * active player and trigger a confirm for the previous + * state + */ +states.change_active_player = { + inactive: '', + auto_resolve() { + return true; + }, + prompt() { + view.prompt = ''; + } +} + states.choose_area_ap = { inactive: 'choose area to use Action Points', prompt() { @@ -1340,6 +1371,37 @@ states.draw_card = { }, }; +states.draw_glory = { + inactive: 'draw from the Bag of Glory', + prompt() { + gen_spend_hero_points(); + view.prompt = 'Draw from the Bag of Glory'; + gen_action('draw_glory'); + }, + draw_glory() { + const index = random(game.bag_of_glory.length); + const faction = game.bag_of_glory[index]; + + game.glory.push(faction); + + // TODO: remove if statement, just here atm to not break + // running games + if (!game.glory_current_year) { + game.glory_current_year = game.glory_current_year = { + a: false, + c: false, + m: false, + }; + } + game.glory_current_year[faction] = true; + + array_remove(game.bag_of_glory, index); + + log(`${get_player(get_active_faction())} draws <ft${faction}> from the Bag of Glory`) + resolve_active_and_proceed(true); + }, +}; + states.end_of_year_discard = { inactive: 'discard cards from hand and tableau', prompt() { @@ -1578,6 +1640,20 @@ function can_move_track_down(track_id): boolean { states.move_track_up_or_down = { inactive: 'move a track', + auto_resolve() { + const { track_id, strength } = get_active_node_args(); + const can_move_up = can_move_track_up(track_id); + const can_move_down = can_move_track_down(track_id); + if (can_move_up && can_move_down) { + return false; + } + if (can_move_up) { + move_track(track_id, strength); + } else if (can_move_down) { + move_track(track_id, -1 * strength); + } + return true; + }, prompt() { gen_spend_hero_points(); const { track_id } = get_active_node_args(); @@ -2541,26 +2617,27 @@ function end_of_year() { } const glory_to_draw = [0, 1, 2, 5]; - const glory_this_year: Record<FactionId, boolean> = { + + game.glory_current_year = { a: false, c: false, m: false, }; - const drawn_glory = []; + + const player_order = get_player_order(); + + const engine = []; + for (let i = 0; i < glory_to_draw[game.year]; ++i) { - const index = random(game.bag_of_glory.length); - const faction = game.bag_of_glory[index]; - game.glory.push(faction); - drawn_glory.push(faction); - glory_this_year[faction] = true; - array_remove(game.bag_of_glory, index); + engine.push(create_leaf_node('draw_glory', player_order[i % 3])); } - log( - `Tokens pulled from the Bag of Glory: ${drawn_glory - .map((faction_id: string) => `<ft${faction_id}>`) - .join('')}` - ); + engine.push(create_function_node('end_of_year_cleanup')); + game.engine = engine; + next(true); +} + +function end_of_year_cleanup() { if (game.year === 3) { // end of game determine_winner(); @@ -2568,7 +2645,7 @@ function end_of_year() { } const players_to_gain_hero_points = role_ids.filter( - (f) => !glory_this_year[f] + (f) => !game.glory_current_year?.[f] ); gain_hero_points_in_player_order(players_to_gain_hero_points, game.year); @@ -2582,6 +2659,7 @@ function end_of_year() { // New deck is used for next year so clear top card // if it was set game.top_of_events_deck = null; + game.glory_current_year = null; next(); } @@ -2693,6 +2771,9 @@ function resolve_fascist_test() { const test_passed = status === VICTORY || (status !== DEFEAT && game.fronts[test.front].value >= test.value); + + const hero_point_actions: EngineNode[] = []; + if (test_passed) { log('The Test is passed'); for (const faction of get_player_order()) { @@ -2705,9 +2786,16 @@ function resolve_fascist_test() { hero_points_gain += 2; } if (hero_points_gain > 0) { - gain_hero_points(faction, hero_points_gain); + const node = resolve_effect( + create_effect('hero_points', faction, hero_points_gain) + ); + hero_point_actions.push(node); } } + + if (hero_point_actions.length > 0) { + insert_after_active_node(create_seq_node(hero_point_actions)); + } } else { log('The Test is failed'); } @@ -2764,6 +2852,8 @@ function get_fronts_to_add_to(target: string, not: FrontId[] = []): FrontId[] { ); } else if (game.fronts[target].status === DEFEAT) { return get_fronts_closest_to(CLOSEST_TO_DEFEAT); + } else if (game.fronts[target].status === VICTORY) { + return get_fronts_to_add_to(ANY); } else { return [target as FrontId]; } |