summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrans Bongers <fransbongers@macbookpro.home>2025-03-22 14:19:48 +0100
committerFrans Bongers <fransbongers@macbookpro.home>2025-03-22 14:19:48 +0100
commit3f07e3e2d2c7b29170cffb5d982b669d7ac67b3f (patch)
treecfd58c620b266906c77755ca6d7aa959ead8b354
parent48dd3c43c2c6cb5e41382377cdd7c4b2214edadd (diff)
downloadland-and-freedom-3f07e3e2d2c7b29170cffb5d982b669d7ac67b3f.tar.gz
improved game flow playing card for action points
-rw-r--r--rules.js77
-rw-r--r--rules.ts92
-rw-r--r--types.d.ts37
3 files changed, 116 insertions, 90 deletions
diff --git a/rules.js b/rules.js
index 6a082d5..f0c5b69 100644
--- a/rules.js
+++ b/rules.js
@@ -459,6 +459,8 @@ function setup(seed, _scenario, options) {
glory_current_year: null,
fascist: 0,
card_played: 0,
+ can_use_ap: 0,
+ can_use_mb: 0,
};
log_header('Land and Freedom', 't');
if (options.hidden_bag)
@@ -842,8 +844,17 @@ states.choose_area_ap = {
inactive: 'choose area to use Action Points',
prompt() {
gen_spend_hero_points();
- view.prompt = 'Use Action Points.';
+ const use_morale_bonus = game.can_use_mb === 1 && game.bonuses[data_1.MORALE_BONUS] === data_1.ON;
+ if (use_morale_bonus) {
+ view.prompt = "Use Action Points and Morale Bonus.";
+ }
+ else {
+ view.prompt = 'Use Action Points.';
+ }
const strength = get_active_node_args().strength;
+ if (use_morale_bonus) {
+ gen_action('use_morale_bonus');
+ }
let can_use_ap = false;
for (const track of tracks) {
can_use_ap = gen_move_track_change(track.id, strength) || can_use_ap;
@@ -869,6 +880,8 @@ states.choose_area_ap = {
resolve_spend_hp();
},
bonus(b) {
+ log("Action Points:");
+ game.can_use_ap = 0;
update_bonus(b, data_1.ON);
const s = get_active_node_args().strength;
const other_bonus = b === data_1.TEAMWORK_BONUS ? data_1.MORALE_BONUS : data_1.TEAMWORK_BONUS;
@@ -878,33 +891,52 @@ states.choose_area_ap = {
resolve_active_and_proceed();
},
front(f) {
+ log("Action Points:");
+ game.can_use_ap = 0;
const s = get_active_node_args().strength;
update_front(f, s, get_active_faction());
resolve_active_and_proceed();
},
tr0(x) {
+ log("Action Points:");
+ game.can_use_ap = 0;
move_track_to(0, x);
resolve_active_and_proceed();
},
tr1(x) {
+ log("Action Points:");
+ game.can_use_ap = 0;
move_track_to(1, x);
resolve_active_and_proceed();
},
tr2(x) {
+ log("Action Points:");
+ game.can_use_ap = 0;
move_track_to(2, x);
resolve_active_and_proceed();
},
tr3(x) {
+ log("Action Points:");
+ game.can_use_ap = 0;
move_track_to(3, x);
resolve_active_and_proceed();
},
tr4(x) {
+ log("Action Points:");
+ game.can_use_ap = 0;
move_track_to(4, x);
resolve_active_and_proceed();
},
skip() {
+ game.can_use_ap = 0;
resolve_active_and_proceed();
},
+ use_morale_bonus() {
+ log(`Morale Bonus:`);
+ game.can_use_mb = 0;
+ insert_before_active_node(create_state_node('activate_icon', get_active_faction()));
+ next();
+ },
};
states.change_bonus = {
inactive: 'select Bonus',
@@ -1496,21 +1528,21 @@ states.player_turn = {
prompt() {
gen_spend_hero_points();
const faction_id = get_active_faction();
- let { use_ap, use_morale_bonus, src } = get_active_node_args();
- use_morale_bonus = use_morale_bonus && game.bonuses[data_1.MORALE_BONUS] === data_1.ON;
+ let { src } = get_active_node_args();
+ const use_morale_bonus = game.can_use_mb === 1 && game.bonuses[data_1.MORALE_BONUS] === data_1.ON;
const can_spend_hp = game.faction_turn === faction_id && game.hero_points[faction_id] > 0;
const can_play_card = !game.card_played;
const use_momentum = game.momentum === faction_id && src !== data_1.MOMENTUM;
if (use_momentum) {
gen_action('use_momentum');
- if (use_ap || use_morale_bonus || can_play_card) {
+ if (use_morale_bonus || can_play_card) {
view.actions['use_momentum'] = 0;
}
}
set_player_turn_prompt({
can_play_card,
can_spend_hp,
- use_ap,
+ use_ap: game.can_use_ap === 1,
use_momentum,
use_morale_bonus,
});
@@ -1518,13 +1550,10 @@ states.player_turn = {
gen_action('play_to_tableau');
gen_action('play_for_event');
}
- if (use_ap) {
- gen_action('use_ap');
- }
- if (use_morale_bonus && game.bonuses[data_1.MORALE_BONUS] === data_1.ON) {
+ if (use_morale_bonus) {
gen_action('use_morale_bonus');
}
- if (!(can_play_card || use_ap || use_morale_bonus || use_momentum)) {
+ if (!(can_play_card || use_morale_bonus || use_momentum)) {
gen_action('end_turn');
}
},
@@ -1537,6 +1566,8 @@ states.player_turn = {
if (game.faction_turn === faction_id) {
game.faction_turn = null;
game.played_card = null;
+ game.can_use_ap = 0;
+ game.can_use_mb = 0;
game.engine.push(create_function_node('end_of_player_turn', { f: faction_id }));
}
game.selected_cards[faction_id].pop();
@@ -1549,11 +1580,11 @@ states.player_turn = {
game.card_played = 1;
const faction = get_active_faction();
const { strength } = play_card_to_tableau(faction);
- update_active_node_args({
- use_morale_bonus: true,
- use_ap: true,
+ game.can_use_ap = 1;
+ game.can_use_mb = 1;
+ insert_before_active_node(create_state_node('choose_area_ap', faction, {
strength,
- });
+ }));
next();
},
play_for_event() {
@@ -1566,29 +1597,17 @@ states.player_turn = {
insert_before_active_node(node);
next();
},
- use_ap() {
- log("Action Points:");
- const faction = get_active_faction();
- const { strength } = get_active_node_args();
- update_active_node_args({
- use_ap: false,
- });
- insert_before_active_node(create_state_node('choose_area_ap', faction, {
- strength,
- }));
- next();
- },
use_momentum() {
const faction_id = get_active_faction();
game.selected_cards[faction_id].pop();
game.momentum = null;
+ game.can_use_ap = 0;
+ game.can_use_mb = 0;
resolve_active_and_proceed();
},
use_morale_bonus() {
log(`Morale Bonus:`);
- update_active_node_args({
- use_morale_bonus: false,
- });
+ game.can_use_mb = 0;
insert_before_active_node(create_state_node('activate_icon', get_active_faction()));
next();
},
diff --git a/rules.ts b/rules.ts
index cb370a7..63ab7f8 100644
--- a/rules.ts
+++ b/rules.ts
@@ -657,6 +657,8 @@ export function setup(seed: number, _scenario: string, options: Record<string,bo
glory_current_year: null,
fascist: 0,
card_played: 0,
+ can_use_ap: 0,
+ can_use_mb: 0,
};
log_header('Land and Freedom', 't')
@@ -1096,8 +1098,20 @@ states.choose_area_ap = {
inactive: 'choose area to use Action Points',
prompt() {
gen_spend_hero_points();
- view.prompt = 'Use Action Points.';
+ const use_morale_bonus = game.can_use_mb === 1 && game.bonuses[MORALE_BONUS] === ON;
+
+ if (use_morale_bonus) {
+ view.prompt = "Use Action Points and Morale Bonus."
+ } else {
+ view.prompt = 'Use Action Points.';
+ }
+
const strength: number = get_active_node_args().strength;
+
+ if (use_morale_bonus) {
+ gen_action('use_morale_bonus');
+ }
+
let can_use_ap = false;
for (const track of tracks) {
can_use_ap = gen_move_track_change(track.id, strength) || can_use_ap;
@@ -1123,6 +1137,8 @@ states.choose_area_ap = {
resolve_spend_hp();
},
bonus(b: number) {
+ log("Action Points:");
+ game.can_use_ap = 0;
// Turn on bonus
update_bonus(b, ON);
const s: number = get_active_node_args().strength;
@@ -1137,33 +1153,54 @@ states.choose_area_ap = {
resolve_active_and_proceed();
},
front(f: FrontId) {
+ log("Action Points:");
+ game.can_use_ap = 0;
const s: number = get_active_node_args().strength;
update_front(f, s, get_active_faction());
resolve_active_and_proceed();
},
tr0(x: number) {
+ log("Action Points:");
+ game.can_use_ap = 0;
move_track_to(0, x);
resolve_active_and_proceed();
},
tr1(x: number) {
+ log("Action Points:");
+ game.can_use_ap = 0;
move_track_to(1, x);
resolve_active_and_proceed();
},
tr2(x: number) {
+ log("Action Points:");
+ game.can_use_ap = 0;
move_track_to(2, x);
resolve_active_and_proceed();
},
tr3(x: number) {
+ log("Action Points:");
+ game.can_use_ap = 0;
move_track_to(3, x);
resolve_active_and_proceed();
},
tr4(x: number) {
+ log("Action Points:");
+ game.can_use_ap = 0;
move_track_to(4, x);
resolve_active_and_proceed();
},
skip() {
+ game.can_use_ap = 0;
resolve_active_and_proceed();
},
+ use_morale_bonus() {
+ log(`Morale Bonus:`)
+ game.can_use_mb = 0;
+ insert_before_active_node(
+ create_state_node('activate_icon', get_active_faction())
+ );
+ next();
+ },
};
states.change_bonus = {
@@ -1817,7 +1854,7 @@ function set_player_turn_prompt({
use_ap,
use_momentum,
use_morale_bonus,
-}: PlayerTurnArgs & { can_spend_hp: boolean; can_play_card: boolean }) {
+}: { can_spend_hp: boolean; can_play_card: boolean; use_ap: boolean; use_momentum: boolean; use_morale_bonus: boolean }) {
if (can_play_card)
view.prompt = "Play card for Action Points or for the Event."
else if (use_momentum)
@@ -1837,10 +1874,10 @@ states.player_turn = {
prompt() {
gen_spend_hero_points();
const faction_id = get_active_faction();
- let { use_ap, use_morale_bonus, src } =
+ let { src } =
get_active_node_args<PlayerTurnArgs>();
- use_morale_bonus = use_morale_bonus && game.bonuses[MORALE_BONUS] === ON;
+ const use_morale_bonus = game.can_use_mb === 1 && game.bonuses[MORALE_BONUS] === ON;
const can_spend_hp =
game.faction_turn === faction_id && game.hero_points[faction_id] > 0;
@@ -1849,7 +1886,7 @@ states.player_turn = {
const use_momentum = game.momentum === faction_id && src !== MOMENTUM;
if (use_momentum) {
gen_action('use_momentum');
- if (use_ap || use_morale_bonus || can_play_card) {
+ if (use_morale_bonus || can_play_card) {
view.actions['use_momentum'] = 0;
}
}
@@ -1857,7 +1894,7 @@ states.player_turn = {
set_player_turn_prompt({
can_play_card,
can_spend_hp,
- use_ap,
+ use_ap: game.can_use_ap === 1, // Will not happen in this state anymore
use_momentum,
use_morale_bonus,
});
@@ -1866,13 +1903,10 @@ states.player_turn = {
gen_action('play_to_tableau');
gen_action('play_for_event');
}
- if (use_ap) {
- gen_action('use_ap');
- }
- if (use_morale_bonus && game.bonuses[MORALE_BONUS] === ON) {
+ if (use_morale_bonus) {
gen_action('use_morale_bonus');
}
- if (!(can_play_card || use_ap || use_morale_bonus || use_momentum)) {
+ if (!(can_play_card || use_morale_bonus || use_momentum)) {
gen_action('end_turn');
}
},
@@ -1885,6 +1919,8 @@ states.player_turn = {
if (game.faction_turn === faction_id) {
game.faction_turn = null;
game.played_card = null;
+ game.can_use_ap = 0;
+ game.can_use_mb = 0;
game.engine.push(create_function_node('end_of_player_turn', { f: faction_id }));
}
game.selected_cards[faction_id].pop();
@@ -1897,11 +1933,13 @@ states.player_turn = {
game.card_played = 1;
const faction = get_active_faction();
const { strength } = play_card_to_tableau(faction);
- update_active_node_args<PlayerTurnArgs>({
- use_morale_bonus: true,
- use_ap: true,
- strength,
- });
+ game.can_use_ap = 1;
+ game.can_use_mb = 1;
+ insert_before_active_node(
+ create_state_node('choose_area_ap', faction, {
+ strength,
+ })
+ );
next();
},
play_for_event() {
@@ -1916,33 +1954,17 @@ states.player_turn = {
next();
},
- use_ap() {
- log("Action Points:");
- const faction = get_active_faction();
- const { strength } = get_active_node_args();
- update_active_node_args({
- use_ap: false,
- });
- insert_before_active_node(
- create_state_node('choose_area_ap', faction, {
- strength,
- })
- );
- next();
- },
use_momentum() {
const faction_id = get_active_faction();
game.selected_cards[faction_id].pop();
game.momentum = null;
+ game.can_use_ap = 0;
+ game.can_use_mb = 0;
resolve_active_and_proceed();
},
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({
- use_morale_bonus: false,
- });
+ game.can_use_mb = 0;
insert_before_active_node(
create_state_node('activate_icon', get_active_faction())
);
diff --git a/types.d.ts b/types.d.ts
index 3459f5a..213b25d 100644
--- a/types.d.ts
+++ b/types.d.ts
@@ -80,6 +80,17 @@ export interface Game {
fascist: 0 | 1 | 2;
card_played: 0 | 1;
hidden_bag?: 0 | 1;
+ /**
+ * Set to 1 if player has played card to their tableau and still
+ * needs to use action points
+ */
+ can_use_ap: 0 | 1;
+ /**
+ * Set to 1 if player has played card to their tableau and still
+ * needs to use morale bonus. Note bonus still needs to be on, this
+ * just determines if player has used it or not
+ */
+ can_use_mb: 0 | 1;
}
export interface View {
@@ -239,32 +250,6 @@ export interface PlayCardArgs extends EngineNodeArgsBase {
}
export interface PlayerTurnArgs extends EngineNodeArgsBase {
- /**
- * When set to true, player can use current card
- * for action points (using for ap sets it to false)
- */
- use_ap?: boolean;
- /**
- * When set to true, player can use current card for
- * morale bonus if that is active (using morale bonus sets it to dalse)
- */
- use_morale_bonus?: boolean;
- /**
- * Set when starting to resolve event effect from card. Will be set to false
- * after all effects have been resolved. Used to determine if momentum medallion
- * can be used.
- */
- resolving_event?: boolean;
- /**
- * Strength of the current card
- */
- strength?: number;
- /**
- * Set to true if player got momentum medallion,
- * but was not able to resolve directly as they were still
- * resolving their current card
- */
- use_momentum?: boolean;
}
// #endregion