summaryrefslogtreecommitdiff
path: root/rules.ts
diff options
context:
space:
mode:
Diffstat (limited to 'rules.ts')
-rw-r--r--rules.ts232
1 files changed, 95 insertions, 137 deletions
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)
}
}