summaryrefslogtreecommitdiff
path: root/rules.js
diff options
context:
space:
mode:
Diffstat (limited to 'rules.js')
-rw-r--r--rules.js108
1 files changed, 88 insertions, 20 deletions
diff --git a/rules.js b/rules.js
index 6920a5e..abff1d8 100644
--- a/rules.js
+++ b/rules.js
@@ -136,6 +136,7 @@ function setup_bag_of_glory() {
function setup_choose_card() {
const player_order = get_player_order();
game.engine = player_order.map((faction_id) => create_leaf_node('choose_card', faction_id));
+ game.engine.push(create_leaf_node('confirm_turn', player_order[2]));
game.engine.push(create_function_node('setup_player_turn'));
next();
}
@@ -174,6 +175,7 @@ function end_of_player_turn() {
const { f: faction } = get_active_node_args();
if (get_next_faction_in_player_order(faction) === game.first_player) {
game.engine = [
+ create_leaf_node('change_active_player', game.initiative),
create_function_node('resolve_fascist_test'),
create_function_node('setup_bag_of_glory'),
];
@@ -196,6 +198,7 @@ const engine_functions = {
checkpoint,
end_of_player_turn,
end_of_turn,
+ end_of_year_cleanup,
end_resolving_event_effects,
setup_bag_of_glory,
setup_choose_card,
@@ -286,7 +289,10 @@ function insert_after_active_node(node, engine = game.engine) {
function insert_before_active_node(node, engine = game.engine) {
insert_before_or_after_active_node(node, 'before', engine);
}
-function next() {
+function next(checkpoint = false) {
+ if (checkpoint) {
+ clear_undo();
+ }
const node = get_active_node(game.engine);
if (node.t === function_node && engine_functions[node.f]) {
const args = node.a;
@@ -312,18 +318,15 @@ function next() {
}
}
}
-function resolve_active_node(checkpoint = false) {
+function resolve_active_node() {
const next_node = get_active_node(game.engine);
if (next_node !== null) {
next_node.r = resolved;
}
- if (checkpoint) {
- clear_undo();
- }
}
function resolve_active_and_proceed(checkpoint = false) {
- resolve_active_node(checkpoint);
- next();
+ resolve_active_node();
+ next(checkpoint);
}
function game_view(state, current) {
game = state;
@@ -464,6 +467,7 @@ function setup(seed, _scenario, _options) {
top_of_events_deck: null,
turn: 0,
year: 0,
+ glory_current_year: null,
};
game.player_order.push(exports.roles[random(2)]);
game.player_order.push(game.player_order[1] === data_1.ANARCHIST ? data_1.COMMUNIST : data_1.ANARCHIST);
@@ -516,6 +520,12 @@ function start_turn() {
}
next();
}
+function player_can_resolve_icon(icon) {
+ if (icon === 'teamwork_on' && game.bonuses[data_1.TEAMWORK_BONUS] === data_1.ON) {
+ return false;
+ }
+ return true;
+}
states.activate_icon = {
inactive: 'activate an icon',
prompt() {
@@ -524,6 +534,9 @@ states.activate_icon = {
const c = cards[game.played_card];
for (const i of c.icons) {
gen_action(i);
+ if (!player_can_resolve_icon(i)) {
+ view.actions[i] = 0;
+ }
}
},
spend_hp() {
@@ -820,6 +833,15 @@ states.break_tie_winner = {
resolve_active_and_proceed();
},
};
+states.change_active_player = {
+ inactive: '',
+ auto_resolve() {
+ return true;
+ },
+ prompt() {
+ view.prompt = '';
+ }
+};
states.choose_area_ap = {
inactive: 'choose area to use Action Points',
prompt() {
@@ -1060,6 +1082,30 @@ states.draw_card = {
resolve_active_and_proceed();
},
};
+states.draw_glory = {
+ inactive: 'draw from the Bag of Glory',
+ prompt() {
+ gen_spend_hero_points();
+ view.prompt = 'Draw from the Bag of Glory';
+ gen_action('draw_glory');
+ },
+ draw_glory() {
+ const index = random(game.bag_of_glory.length);
+ const faction = game.bag_of_glory[index];
+ game.glory.push(faction);
+ if (!game.glory_current_year) {
+ game.glory_current_year = game.glory_current_year = {
+ a: false,
+ c: false,
+ m: false,
+ };
+ }
+ 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`);
+ resolve_active_and_proceed(true);
+ },
+};
states.end_of_year_discard = {
inactive: 'discard cards from hand and tableau',
prompt() {
@@ -1260,6 +1306,21 @@ function can_move_track_down(track_id) {
}
states.move_track_up_or_down = {
inactive: 'move a track',
+ auto_resolve() {
+ const { track_id, strength } = get_active_node_args();
+ const can_move_up = can_move_track_up(track_id);
+ const can_move_down = can_move_track_down(track_id);
+ if (can_move_up && can_move_down) {
+ return false;
+ }
+ if (can_move_up) {
+ move_track(track_id, strength);
+ }
+ else if (can_move_down) {
+ move_track(track_id, -1 * strength);
+ }
+ return true;
+ },
prompt() {
gen_spend_hero_points();
const { track_id } = get_active_node_args();
@@ -2062,33 +2123,32 @@ function end_of_year() {
log_h1('End of year');
}
const glory_to_draw = [0, 1, 2, 5];
- const glory_this_year = {
+ game.glory_current_year = {
a: false,
c: false,
m: false,
};
- const drawn_glory = [];
+ const player_order = get_player_order();
+ const engine = [];
for (let i = 0; i < glory_to_draw[game.year]; ++i) {
- const index = random(game.bag_of_glory.length);
- const faction = game.bag_of_glory[index];
- game.glory.push(faction);
- drawn_glory.push(faction);
- glory_this_year[faction] = true;
- array_remove(game.bag_of_glory, index);
+ engine.push(create_leaf_node('draw_glory', player_order[i % 3]));
}
- log(`Tokens pulled from the Bag of Glory: ${drawn_glory
- .map((faction_id) => `<ft${faction_id}>`)
- .join('')}`);
+ engine.push(create_function_node('end_of_year_cleanup'));
+ game.engine = engine;
+ next(true);
+}
+function end_of_year_cleanup() {
if (game.year === 3) {
determine_winner();
return;
}
- const players_to_gain_hero_points = role_ids.filter((f) => !glory_this_year[f]);
+ const players_to_gain_hero_points = role_ids.filter((f) => !game.glory_current_year?.[f]);
gain_hero_points_in_player_order(players_to_gain_hero_points, game.year);
game.engine = get_player_order().map((f) => create_function_node('check_end_of_year_discard', { f }));
game.engine.push(create_function_node('checkpoint'));
game.engine.push(create_function_node('start_year'));
game.top_of_events_deck = null;
+ game.glory_current_year = null;
next();
}
function end_resolving_event_effects() {
@@ -2165,6 +2225,7 @@ function resolve_fascist_test() {
const status = game.fronts[test.front].status;
const test_passed = status === data_1.VICTORY ||
(status !== data_1.DEFEAT && game.fronts[test.front].value >= test.value);
+ const hero_point_actions = [];
if (test_passed) {
log('The Test is passed');
for (const faction of get_player_order()) {
@@ -2175,9 +2236,13 @@ function resolve_fascist_test() {
hero_points_gain += 2;
}
if (hero_points_gain > 0) {
- gain_hero_points(faction, hero_points_gain);
+ const node = resolve_effect((0, data_1.create_effect)('hero_points', faction, hero_points_gain));
+ hero_point_actions.push(node);
}
}
+ if (hero_point_actions.length > 0) {
+ insert_after_active_node(create_seq_node(hero_point_actions));
+ }
}
else {
log('The Test is failed');
@@ -2227,6 +2292,9 @@ function get_fronts_to_add_to(target, not = []) {
else if (game.fronts[target].status === data_1.DEFEAT) {
return get_fronts_closest_to(data_1.CLOSEST_TO_DEFEAT);
}
+ else if (game.fronts[target].status === data_1.VICTORY) {
+ return get_fronts_to_add_to(data_1.ANY);
+ }
else {
return [target];
}