diff options
Diffstat (limited to 'rules.ts')
-rw-r--r-- | rules.ts | 232 |
1 files changed, 95 insertions, 137 deletions
@@ -229,7 +229,6 @@ function checkpoint() { } function setup_bag_of_glory() { - log_h1('Bag of Glory'); game.engine = [ create_state_node('add_glory', game.initiative), create_function_node('end_of_turn'), @@ -249,7 +248,7 @@ function setup_choose_card() { function setup_final_bid() { game.fascist = 0; - log_h1('Final Bid'); + log_header('Final Bid', 't'); const player_order = get_player_order(); game.engine = player_order.map((faction_id) => create_state_node('choose_final_bid', faction_id) @@ -312,10 +311,9 @@ function end_of_player_turn() { function start_of_player_turn() { const args = get_active_node_args(); - const player = faction_player_map[args.f]; game.faction_turn = args.f; game.played_card = game.selected_cards[args.f][0]; - log_h2(cards[game.played_card].title, player); + log_header("C" + game.played_card, args.f); resolve_active_and_proceed(); } @@ -334,6 +332,7 @@ const engine_functions: Record<string, Function> = { start_year, resolve_fascist_test, resolve_final_bid, + log_trigger, // Unique card effects card1_event2, card3_event2, @@ -666,6 +665,8 @@ export function setup(seed: number, _scenario: string, options: Record<string,bo card_played: 0, }; + log_header('Land and Freedom', 't') + if (options.hidden_bag) game.hidden_bag = 1; @@ -682,7 +683,7 @@ export function setup(seed: number, _scenario: string, options: Record<string,bo return game; } -function draw_hand_cards(faction_id: FactionId, count: number) { +function draw_hand_cards(faction_id: FactionId, count: number, indent = true) { const deck = list_deck(faction_id); if (game.medallions[faction_id].includes(INTELLIGENCE_MEDALLION_ID)) { @@ -705,33 +706,35 @@ function draw_hand_cards(faction_id: FactionId, count: number) { drawn_cards++; } } - const log = - drawn_cards === 1 - ? `${get_player(faction_id)} draws 1 card` - : `${get_player(faction_id)} draws ${drawn_cards} cards`; - logi(log); + + if (indent) + logi(`${get_player(faction_id)} +${drawn_cards} cards`); + else + log(`${get_player(faction_id)} +${drawn_cards} cards.`); } // #endregion function start_year() { game.year++; + log_header(`Year ${game.year}`, 't'); game.turn = 1; game.current_events = []; role_ids.forEach((role) => { - draw_hand_cards(role, 5); + draw_hand_cards(role, 5, false); }); start_turn(); } function start_turn() { - log_h1(`Year ${game.year} - Turn ${game.turn}`); + log_header(`Turn ${game.turn}`, 't'); const cardId = draw_fascist_card(); game.current_events.push(cardId); const card = cards[cardId] as EventCard; - log_h2(card.title, 'fascist'); + log_header("C" + cardId, 'f') + log("Fascist Event:") game.fascist = 1; game.engine = card.effects.map((effect) => @@ -933,12 +936,9 @@ states.add_card_to_tableau = { }, card(c: CardId) { 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` - ); + logp(`added C${c} to their tableau`); resolve_active_and_proceed(); }, skip() { @@ -1358,10 +1358,10 @@ function setup_momentum() { } states.choose_medallion = { - inactive: 'choose a medallion', + inactive: 'earn a medallion', prompt() { gen_spend_hero_points(); - view.prompt = 'Choose a Medallion.'; + view.prompt = 'Earn a Medallion.'; for (let m of game.medallions.pool) { gen_action_medallion(m); } @@ -1376,7 +1376,7 @@ states.choose_medallion = { const faction = get_active_faction(); const medallion = medallions[m]; - logi(`${faction_player_map[faction]} earns ${medallion.name}`); + logp(`earned ${medallion.name}`); const index = game.medallions.pool.indexOf(m); @@ -1384,7 +1384,7 @@ states.choose_medallion = { switch (m) { case 0: - add_glory(faction, 1, true); + add_glory(faction, 1); break; case 1: gain_hero_points(faction, 7); @@ -1459,7 +1459,7 @@ states.draw_glory = { inactive: 'draw from the Bag of Glory', prompt() { gen_spend_hero_points(); - view.prompt = 'Draw from the Bag of Glory'; + view.prompt = 'Draw from the Bag of Glory.'; gen_action('draw_glory'); }, draw_glory() { @@ -1481,11 +1481,8 @@ states.draw_glory = { array_remove(game.bag_of_glory, index); - log( - `${get_player( - get_active_faction() - )} draws <ft${faction}> from the Bag of Glory` - ); + logi(`Pulled T${faction} from the Bag`); + resolve_active_and_proceed(true); }, }; @@ -1531,7 +1528,7 @@ states.end_of_year_discard = { // More cards to discard so resolve same state again next(); } else { - log(`${faction_player_map[faction_id]} discards cards`); + log(`${game.active} discarded cards.`); resolve_active_and_proceed(); } }, @@ -1839,11 +1836,10 @@ states.peek_fascist_cards = { function resolve_spend_hp() { // insert spend hero points node before current node // so it will return to current node after resolving + log("Hero Points:") insert_before_active_node( create_state_node('spend_hero_points', get_active_faction()) ); - log('Spends Hero Points'); - next(); } @@ -1933,6 +1929,7 @@ states.player_turn = { play_for_event() { game.card_played = 1; const faction = get_active_faction(); + log('Played for Event:'); const { effects } = play_card_for_event(faction); update_active_node_args<PlayerTurnArgs>({ resolving_event: true, @@ -1946,6 +1943,7 @@ states.player_turn = { next(); }, use_ap() { + log("Action Points:"); const faction = get_active_faction(); const { strength } = get_active_node_args(); update_active_node_args({ @@ -1959,6 +1957,7 @@ states.player_turn = { next(); }, use_momentum() { + log("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 @@ -1977,6 +1976,7 @@ states.player_turn = { next(); }, use_morale_bonus() { + log(`Morale Bonus:`) // Update args before inserting node before current node, // otherwise it will update args of inserted node update_active_node_args({ @@ -2008,14 +2008,7 @@ states.remove_blank_marker = { const track_id = Math.floor(b / 11); const space_id = b % 11; - - logi( - `${ - faction_player_map[faction] - } removes a Blank marker from space ${space_id} of ${get_track_name( - track_id - )}` - ); + logp(`removed blank marker from ${get_track_name(track_id)} ${space_id}`); game.triggered_track_effects = game.triggered_track_effects.filter( (id) => id !== b ); @@ -2129,7 +2122,7 @@ states.return_card = { const faction = get_active_faction(); array_remove(game.trash[faction], game.trash[faction].indexOf(c)); game.hands[faction].push(c); - logi(`${faction_player_map[faction]} returns a card to their hand`); + logp(`returned a card to their hand`); resolve_active_and_proceed(); }, skip() { @@ -2384,8 +2377,7 @@ states.take_hero_points = { }, }; -function trash_card() { - const faction = get_active_faction(); +function trash_card(faction: FactionId) { const index = game.selected_cards[faction].length - 1; const card_id = game.selected_cards[faction][index]; @@ -2610,22 +2602,14 @@ function setup_return_card_from_trash() { function add_glory( faction: FactionId, - amount: number, - indent: boolean = false + amount: number ) { - let tokens_log = ''; - for (let i = 0; i < amount; ++i) { - game.bag_of_glory.push(get_active_faction()); - tokens_log += `<ft${faction}>`; - } - - let text = `${faction_player_map[faction]} adds ${tokens_log} to the Bag of Glory`; - - if (indent) { - logi(text); - } else { - log_h3(text); - } + for (let i = 0; i < amount; ++i) + game.bag_of_glory.push(faction); + if (amount > 1) + logi(`Added ${amount} T${faction} to the Bag`); + else + logi(`Added T${faction} to the Bag`); } function check_initiative() { @@ -2642,7 +2626,7 @@ function check_initiative() { return; } game.initiative = initiative; - logi(`${faction_player_map[initiative]} claims the Initiative`); + logi(`${faction_player_map[initiative]} claimed Initiative`); } function war_is_won() { @@ -2703,18 +2687,17 @@ function end_of_turn() { } function end_of_year() { + log_header('End of Year', 't'); + if (game.year === 3) { - log_h1('End of the game'); const is_won = war_is_won(); if (is_won) { log('The war is won!'); } else { - game_over('None', 'The war is lost. All Players lose the game!'); + game_over('Fascist', 'The war is lost. All players lose the game!'); resolve_active_and_proceed(); return; } - } else { - log_h1('End of year'); } const glory_to_draw = [0, 1, 2, 5]; @@ -2817,14 +2800,10 @@ function gain_hero_points( const gain = Math.min(game.hero_points.pool, value); game.hero_points.pool -= gain; game.hero_points[faction_id] += gain; - logi( - `${get_player(faction_id)} +${gain} ${ - gain === 1 ? 'Hero Point' : 'Hero Points' - }` - ); + logi(`${get_player(faction_id)} +${gain} HP`); } -function game_over(result: Player | 'None', victory: string) { +function game_over(result: Player | 'Fascist', victory: string) { insert_after_active_node(create_state_node('game_over', 'None')); game.result = result; game.victory = victory; @@ -2846,9 +2825,6 @@ function play_card_for_event(faction: FactionId): PlayerCard { const card_id = game.selected_cards[faction][index]; const card = cards[card_id]; game.played_card = card_id; - - log('Played for Event:'); - return card as PlayerCard; } @@ -2860,7 +2836,6 @@ function play_card_to_tableau(faction: FactionId): PlayerCard { array_remove(game.hands[faction], game.hands[faction].indexOf(card_id)); - log('Played to Tableau:'); game.tableaus[faction].push(card_id); return card as PlayerCard; } @@ -2868,20 +2843,23 @@ function play_card_to_tableau(faction: FactionId): PlayerCard { function resolve_fascist_test() { game.fascist = 2; - log_h2('Fascist Test', 'fascist'); - const test = get_current_event().test; - const status = game.fronts[test.front].status; + const front = test.front + const status = game.fronts[front].status; + const test_passed = status === VICTORY || - (status !== DEFEAT && game.fronts[test.front].value >= test.value); + (status !== DEFEAT && game.fronts[front].value >= test.value); const hero_point_actions: EngineNode[] = []; + log_header("C" + get_current_event_id(), 'f'); + if (test_passed) { - log('The Test is passed'); + log(front_names[front] + ' passed:'); + for (const faction of get_player_order()) { - let hero_points_gain = game.fronts[test.front].contributions.includes( + let hero_points_gain = game.fronts[front].contributions.includes( faction ) ? 2 @@ -2902,7 +2880,7 @@ function resolve_fascist_test() { insert_after_active_node(create_seq_node(hero_point_actions)); } } else { - log('The Test is failed'); + log(front_names[front] + ' failed:'); } const effect = test_passed ? test.pass : test.fail; @@ -3071,6 +3049,7 @@ function move_track_to(track_id: number, new_value: number) { const node = resolve_effect(trigger, tracks[track_id].action); if (node !== null) { insert_after_active_node(node); + insert_after_active_node(create_function_node('log_trigger', [track_id, space_id])); } } }); @@ -3113,7 +3092,10 @@ function update_bonus(bonus_id: number, status: number) { return; } game.bonuses[bonus_id] = status; - logi(`${bonus_names[bonus_id]} ${status === ON ? 'on' : 'off'}`); + if (status === ON) + logi(`${bonus_names[bonus_id]} on`); + else + logi(`${bonus_names[bonus_id]} off`); } function update_front( @@ -3137,7 +3119,7 @@ function update_front( } const value_before = game.fronts[front_id].value; game.fronts[front_id].value += change; - logi(`${front_names[front_id]}: ${change > 0 ? '+' : ''}${change}`); + logi(`${front_names[front_id]} ${change > 0 ? '+' : ''}${change}`); if ( faction_id !== null && value_before <= 0 && @@ -3177,10 +3159,14 @@ function update_front( function defeat_on_a_front(front_id: FrontId) { game.fronts[front_id].status = DEFEAT; - log('Defeat on ' + get_front_name(front_id)); + + log_br() + log('Defeat on ' + get_front_name(front_id) + '!'); + log_br() + // Check game end if (front_id === 'm' || get_defeated_front_count() == 2) { - game_over('None', 'All players lose the game!'); + game_over('Fascist', 'All players lose the game!'); return; } insert_after_active_node( @@ -3195,7 +3181,11 @@ function defeat_on_a_front(front_id: FrontId) { function victory_on_a_front(front_id: FrontId) { game.fronts[front_id].status = VICTORY; - log('Victory on ' + get_front_name(front_id)); + + log_br() + log('Victory on ' + get_front_name(front_id) + '!'); + log_br() + gain_hero_points_in_player_order(game.fronts[front_id].contributions, 3); } @@ -3254,6 +3244,7 @@ function resolve_effect(effect: Effect, source?: EffectSource): EngineNode { src: source, }); } + // Default cases where effect type is mapped to a state let state = effect_type_state_map[effect.type]; if (state !== undefined) { @@ -3366,8 +3357,7 @@ function resolve_effect(effect: Effect, source?: EffectSource): EngineNode { if (strategy) { return strategy.resolve(); } else { - console.log('----UNRESOLVED EFFECT----', effect); - throw new Error('Unresolved effect'); + throw new Error('Unresolved effect: ' + effect); } } @@ -3406,14 +3396,8 @@ function lose_hero_points(faction: FactionId, value: number) { const points_lost = Math.min(game.hero_points[faction], Math.abs(value)); game.hero_points.pool += points_lost; game.hero_points[faction] -= points_lost; - if (points_lost === 0) { - return; - } - if (points_lost === 1) { - log(`${get_player(faction)}: -1 Hero Point`); - } else { - log(`${get_player(faction)}: -${points_lost} Hero Points`); - } + if (points_lost !== 0) + logi(`${get_player(faction)} -${points_lost} HP`); } // #endregion @@ -3457,55 +3441,25 @@ function log(msg: string) { game.log.push(msg); } -// function logevent(cap: Card) { -// game.log.push(`E${cap}.`) -// } - -// function logcap(cap: Card) { -// game.log.push(`C${cap}.`) -// } - -function logi(msg: string) { - log('>' + msg); -} - -// function logii(msg: string) { -// log('>>' + msg); -// } - -function log_h1(msg: string) { +function log_header(msg: string, prefix: string) { log_br(); - log('#t ' + msg); + log(`#${prefix} ${msg}`); log_br(); } -function log_h2(msg: string, player?: Player | 'fascist') { - log_br(); - log(`#${player[0].toLowerCase()} ${msg}`); - log_br(); +function log_trigger(args) { + let [ track_id, space_id ] = args; + log(`Trigger ${get_track_name(track_id)} #${space_id}:`); + resolve_active_and_proceed(); } -// function log_h2_active(msg: string) { -// log_br(); -// log('.h2 ' + msg); -// log_br(); -// } - -// function log_h2_common(msg: string) { -// log_br(); -// log('.h2 ' + msg); -// log_br(); -// } - -function log_h3(msg: string) { - log_br(); - log('.h3 ' + msg); +function logi(msg: string) { + log(">" + msg); } -// function log_h4(msg: string) { -// log_br(); -// log('.h4 ' + msg); -// } +function logp(msg: string) { + log(">" + game.active + " " + msg); +} // #endregion LOGGING @@ -3523,10 +3477,12 @@ function get_front_name(id: FrontId | 'd' | 'v') { return front_names[id]; } +function get_current_event_id(): CardId { + return game.current_events[game.current_events.length - 1] +} + function get_current_event(): EventCard { - return cards[ - game.current_events[game.current_events.length - 1] - ] as EventCard; + return cards[get_current_event_id()] as EventCard; } function get_defeated_front_count() { @@ -3722,11 +3678,13 @@ function list_deck(id: FactionId | 'f') { function draw_medallions() { const medallion_ids = make_list(0, 8) as number[]; + log("Medallions:") for (let m = 0; m < 5; ++m) { let i = random(medallion_ids.length); let r = medallion_ids[i] as CardId; set_delete(medallion_ids, r); game.medallions.pool.push(r); + logi("M" + r) } } |