diff options
author | Frans Bongers <fransbongers@franss-mbp.home> | 2025-03-09 21:08:42 +0100 |
---|---|---|
committer | Frans Bongers <fransbongers@franss-mbp.home> | 2025-03-09 21:08:42 +0100 |
commit | ebe9d5b86b2fe547395524f6414d47c2e4448771 (patch) | |
tree | b90b7f42a2bef30d45db6dda5b73b04d23a869f9 | |
parent | 59dea4f112065f499ca8ce7379953a22e52a2f48 (diff) | |
download | land-and-freedom-ebe9d5b86b2fe547395524f6414d47c2e4448771.tar.gz |
keep card selected when played to tableau
-rw-r--r-- | rules.js | 39 | ||||
-rw-r--r-- | rules.ts | 53 | ||||
-rw-r--r-- | types.d.ts | 1 |
3 files changed, 48 insertions, 45 deletions
@@ -148,6 +148,7 @@ function setup_final_bid() { } function setup_player_turn() { game.fascist = 0; + game.card_played = 0; const next_faction = game.first_player === null ? get_player_order()[0] : get_next_faction_in_player_order(get_active_faction()); @@ -224,6 +225,7 @@ const engine_functions = { card53_event2, card54_event1, setup_return_card_from_trash, + trash_card, }; function get_active(engine) { for (let i of engine) { @@ -475,6 +477,7 @@ function setup(seed, _scenario, _options) { year: 0, glory_current_year: null, fascist: 0, + card_played: 0, }; game.player_order.push(exports.roles[random(2)]); game.player_order.push(game.player_order[1] === data_1.ANARCHIST ? data_1.COMMUNIST : data_1.ANARCHIST); @@ -945,7 +948,8 @@ states.play_card = { }, card(c) { const faction = get_active_faction(); - game.selected_cards[faction].push(c); + game.selected_cards[faction] = [c]; + game.card_played = 0; game.played_card = game.selected_cards[faction][0]; resolve_active_and_proceed(); }, @@ -975,7 +979,7 @@ states.choose_card = { }, card(c, player) { const faction = player_faction_map[player]; - game.selected_cards[faction].push(c); + game.selected_cards[faction] = [c]; }, undo(_, player) { const faction = player_faction_map[player]; @@ -1024,7 +1028,7 @@ function setup_momentum() { return; } const node = get_nodes_for_state('player_turn')[0]; - const player_needs_to_play_card = game.selected_cards[faction].length > 0; + const player_needs_to_play_card = !game.card_played; const { use_ap, use_morale_bonus, resolving_event } = node.a ?? {}; if (player_needs_to_play_card || use_ap || @@ -1483,7 +1487,7 @@ states.player_turn = { let { use_ap, use_morale_bonus, use_momentum } = get_active_node_args(); use_morale_bonus = use_morale_bonus && game.bonuses[data_1.MORALE_BONUS] === data_1.ON; const can_spend_hp = game.faction_turn === faction_id && game.hero_points[faction_id] > 0; - const can_play_card = game.selected_cards[faction_id].length > 0; + const can_play_card = !game.card_played; if (use_momentum) { gen_action('use_momentum'); if (use_ap || use_morale_bonus || can_play_card) { @@ -1517,9 +1521,11 @@ states.player_turn = { end_turn() { game.faction_turn = null; game.played_card = null; + game.selected_cards[get_active_faction()] = []; resolve_active_and_proceed(true); }, play_to_tableau() { + game.card_played = 1; const faction = get_active_faction(); const { strength } = play_card_to_tableau(faction); update_active_node_args({ @@ -1530,13 +1536,14 @@ states.player_turn = { next(); }, play_for_event() { + game.card_played = 1; const faction = get_active_faction(); const { effects } = play_card_for_event(faction); update_active_node_args({ resolving_event: true, }); const node = create_effects_node(effects, 'player_event'); - node.c.push(create_state_node('trash_card_played_for_event', faction)); + node.c.push(create_function_node('trash_card', faction)); node.c.push(create_function_node('end_resolving_event_effects')); insert_before_active_node(node); next(); @@ -1553,11 +1560,16 @@ states.player_turn = { next(); }, use_momentum() { + const faction = get_active_faction(); + game.card_played = 0; + game.selected_cards[faction] = []; update_active_node_args({ use_morale_bonus: false, use_momentum: false, }); - setup_momentum(); + insert_before_active_node(create_state_node('play_card', faction, { + src: 'momentum', + })); next(); }, use_morale_bonus() { @@ -1896,18 +1908,8 @@ function trash_card() { array_remove(game.hands[faction], game.hands[faction].indexOf(card_id)); array_remove(game.selected_cards[faction], index); game.trash[faction].push(card_id); + resolve_active_and_proceed(); } -states.trash_card_played_for_event = { - inactive: 'trash their card', - prompt() { - view.prompt = 'Trash your card'; - gen_action('trash_card'); - }, - trash_card() { - trash_card(); - resolve_active_and_proceed(); - }, -}; states.use_organization_medallion = { inactive: 'use Organization Medallion', prompt() { @@ -1930,7 +1932,7 @@ states.use_organization_medallion = { else { v--; } - move_track(t, v); + move_track(t, v - game.tracks[t]); resolve_active_and_proceed(); }, no() { @@ -2250,7 +2252,6 @@ function play_card_to_tableau(faction) { const card = cards[card_id]; game.played_card = card_id; array_remove(game.hands[faction], game.hands[faction].indexOf(card_id)); - array_remove(game.selected_cards[faction], index); log('Played to Tableau:'); game.tableaus[faction].push(card_id); return card; @@ -262,6 +262,7 @@ function setup_final_bid() { function setup_player_turn() { game.fascist = 0; + game.card_played = 0; const next_faction = game.first_player === null @@ -352,6 +353,7 @@ const engine_functions: Record<string, Function> = { card53_event2, card54_event1, setup_return_card_from_trash, + trash_card, }; function get_active( @@ -661,6 +663,7 @@ export function setup(seed: number, _scenario: string, _options: unknown) { year: 0, glory_current_year: null, fascist: 0, + card_played: 0, }; // Randomly choose second player @@ -1206,8 +1209,10 @@ states.play_card = { }, card(c: CardId) { const faction = get_active_faction(); - game.selected_cards[faction].push(c); + game.selected_cards[faction] = [c]; + game.card_played = 0; + // NOTE: I don't think we are using game.played_card in the UI at the moment? game.played_card = game.selected_cards[faction][0]; resolve_active_and_proceed(); @@ -1241,7 +1246,7 @@ states.choose_card = { }, card(c: CardId, player: Player) { const faction = player_faction_map[player]; - game.selected_cards[faction].push(c); + game.selected_cards[faction] = [c]; }, undo(_, player: Player) { const faction = player_faction_map[player]; @@ -1305,7 +1310,7 @@ function setup_momentum() { // Get player turn node const node: StateNode<PlayerTurnArgs> = get_nodes_for_state('player_turn')[0]; - const player_needs_to_play_card = game.selected_cards[faction].length > 0; + const player_needs_to_play_card = !game.card_played; const { use_ap, use_morale_bonus, resolving_event } = node.a ?? ({} as PlayerTurnArgs); @@ -1840,7 +1845,7 @@ states.player_turn = { const can_spend_hp = game.faction_turn === faction_id && game.hero_points[faction_id] > 0; - const can_play_card = game.selected_cards[faction_id].length > 0; + const can_play_card = !game.card_played; if (use_momentum) { gen_action('use_momentum'); if (use_ap || use_morale_bonus || can_play_card) { @@ -1876,9 +1881,11 @@ states.player_turn = { end_turn() { game.faction_turn = null; game.played_card = null; + game.selected_cards[get_active_faction()] = []; resolve_active_and_proceed(true); }, play_to_tableau() { + game.card_played = 1; const faction = get_active_faction(); const { strength } = play_card_to_tableau(faction); update_active_node_args<PlayerTurnArgs>({ @@ -1889,6 +1896,7 @@ states.player_turn = { next(); }, play_for_event() { + game.card_played = 1; const faction = get_active_faction(); const { effects } = play_card_for_event(faction); update_active_node_args<PlayerTurnArgs>({ @@ -1896,7 +1904,7 @@ states.player_turn = { }); const node = create_effects_node(effects, 'player_event'); - node.c.push(create_state_node('trash_card_played_for_event', faction)); + node.c.push(create_function_node('trash_card', faction)); node.c.push(create_function_node('end_resolving_event_effects')); insert_before_active_node(node); @@ -1916,14 +1924,21 @@ states.player_turn = { next(); }, use_momentum() { + const faction = get_active_faction(); // We need to update since there can be a case where // morale bonus hasn't been used yet but is still set to true // due to bonus being turned off. + game.card_played = 0; + game.selected_cards[faction] = []; update_active_node_args<PlayerTurnArgs>({ use_morale_bonus: false, use_momentum: false, }); - setup_momentum(); + insert_before_active_node( + create_state_node<PlayCardArgs>('play_card', faction, { + src: 'momentum', + }) + ) next(); }, use_morale_bonus() { @@ -2341,25 +2356,9 @@ function trash_card() { array_remove(game.hands[faction], game.hands[faction].indexOf(card_id)); array_remove(game.selected_cards[faction], index); game.trash[faction].push(card_id); + resolve_active_and_proceed(); } -states.trash_card_played_for_event = { - inactive: 'trash their card', - prompt() { - view.prompt = 'Trash your card'; - gen_action('trash_card'); - }, - // NOTE: uncomment this to autoresolve - // auto_resolve() { - // trash_card(); - // return true; - // }, - trash_card() { - trash_card(); - resolve_active_and_proceed(); - }, -}; - states.use_organization_medallion = { inactive: 'use Organization Medallion', prompt() { @@ -2377,15 +2376,18 @@ states.use_organization_medallion = { pay_hero_points(faction, 1); game.used_medallions.push(ORGANIZATION_MEDALLION_ID); + // Value is the clicked location on the track let { t, v } = get_active_node_args(); + // If player uses medallion we need to add or subtract + // depending on direction of movement if (v > game.tracks[t]) { v++; } else { v--; } - move_track(t, v); + move_track(t, v - game.tracks[t]); resolve_active_and_proceed(); }, no() { @@ -2815,8 +2817,7 @@ function play_card_to_tableau(faction: FactionId): PlayerCard { game.played_card = card_id; array_remove(game.hands[faction], game.hands[faction].indexOf(card_id)); - // TODO: keep card selected during resolution - array_remove(game.selected_cards[faction], index); + log('Played to Tableau:'); game.tableaus[faction].push(card_id); return card as PlayerCard; @@ -73,6 +73,7 @@ export interface Game { used_medallions: number[]; glory_current_year?: Record<FactionId, boolean> | null; fascist: 0 | 1; + card_played: 0 | 1; } export interface View { |