diff options
author | Frans Bongers <fransbongers@franss-mbp.home> | 2024-12-01 20:07:32 +0100 |
---|---|---|
committer | Frans Bongers <fransbongers@franss-mbp.home> | 2024-12-01 20:07:32 +0100 |
commit | e32cc3efe1c1ef5378cef422555e8c8289449938 (patch) | |
tree | 8635f5131bd3b261b1b690df9d9f72626cfdf440 /rules.ts | |
parent | 74e1497d50a6ff81c74c593f2d0f7018d2995fd8 (diff) | |
download | land-and-freedom-e32cc3efe1c1ef5378cef422555e8c8289449938.tar.gz |
add card effects
Diffstat (limited to 'rules.ts')
-rw-r--r-- | rules.ts | 223 |
1 files changed, 162 insertions, 61 deletions
@@ -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; |