diff options
author | Tor Andersson <tor@ccxvii.net> | 2025-03-19 00:35:42 +0100 |
---|---|---|
committer | Tor Andersson <tor@ccxvii.net> | 2025-03-19 00:35:42 +0100 |
commit | 43751f0bdb0736cd2222fccc4c96af63369e4e4c (patch) | |
tree | 422c24f5228a87f6e1d42d778c513ce06a3e6dd7 | |
parent | aba8efc5d2d64725d79de4d284266e0f99b59605 (diff) | |
download | land-and-freedom-43751f0bdb0736cd2222fccc4c96af63369e4e4c.tar.gz |
Tweak log messages.
Loss result to "Fascist" (instead of "None").
Use correct faction in trash_card.
-rw-r--r-- | images/icons/player_anarchist.png | bin | 0 -> 1660 bytes | |||
-rw-r--r-- | images/icons/player_communist.png | bin | 0 -> 1631 bytes | |||
-rw-r--r-- | images/icons/player_fascist.png | bin | 0 -> 1037 bytes | |||
-rw-r--r-- | images/icons/player_moderate.png | bin | 0 -> 1451 bytes | |||
-rw-r--r-- | play.css | 17 | ||||
-rw-r--r-- | play.html | 2 | ||||
-rw-r--r-- | play.js | 36 | ||||
-rw-r--r-- | rules.js | 164 | ||||
-rw-r--r-- | rules.ts | 232 |
9 files changed, 229 insertions, 222 deletions
diff --git a/images/icons/player_anarchist.png b/images/icons/player_anarchist.png Binary files differnew file mode 100644 index 0000000..841bf95 --- /dev/null +++ b/images/icons/player_anarchist.png diff --git a/images/icons/player_communist.png b/images/icons/player_communist.png Binary files differnew file mode 100644 index 0000000..20bcbfb --- /dev/null +++ b/images/icons/player_communist.png diff --git a/images/icons/player_fascist.png b/images/icons/player_fascist.png Binary files differnew file mode 100644 index 0000000..5addf45 --- /dev/null +++ b/images/icons/player_fascist.png diff --git a/images/icons/player_moderate.png b/images/icons/player_moderate.png Binary files differnew file mode 100644 index 0000000..bac73ac --- /dev/null +++ b/images/icons/player_moderate.png @@ -14,6 +14,8 @@ body header.fascist.your_turn { background-color: hsl(30, 35%, 65%); } #log div.h.m { background-color: hsl(325, 30%, 75%); } #log div.h.f { background-color: hsl(30, 35%, 75%); } +#log img { height: 16px; vertical-align: -4px; border: 1px solid #444; } + .panel { background-image: url(images/texture.png) } .panel { background-color: hsl(0, 0%, 60%); } .panel.anarchist { background-color: hsl(257, 10%, 60%); } @@ -36,7 +38,13 @@ body header.fascist.your_turn { background-color: hsl(30, 35%, 65%); } .card.action { box-shadow: 0 0 0 4px cyan !important; } .card.selected { box-shadow: 0 0 0 4px blue !important; } - +#tooltip { + pointer-events: none; + position: fixed; + z-index: 600; + right: 240px; + top: 60px; +} #log div:empty { min-height: 6px; @@ -46,12 +54,19 @@ body header.fascist.your_turn { background-color: hsl(30, 35%, 65%); } background-color: tan; border-top: 1px solid black; border-bottom: 1px solid black; margin: 8px 0; + font-variant: small-caps; + text-align: center; + text-indent: 0; + padding: 0px 4px; } #log div { padding-left: 20px; text-indent: -12px; } #log div.i { padding-left: 32px; text-indent: -12px; } #log div.ii { padding-left: 44px; text-indent: -12px; } +#log .tip { cursor: pointer; } +#log .tip:hover { text-decoration: underline; } + #mapwrap { width: 1650px; height: 1275px; @@ -17,6 +17,8 @@ </head> <body> +<div id="tooltip"></div> + <header> <div id="toolbar"> <details> @@ -11,6 +11,8 @@ const ui = { map_container: document.getElementById("pieces"), + tooltip: document.getElementById("tooltip"), + fascist_cards: document.getElementById("fascist_cards"), trash: document.getElementById("trash"), hand: document.getElementById("hand"), @@ -586,6 +588,36 @@ function on_update() { // eslint-disable-line no-unused-vars animation_register.forEach(animate_position) } +function on_focus_card_tip(x) { + ui.tooltip.className = "card card_" + x +} + +function on_focus_medallion_tip(x) { + ui.tooltip.className = "pink token medallion medallion_" + x +} + +function on_blur_tip(x) { + ui.tooltip.className = "hide" +} + +function sub_card(_match, p1) { + return `<span class="tip" onmouseenter="on_focus_card_tip(${p1})" onmouseleave="on_blur_tip()">${data.cards[p1].title}</span>` +} + +function sub_medallion(_match, p1) { + return `<span class="tip" onmouseenter="on_focus_medallion_tip(${p1})" onmouseleave="on_blur_tip()">${data.medallions[p1].name}</span>` +} + +function sub_token(match) { + switch (match) { + case "Ta": return `<img src="images/icons/player_anarchist.png">` + case "Tc": return `<img src="images/icons/player_communist.png">` + case "Tm": return `<img src="images/icons/player_moderate.png">` + case "Tf": return `<img src="images/icons/player_fascist.png">` + } + return match +} + function on_log(text) { // eslint-disable-line no-unused-vars let p = document.createElement("div") @@ -603,7 +635,9 @@ function on_log(text) { // eslint-disable-line no-unused-vars text = text.replace(/>/g, ">") text = text.replace(/-( ?[\d(])/g, "\u2212$1") - // text = text.replace(/C(\d+)/g, sub_card) + text = text.replace(/\bC(\d+)\b/g, sub_card) + text = text.replace(/\bM(\d+)\b/g, sub_medallion) + text = text.replace(/\bT[acmf]\b/g, sub_token) if (text.startsWith("#")) { p.className = "h " + text[1] @@ -123,7 +123,6 @@ function checkpoint() { resolve_active_and_proceed(); } 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'), @@ -138,7 +137,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)); game.engine.push(create_function_node('checkpoint')); @@ -186,10 +185,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(); } const engine_functions = { @@ -207,6 +205,7 @@ const engine_functions = { start_year, resolve_fascist_test, resolve_final_bid, + log_trigger, card1_event2, card3_event2, card10_event2, @@ -482,6 +481,7 @@ function setup(seed, _scenario, options) { fascist: 0, card_played: 0, }; + log_header('Land and Freedom', 't'); if (options.hidden_bag) game.hidden_bag = 1; game.player_order.push(exports.roles[random(2)]); @@ -490,7 +490,7 @@ function setup(seed, _scenario, options) { start_year(); return game; } -function draw_hand_cards(faction_id, count) { +function draw_hand_cards(faction_id, count, indent = true) { const deck = list_deck(faction_id); if (game.medallions[faction_id].includes(data_1.INTELLIGENCE_MEDALLION_ID)) { count++; @@ -509,26 +509,28 @@ function draw_hand_cards(faction_id, count) { 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.`); } 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]; - log_h2(card.title, 'fascist'); + log_header("C" + cardId, 'f'); + log("Fascist Event:"); game.fascist = 1; game.engine = card.effects.map((effect) => resolve_effect(effect, 'fascist_event')); game.engine.push(create_state_node('confirm_fascist_turn', game.initiative, { src: 'fascist_event' })); @@ -707,10 +709,9 @@ states.add_card_to_tableau = { }, 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`); + logp(`added C${c} to their tableau`); resolve_active_and_proceed(); }, skip() { @@ -1075,10 +1076,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); } @@ -1092,12 +1093,12 @@ states.choose_medallion = { medallion(m) { 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); game.medallions.pool[index] = null; switch (m) { case 0: - add_glory(faction, 1, true); + add_glory(faction, 1); break; case 1: gain_hero_points(faction, 7); @@ -1168,7 +1169,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() { @@ -1184,7 +1185,7 @@ states.draw_glory = { } 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`); + logi(`Pulled T${faction} from the Bag`); resolve_active_and_proceed(true); }, }; @@ -1226,7 +1227,7 @@ states.end_of_year_discard = { next(); } else { - log(`${faction_player_map[faction_id]} discards cards`); + log(`${game.active} discarded cards.`); resolve_active_and_proceed(); } }, @@ -1502,8 +1503,8 @@ states.peek_fascist_cards = { }, }; function resolve_spend_hp() { + log("Hero Points:"); insert_before_active_node(create_state_node('spend_hero_points', get_active_faction())); - log('Spends Hero Points'); next(); } function set_player_turn_prompt({ can_play_card, use_ap, use_momentum, use_morale_bonus, }) { @@ -1579,6 +1580,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({ resolving_event: true, @@ -1590,6 +1592,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({ @@ -1601,6 +1604,7 @@ states.player_turn = { next(); }, use_momentum() { + log("Momentum:"); const faction = get_active_faction(); game.card_played = 0; game.selected_cards[faction] = []; @@ -1614,6 +1618,7 @@ states.player_turn = { next(); }, use_morale_bonus() { + log(`Morale Bonus:`); update_active_node_args({ use_morale_bonus: false, }); @@ -1638,7 +1643,7 @@ states.remove_blank_marker = { pay_hero_points(faction, 1); 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); game.used_medallions.push(data_1.ARCHIVES_MEDALLION_ID); resolve_active_and_proceed(); @@ -1732,7 +1737,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() { @@ -1943,8 +1948,7 @@ states.take_hero_points = { resolve_active_and_proceed(); }, }; -function trash_card() { - const faction = get_active_faction(); +function trash_card(faction) { const index = game.selected_cards[faction].length - 1; const card_id = game.selected_cards[faction][index]; array_remove(game.hands[faction], game.hands[faction].indexOf(card_id)); @@ -2098,19 +2102,13 @@ function card54_event1() { function setup_return_card_from_trash() { resolve_active_and_proceed(); } -function add_glory(faction, amount, indent = false) { - 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); - } +function add_glory(faction, amount) { + 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() { let initiative; @@ -2127,7 +2125,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() { let won_fronts = 0; @@ -2185,21 +2183,18 @@ 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]; game.glory_current_year = { a: false, @@ -2263,7 +2258,7 @@ function gain_hero_points(faction_id, value, skip_abilities = false) { 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, victory) { insert_after_active_node(create_state_node('game_over', 'None')); @@ -2285,7 +2280,6 @@ function play_card_for_event(faction) { const card_id = game.selected_cards[faction][index]; const card = cards[card_id]; game.played_card = card_id; - log('Played for Event:'); return card; } function play_card_to_tableau(faction) { @@ -2294,22 +2288,22 @@ 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)); - log('Played to Tableau:'); game.tableaus[faction].push(card_id); return card; } 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 === data_1.VICTORY || - (status !== data_1.DEFEAT && game.fronts[test.front].value >= test.value); + (status !== data_1.DEFEAT && game.fronts[front].value >= test.value); const hero_point_actions = []; + 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(faction) + let hero_points_gain = game.fronts[front].contributions.includes(faction) ? 2 : 0; if (can_use_medallion(data_1.PROPAGANDA_MEDALLION_ID, faction)) { @@ -2325,7 +2319,7 @@ function resolve_fascist_test() { } } else { - log('The Test is failed'); + log(front_names[front] + ' failed:'); } const effect = test_passed ? test.pass : test.fail; const node = resolve_effect(effect, 'fascist_test'); @@ -2464,6 +2458,7 @@ function move_track_to(track_id, new_value) { 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])); } } }); @@ -2495,7 +2490,10 @@ function update_bonus(bonus_id, status) { return; } game.bonuses[bonus_id] = status; - logi(`${bonus_names[bonus_id]} ${status === data_1.ON ? 'on' : 'off'}`); + if (status === data_1.ON) + logi(`${bonus_names[bonus_id]} on`); + else + logi(`${bonus_names[bonus_id]} off`); } function update_front(front_id, change, faction_id = null) { const player_token_on_front = faction_id !== null && @@ -2509,7 +2507,7 @@ function update_front(front_id, change, faction_id = null) { } 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 && game.fronts[front_id].value > 0) { @@ -2536,9 +2534,11 @@ function update_front(front_id, change, faction_id = null) { } function defeat_on_a_front(front_id) { game.fronts[front_id].status = data_1.DEFEAT; - log('Defeat on ' + get_front_name(front_id)); + log_br(); + log('Defeat on ' + get_front_name(front_id) + '!'); + log_br(); 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(create_effects_node([ @@ -2550,7 +2550,9 @@ function defeat_on_a_front(front_id) { } function victory_on_a_front(front_id) { game.fronts[front_id].status = data_1.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); } function create_effects_node(effects, source) { @@ -2685,8 +2687,7 @@ function resolve_effect(effect, source) { return strategy.resolve(); } else { - console.log('----UNRESOLVED EFFECT----', effect); - throw new Error('Unresolved effect'); + throw new Error('Unresolved effect: ' + effect); } } function win_final_bid(faction_id) { @@ -2716,15 +2717,8 @@ function lose_hero_points(faction, value) { 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`); } function get_fronts_closest_to(target) { const values = Object.values(game.fronts).reduce((accrued, current) => { @@ -2746,22 +2740,21 @@ function log_br() { function log(msg) { game.log.push(msg); } -function logi(msg) { - log('>' + msg); -} -function log_h1(msg) { +function log_header(msg, prefix) { log_br(); - log('#t ' + msg); + log(`#${prefix} ${msg}`); log_br(); } -function log_h2(msg, player) { - 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_h3(msg) { - log_br(); - log('.h3 ' + msg); +function logi(msg) { + log(">" + msg); +} +function logp(msg) { + log(">" + game.active + " " + msg); } function get_active_faction() { return player_faction_map[game.active]; @@ -2772,8 +2765,11 @@ function get_blank_marker_id(track_id, space_id) { function get_front_name(id) { return front_names[id]; } +function get_current_event_id() { + return game.current_events[game.current_events.length - 1]; +} function get_current_event() { - return cards[game.current_events[game.current_events.length - 1]]; + return cards[get_current_event_id()]; } function get_defeated_front_count() { let count = 0; @@ -2941,11 +2937,13 @@ function list_deck(id) { } function draw_medallions() { const medallion_ids = make_list(0, 8); + log("Medallions:"); for (let m = 0; m < 5; ++m) { let i = random(medallion_ids.length); let r = medallion_ids[i]; set_delete(medallion_ids, r); game.medallions.pool.push(r); + logi("M" + r); } } function clear_undo() { @@ -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) } } |