summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Andersson <tor@ccxvii.net>2025-03-19 00:35:42 +0100
committerTor Andersson <tor@ccxvii.net>2025-03-19 00:35:42 +0100
commit43751f0bdb0736cd2222fccc4c96af63369e4e4c (patch)
tree422c24f5228a87f6e1d42d778c513ce06a3e6dd7
parentaba8efc5d2d64725d79de4d284266e0f99b59605 (diff)
downloadland-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.pngbin0 -> 1660 bytes
-rw-r--r--images/icons/player_communist.pngbin0 -> 1631 bytes
-rw-r--r--images/icons/player_fascist.pngbin0 -> 1037 bytes
-rw-r--r--images/icons/player_moderate.pngbin0 -> 1451 bytes
-rw-r--r--play.css17
-rw-r--r--play.html2
-rw-r--r--play.js36
-rw-r--r--rules.js164
-rw-r--r--rules.ts232
9 files changed, 229 insertions, 222 deletions
diff --git a/images/icons/player_anarchist.png b/images/icons/player_anarchist.png
new file mode 100644
index 0000000..841bf95
--- /dev/null
+++ b/images/icons/player_anarchist.png
Binary files differ
diff --git a/images/icons/player_communist.png b/images/icons/player_communist.png
new file mode 100644
index 0000000..20bcbfb
--- /dev/null
+++ b/images/icons/player_communist.png
Binary files differ
diff --git a/images/icons/player_fascist.png b/images/icons/player_fascist.png
new file mode 100644
index 0000000..5addf45
--- /dev/null
+++ b/images/icons/player_fascist.png
Binary files differ
diff --git a/images/icons/player_moderate.png b/images/icons/player_moderate.png
new file mode 100644
index 0000000..bac73ac
--- /dev/null
+++ b/images/icons/player_moderate.png
Binary files differ
diff --git a/play.css b/play.css
index 2ad6d9d..e1ec1b8 100644
--- a/play.css
+++ b/play.css
@@ -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;
diff --git a/play.html b/play.html
index 77addab..8000203 100644
--- a/play.html
+++ b/play.html
@@ -17,6 +17,8 @@
</head>
<body>
+<div id="tooltip"></div>
+
<header>
<div id="toolbar">
<details>
diff --git a/play.js b/play.js
index 0415fff..24f26ee 100644
--- a/play.js
+++ b/play.js
@@ -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, "&gt;")
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]
diff --git a/rules.js b/rules.js
index bb5c6ac..c2b93f0 100644
--- a/rules.js
+++ b/rules.js
@@ -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() {
diff --git a/rules.ts b/rules.ts
index 31d4e92..fbcc77b 100644
--- a/rules.ts
+++ b/rules.ts
@@ -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)
}
}