summaryrefslogtreecommitdiff
path: root/rules.js
diff options
context:
space:
mode:
authorFrans Bongers <fransbongers@franss-mbp.home>2025-02-16 19:51:08 +0100
committerFrans Bongers <fransbongers@franss-mbp.home>2025-02-16 19:53:04 +0100
commitdbd1660fc0f297d2b7b571af6038e53d6596161c (patch)
tree9966947e32fadfd457d6c227159b7ba3165a263b /rules.js
parente798a3c84d9c50e6723ab0fd7f22a9328a81199e (diff)
downloadland-and-freedom-dbd1660fc0f297d2b7b571af6038e53d6596161c.tar.gz
initial multiactive updates
Diffstat (limited to 'rules.js')
-rw-r--r--rules.js115
1 files changed, 65 insertions, 50 deletions
diff --git a/rules.js b/rules.js
index abff1d8..455475f 100644
--- a/rules.js
+++ b/rules.js
@@ -134,9 +134,7 @@ function setup_bag_of_glory() {
next();
}
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 = [create_leaf_node('choose_card', 'all')];
game.engine.push(create_function_node('setup_player_turn'));
next();
}
@@ -289,6 +287,20 @@ 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 get_next_active(p) {
+ if (Array.isArray(p)) {
+ return p.map((faction) => faction_player_map[faction]);
+ }
+ if (p === 'all') {
+ return exports.roles;
+ }
+ if (p === 'None') {
+ return 'None';
+ }
+ else {
+ return faction_player_map[p];
+ }
+}
function next(checkpoint = false) {
if (checkpoint) {
clear_undo();
@@ -306,7 +318,7 @@ function next(checkpoint = false) {
else if (node.t === 'l') {
game.state = node.s;
const current_active = game.active;
- const next_active = faction_player_map[node.p];
+ const next_active = get_next_active(node.p);
if (next_active !== current_active && game.undo.length > 0) {
insert_before_active_node(create_leaf_node('confirm_turn', get_active_faction()));
game.state = 'confirm_turn';
@@ -332,6 +344,7 @@ function game_view(state, current) {
game = state;
const faction = current === OBSERVER ? null : player_faction_map[current];
view = {
+ active: game.active,
engine: game.engine,
log: game.log,
prompt: null,
@@ -480,20 +493,24 @@ function draw_hand_cards(faction_id, count) {
if (game.medallions[faction_id].includes(data_1.INTELLIGENCE_MEDALLION_ID)) {
count++;
}
- const drawn_cards = count;
+ let drawn_cards = 0;
if (deck.length < count) {
count = count - deck.length;
+ drawn_cards += deck.length;
game.hands[faction_id] = game.hands[faction_id].concat(deck);
game.discard[faction_id] = [];
}
+ for (let i = 0; i < count; i++) {
+ const deck = list_deck(faction_id);
+ if (deck.length > 0) {
+ game.hands[faction_id].push(draw_card(deck));
+ drawn_cards++;
+ }
+ }
const log = drawn_cards === 1
? `${get_player(faction_id)} draws 1 card`
: `${get_player(faction_id)} draws ${drawn_cards} cards`;
logi(log);
- for (let i = 0; i < count; i++) {
- const deck = list_deck(faction_id);
- game.hands[faction_id].push(draw_card(deck));
- }
}
function start_year() {
game.year++;
@@ -717,10 +734,17 @@ states.add_to_front = {
gen_spend_hero_points();
const args = get_active_node_args();
const possible_fronts = get_fronts_to_add_to(args.t);
- view.prompt =
- possible_fronts.length === 1
- ? `Add strength to ${front_names[possible_fronts[0]]}`
- : 'Add strength to a Front';
+ const number_of_fronts = possible_fronts.length;
+ if (number_of_fronts === 0) {
+ view.prompt = 'No valid front to target. You must skip';
+ gen_action('skip');
+ }
+ else if (number_of_fronts === 1) {
+ view.prompt = `Add strength to ${front_names[possible_fronts[0]]}`;
+ }
+ else {
+ view.prompt = 'Add strength to a Front';
+ }
for (let f of possible_fronts) {
gen_action_front(f);
}
@@ -736,55 +760,43 @@ states.add_to_front = {
update_front(f, value, get_active_faction());
resolve_active_and_proceed();
},
+ skip() {
+ resolve_active_and_proceed();
+ },
};
states.attack_front = {
inactive: 'attack a Front',
prompt() {
gen_spend_hero_points();
const { t: target, n, src } = get_active_node_args();
- let fronts = [];
- if (target === data_1.ANY) {
- fronts = get_fronts_to_add_to(data_1.ANY, n);
- }
- else if (target === 'd' || target === 'v') {
- fronts = get_fronts_closest_to(target);
- }
- else if (game.fronts[target].status === data_1.DEFEAT) {
- fronts = get_fronts_closest_to('d');
+ const possible_fronts = get_fronts_to_add_to(target, n);
+ const number_of_fronts = possible_fronts.length;
+ if (number_of_fronts === 0) {
+ view.prompt = 'No valid front to target. You must skip';
+ gen_action('skip');
}
- else if (game.fronts[target].status === data_1.VICTORY) {
- fronts = get_fronts_to_add_to(data_1.ANY);
+ else if (number_of_fronts === 1) {
+ view.prompt = `Attack ${front_names[possible_fronts[0]]}`;
}
else {
- fronts.push(target);
+ view.prompt = 'Attack a Front';
}
- view.prompt =
- fronts.length === 1
- ? `Attack ${front_names[fronts[0]]}`
- : 'Attack a front';
- let prefix = '';
if (src) {
- prefix = `${get_source_name(src)}: `;
- }
- if (fronts.length === 1) {
- view.prompt = prefix
- ? `${prefix}attack ${front_names[fronts[0]]}`
- : `Attack ${front_names[fronts[0]]}`;
- }
- else {
- view.prompt = prefix ? `${prefix}attack a front` : `Attack a front`;
+ view.prompt = add_prompt_prefix(view.prompt, get_source_name(src));
}
- fronts.forEach((id) => gen_action('front', id));
+ possible_fronts.forEach((id) => gen_action('front', id));
},
spend_hp() {
resolve_spend_hp();
},
front(f) {
- const node = get_active_node();
- const value = node.a.v;
+ const value = get_active_node_args().v;
update_front(f, value);
resolve_active_and_proceed();
},
+ skip() {
+ resolve_active_and_proceed();
+ },
};
states.break_tie_final_bid = {
inactive: 'break tie for Final Bid',
@@ -840,7 +852,7 @@ states.change_active_player = {
},
prompt() {
view.prompt = '';
- }
+ },
};
states.choose_area_ap = {
inactive: 'choose area to use Action Points',
@@ -928,14 +940,15 @@ states.change_bonus = {
};
states.choose_card = {
inactive: 'choose a card',
- prompt() {
+ prompt(player) {
+ console.log('player', player);
gen_spend_hero_points();
const { src } = get_active_node_args();
view.prompt = 'Choose a card to play this turn';
if (src === 'momentum') {
view.prompt = 'Choose a card to play';
}
- const faction = get_active_faction();
+ const faction = player_faction_map[player];
const hand = game.hands[faction];
for (let c of hand) {
if (!game.selected_cards[faction].includes(c)) {
@@ -946,14 +959,13 @@ states.choose_card = {
spend_hp() {
resolve_spend_hp();
},
- card(c) {
- const faction = get_active_faction();
+ card(c, player) {
+ const faction = player_faction_map[player];
game.selected_cards[faction].push(c);
const { src } = get_active_node_args();
if (src === 'momentum') {
game.played_card = game.selected_cards[faction][0];
}
- resolve_active_and_proceed();
},
};
states.choose_final_bid = {
@@ -1074,12 +1086,12 @@ states.draw_card = {
draw_card() {
const { v } = get_active_node_args();
draw_hand_cards(get_active_faction(), v);
- resolve_active_and_proceed();
+ resolve_active_and_proceed(true);
},
draw_cards() {
const { v } = get_active_node_args();
draw_hand_cards(get_active_faction(), v);
- resolve_active_and_proceed();
+ resolve_active_and_proceed(true);
},
};
states.draw_glory = {
@@ -2627,6 +2639,9 @@ function get_fronts_closest_to(target) {
}
return accrued;
}, []);
+ if (values.length === 0) {
+ return [];
+ }
const targetValue = target === 'd' ? Math.min(...values) : Math.max(...values);
return Object.keys(game.fronts).filter((frontId) => game.fronts[frontId].value === targetValue);
}