summaryrefslogtreecommitdiff
path: root/rules.ts
diff options
context:
space:
mode:
authorFrans Bongers <fransbongers@franss-mbp.home>2024-12-01 20:07:32 +0100
committerFrans Bongers <fransbongers@franss-mbp.home>2024-12-01 20:07:32 +0100
commite32cc3efe1c1ef5378cef422555e8c8289449938 (patch)
tree8635f5131bd3b261b1b690df9d9f72626cfdf440 /rules.ts
parent74e1497d50a6ff81c74c593f2d0f7018d2995fd8 (diff)
downloadland-and-freedom-e32cc3efe1c1ef5378cef422555e8c8289449938.tar.gz
add card effects
Diffstat (limited to 'rules.ts')
-rw-r--r--rules.ts223
1 files changed, 162 insertions, 61 deletions
diff --git a/rules.ts b/rules.ts
index cbe7f5a..0b4901f 100644
--- a/rules.ts
+++ b/rules.ts
@@ -2,12 +2,15 @@
import {
CardId,
+ Effect,
EngineNode,
+ EventCard,
FactionId,
FunctionNode,
Game,
LeafNode,
Player,
+ PlayerCard,
States,
View,
} from './types';
@@ -22,15 +25,12 @@ import data, {
// TEAMWORK_BONUS,
// OFF,
ON,
- EventCard,
- CardEffect,
LIBERTY,
COLLECTIVIZATION,
GOVERNMENT,
SOVIET_SUPPORT,
FOREIGN_AID,
PLAYER_WITH_MOST_HERO_POINTS,
- PlayerCard,
// StaticData,
// PLAYER_WITH_MOST_HERO_POINTS,
} from './data';
@@ -75,25 +75,10 @@ const front_names: Record<string, string> = {
v: 'the Front closest to Victory',
};
-const tracks = [
- LIBERTY,
- COLLECTIVIZATION,
- GOVERNMENT,
- SOVIET_SUPPORT,
- FOREIGN_AID,
-];
-
-const track_names: Record<number, string> = {
- [LIBERTY]: 'Liberty',
- [COLLECTIVIZATION]: 'Collectivization',
- [GOVERNMENT]: 'Government',
- [SOVIET_SUPPORT]: 'Soviet Support',
- [FOREIGN_AID]: 'Foreign Aid',
-};
-
const {
cards,
- // fronts
+ // fronts,
+ tracks,
} = data;
const faction_cards = {
@@ -453,6 +438,7 @@ export function setup(seed: number, _scenario: string, _options: unknown) {
[MODERATES_ID]: [],
},
tracks: [5, 5, 6, 3, 3],
+ triggered_track_effects: [[], [], [], [], []],
log: [],
undo: [],
turn: 1,
@@ -492,12 +478,9 @@ function start_turn() {
const card = cards[cardId] as EventCard;
log_h3('Fascist Event: ' + card.title);
- game.engine = card.effects.map((_effect, index) => ({
- t: leaf_node,
- s: 'resolve_event',
- p: game.initiative,
- a: index,
- }));
+ game.engine = card.effects.map((effect) =>
+ resolve_effect(effect, game.initiative)
+ );
game.engine.push({
t: 'f',
f: 'setup_choose_card',
@@ -534,12 +517,34 @@ states.add_glory = {
},
};
+states.attack_front = {
+ inactive: 'attack a Front',
+ prompt() {
+ const node = get_active_node();
+ const front = node.a.f;
+ view.prompt = 'Attack ' + front_names[front];
+ if (front === 'd' || front === 'v') {
+ const fronts = get_fronts_closest_to(front);
+ fronts.forEach((id) => gen_action('front', id));
+ } else {
+ gen_action('front', front);
+ }
+ },
+ front(f: string) {
+ const node = get_active_node();
+ const value = node.a.v;
+ game.fronts[f] += value;
+ log_h3(`${Math.abs(value)} attacks added to ${front_names[f]}`);
+ resolve_active_and_proceed();
+ },
+};
+
states.choose_area_ap = {
inactive: 'choose area to use Action Points',
prompt() {
view.prompt = 'Choose area of the board to affect';
- for (let track_id of tracks) {
- gen_action_standee(track_id);
+ for (let track of tracks) {
+ gen_action_standee(track.id);
}
},
standee(track_id: number) {
@@ -561,7 +566,7 @@ states.move_track_up_or_down = {
inactive: 'move a track',
prompt() {
const node = get_active_node();
- view.prompt = `Move ${get_track_name(node.a.track_id)} up or down`
+ view.prompt = `Move ${get_track_name(node.a.track_id)} up or down`;
gen_action('up');
gen_action('down');
},
@@ -574,8 +579,8 @@ states.move_track_up_or_down = {
const node = get_active_node();
move_track(node.a.track_id, node.a.strength);
resolve_active_and_proceed();
- }
-}
+ },
+};
states.choose_card = {
inactive: 'choose a card',
@@ -594,6 +599,31 @@ states.choose_card = {
},
};
+states.lose_hero_points = {
+ inactive: 'choose a Player',
+ prompt() {
+ view.prompt = 'Lose Hero Points';
+ },
+};
+
+states.move_track = {
+ inactive: 'move a Track',
+ prompt() {
+ const node = get_active_node();
+ const track = node.a.t;
+ const value = node.a.v;
+ view.prompt = `Move ${tracks[track].name} ${value > 0 ? 'up' : 'down'}`;
+ // return 'Decrease ' + tracks[effect.target].name;
+ gen_action_standee(track)
+ },
+ standee(s: number) {
+ const node = get_active_node();
+ const value = node.a.v;
+ move_track(s, value)
+ resolve_active_and_proceed();
+ },
+};
+
states.player_turn = {
inactive: 'play their turn',
prompt() {
@@ -682,18 +712,10 @@ states.resolve_event = {
prompt() {
const card = get_current_event();
const node = get_active_node(game.engine) as LeafNode;
- const effect: CardEffect = card.effects[node.a];
+ const effect: Effect = card.effects[node.a];
view.prompt = get_event_prompt(effect);
- if (
- effect.type === 'attack' &&
- (effect.target === 'd' || effect.target === 'v')
- ) {
- const fronts = get_fronts_closest_to(effect.target);
- fronts.forEach((id) => gen_action('front', id));
- } else if (effect.type === 'attack') {
- gen_action('front', effect.target);
- } else if (effect.type === 'track') {
+if (effect.type === 'track') {
gen_action('standee', effect.target);
} else if (
effect.type === 'hero_points' &&
@@ -706,20 +728,7 @@ states.resolve_event = {
}
// for (let p = 0; p < 5; ++p) gen_action('standee', p);
},
- front(f: string) {
- const card = get_current_event();
- const value = card.effects[get_active_node_args()].value;
- game.fronts[f] -= value;
- log_h3(`${value} attacks added to ${front_names[f]}`);
- resolve_active_and_proceed();
- },
- standee(s: string) {
- const effect = get_current_event().effects[get_active_node_args()];
- const value = effect.value;
- game.tracks[s] += value;
- log_h3(`${track_names[effect.target]} decreased by ${Math.abs(value)}`);
- resolve_active_and_proceed();
- },
+
Anarchist() {
lose_hero_point(ANARCHISTS_ID, 1);
resolve_active_and_proceed();
@@ -803,8 +812,100 @@ function resolve_fascist_test() {
next();
}
-function move_track(track: number, change: number) {
-
+function move_track(track_id: number, change: number) {
+ // Check if track can be moved
+ // Updata values
+ // Check all triggers
+ // Add states for triggers
+ const current_value = game.tracks[track_id];
+ let new_value = current_value + change;
+ new_value = Math.max(new_value, track_id === GOVERNMENT ? 1 : 0);
+ new_value = Math.min(new_value, 10);
+ game.tracks[track_id] = new_value;
+ log(`${game.active} moves ${get_track_name(track_id)} to ${new_value}`);
+ const triggered_spaces =
+ change > 0
+ ? make_list(current_value + 1, new_value).reverse()
+ : make_list(new_value, current_value - 1);
+
+ triggered_spaces.forEach((space_id) => {
+ const trigger = tracks[track_id].triggers[space_id];
+ if (
+ trigger !== null &&
+ !game.triggered_track_effects[track_id].includes(space_id)
+ ) {
+ if (space_id !== 0) {
+ game.triggered_track_effects[track_id].push(space_id);
+ }
+ const node = resolve_effect(trigger);
+ if (node !== null) {
+ insert_after_active_node(node);
+ }
+ }
+ });
+}
+
+function resolve_effect(
+ effect: Effect,
+ faction: FactionId = get_active_faction()
+): EngineNode | null {
+ if (effect.type === 'attack') {
+ return {
+ t: leaf_node,
+ p: faction,
+ s: 'attack_front',
+ a: {
+ f: effect.target,
+ v: effect.value,
+ },
+ };
+ }
+ if (effect.type === 'track') {
+ return {
+ t: leaf_node,
+ p: faction,
+ s: 'move_track',
+ a: {
+ t: effect.target,
+ v: effect.value,
+ },
+ };
+ }
+ if (
+ effect.type === 'hero_points' &&
+ effect.target === PLAYER_WITH_MOST_HERO_POINTS
+ ) {
+ return {
+ t: leaf_node,
+ p: faction,
+ s: 'lose_hero_points',
+ a: {
+ p: effect.target,
+ v: effect.value,
+ },
+ };
+ }
+ return null;
+
+ // if (
+ // effect.type === 'attack' &&
+ // (effect.target === 'd' || effect.target === 'v')
+ // ) {
+ // const fronts = get_fronts_closest_to(effect.target);
+ // fronts.forEach((id) => gen_action('front', id));
+ // } else if (effect.type === 'attack') {
+ // gen_action('front', effect.target);
+ // } else if (effect.type === 'track') {
+ // gen_action('standee', effect.target);
+ // } else if (
+ // effect.type === 'hero_points' &&
+ // effect.target === PLAYER_WITH_MOST_HERO_POINTS
+ // ) {
+ // const factions = get_factions_with_most_hero_poins();
+ // for (let faction_id of factions) {
+ // gen_action(get_player(faction_id));
+ // }
+ // }
}
// #endregion
@@ -874,7 +975,7 @@ function get_current_event(): EventCard {
// }
// }
-function get_event_prompt(effect: CardEffect) {
+function get_event_prompt(effect: Effect) {
let prompt = '';
switch (effect.type) {
case 'attack':
@@ -884,7 +985,7 @@ function get_event_prompt(effect: CardEffect) {
case 'hero_points':
return 'Select player with most Hero points';
case 'track':
- return 'Decrease ' + track_names[effect.target];
+ return 'Decrease ' + tracks[effect.target].name;
}
return prompt;
}
@@ -1067,10 +1168,10 @@ function get_factions_with_most_hero_poins() {
}
function get_track_name(track_id: number): string {
- return track_names[track_id];
+ return tracks[track_id].name;
}
-function make_list(first: number, last: number) {
+function make_list(first: number, last: number): number[] {
let list = [];
for (let i = first; i <= last; i++) list.push(i);
return list;