diff options
-rw-r--r-- | play.js | 27 | ||||
-rw-r--r-- | rules.js | 1073 |
2 files changed, 1044 insertions, 56 deletions
@@ -313,7 +313,7 @@ function layout_disc(s, disc) { disc.classList.remove("hide") disc.style.left = (space_layout_disc[s].x - 50 - 12) + "px" disc.style.top = (space_layout_disc[s].y - 20 - 8) + "px" - disc.style.zIndex = 51; + disc.style.zIndex = 51 } else disc.classList.add("hide") @@ -411,11 +411,11 @@ function on_update() { for (let i = 0; i < 36; ++i) { if (view.pieces[i] >= 0) { layout[view.pieces[i]].push(ui.cubes[i]) - ui.cubes[i].classList.remove("hide"); + ui.cubes[i].classList.remove("hide") ui.cubes[i].classList.toggle("action", is_piece_action(i)) } else { - ui.cubes[i].classList.add("hide"); + ui.cubes[i].classList.add("hide") } } for (let i = 0; i < space_count; ++i) { @@ -432,28 +432,31 @@ function on_update() { ui.cards[i].classList.toggle("selected", i === view.selected_card) } - action_button("commune", "Commune"); - action_button("versailles", "Versailles"); + action_button("commune", "Commune") + action_button("versailles", "Versailles") - action_button("spend", "Spend"); - action_button("draw", "Draw"); + action_button("spend", "Spend") + action_button("draw", "Draw") action_button("momentum", "Momentum") action_button("event", "Event") action_button("political", "Political") action_button("military", "Military") + action_button("public_opinion", "Public Opinion") + action_button("paris", "Paris") action_button("ops", "Operations") action_button("place", "Place") action_button("remove", "Remove") action_button("replace", "Replace") - action_button("end_remove", "End Remove"); - action_button("end_turn", "End Turn"); + action_button("end_remove", "End Remove") + action_button("end_ops", "End Operations") + action_button("end_event", "End Event") - action_button("skip", "Skip"); - action_button("done", "Done"); - action_button("undo", "Undo"); + action_button("skip", "Skip") + action_button("done", "Done") + action_button("undo", "Undo") } build_user_interface() @@ -159,6 +159,8 @@ const first_space = NATIONAL_ASSEMBLY const last_space = PERE_LACHAISE const space_count = last_space + 1 +const ANY = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ] + const POLITICAL = [ NATIONAL_ASSEMBLY, ROYALISTS, @@ -177,28 +179,6 @@ const MILITARY = [ PERE_LACHAISE, ] -function is_political_space(s) { - return ( - s === NATIONAL_ASSEMBLY || - s === ROYALISTS || - s === REPUBLICANS || - s === PRESS || - s === CATHOLIC_CHURCH || - s === SOCIAL_MOVEMENTS - ) -} - -function is_military_space(s) { - return ( - s === MONT_VALERIEN || - s === FORT_D_ISSY || - s === CHATEAU_DE_VINCENNES || - s === BUTTE_MONTMARTRE || - s === BUTTE_AUX_CAILLES || - s === PERE_LACHAISE - ) -} - const INSTITUTIONAL = [ NATIONAL_ASSEMBLY, ROYALISTS, REPUBLICANS ] const PUBLIC_OPINION = [ PRESS, CATHOLIC_CHURCH, SOCIAL_MOVEMENTS ] @@ -239,6 +219,28 @@ const ADJACENT_FROM = [ [ MONT_VALERIEN, FORT_D_ISSY ], ] +function is_political_space(s) { + return ( + s === NATIONAL_ASSEMBLY || + s === ROYALISTS || + s === REPUBLICANS || + s === PRESS || + s === CATHOLIC_CHURCH || + s === SOCIAL_MOVEMENTS + ) +} + +function is_military_space(s) { + return ( + s === MONT_VALERIEN || + s === FORT_D_ISSY || + s === CHATEAU_DE_VINCENNES || + s === BUTTE_MONTMARTRE || + s === BUTTE_AUX_CAILLES || + s === PERE_LACHAISE + ) +} + // === GAME STATE === function discard_card(c) { @@ -296,9 +298,37 @@ function can_advance_momentum() { } function can_play_event(c) { - if (game.active === COMMUNE) - return is_commune_card(c) || is_neutral_card(c) - return is_versailles_card(c) || is_neutral_card(c) + if (game.active === COMMUNE && is_versailles_card(c)) + return false + if (game.active === VERSAILLES && is_commune_card(c)) + return false + + // Cards 38 through 41 can only be played if you have the initiative + if (c >= 38 && c <= 41) + if (game.active !== game.initiative) + return false + + // Otto von Bismarck - must remove blue cube from National Assembly + if (c === 12) + if (!has_versailles_cube(NATIONAL_ASSEMBLY)) + return false + + // Le Reveil - cannot be played if Socialist Newspaper Ban + if (c === 21) + if (game.snb) + return false + + // Victor Hugo - must decrease both player momentums + if (c === 38) + if (game.red_momentum < 1 || game.blue_momentum < 1) + return false + + // Freemason Parade - must remove red & blue cubes from one Military space + if (c === 41) + if (!can_play_freemason_parade()) + return false + + return true } var c_count = new Array(space_count).fill(0) @@ -442,6 +472,12 @@ function count_friendly_cubes(s) { return count_versailles_cubes(s) } +function count_friendly_discs(s) { + if (game.active === COMMUNE) + return count_commune_discs(s) + return count_versailles_discs(s) +} + function count_enemy_pieces(s) { if (game.active === COMMUNE) return count_versailles_pieces(s) @@ -500,6 +536,18 @@ function find_friendly_disc(s) { return find_versailles_disc(s) } +function find_available_disc() { + return find_friendly_disc(-1) +} + +function has_commune_cube(s) { + return find_commune_cube(s) >= 0 +} + +function has_versailles_cube(s) { + return find_versailles_cube(s) >= 0 +} + function has_enemy_cube(s) { return find_enemy_cube(s) >= 0 } @@ -524,6 +572,23 @@ function is_disc(p) { return p >= 36 } +function can_place_cube(s) { + console.log("can_place_cube", s, find_available_cube(), count_friendly_cubes(s)) + return find_available_cube() >= 0 && count_friendly_cubes(s) < 4 +} + +function can_place_disc(s) { + return find_available_disc() >= 0 && count_friendly_discs(s) < 1 +} + +function can_replace_cube(s) { + return has_enemy_cube(s) && can_place_cube(s) +} + +function can_remove_cube(s) { + return has_enemy_cube(s) +} + function remove_piece(p) { if (is_commune_cube(p)) { if (game.red_momentum >= 1 && count_commune_cubes(RED_CUBE_POOL[0]) < 2) @@ -549,6 +614,14 @@ function place_piece(p, s) { game.pieces[p] = s } +function place_cube(s) { + game.pieces[find_available_cube()] = s +} + +function place_disc(s) { + game.pieces[find_available_disc()] = s +} + function find_available_cube() { let p = -1 if (game.active === COMMUNE) { @@ -635,6 +708,10 @@ function versailles_political_vp() { return -game.political_vp } +function where_present(list) { + return list.filter(s => is_present(s)) +} + // === CHOOSE OBJECTIVE CARD === states.choose_objective_card = { @@ -798,21 +875,25 @@ states.play_card = { gen_action_card(final) }, event() { + push_undo() log("Event.") discard_card(game.what) goto_play_event(game.what) }, political() { + push_undo() log("Ops.") discard_card(game.what) goto_operations(card_ops[game.what], POLITICAL) }, military() { + push_undo() log("Ops.") discard_card(game.what) goto_operations(card_ops[game.what], MILITARY) }, momentum() { + push_undo() log(`Momentum.`) if (game.scenario === "Censorship") recycle_card(game.what) @@ -830,6 +911,7 @@ states.play_card = { this.momentum() }, card(c) { + push_undo() log(`Discarded for #${c}.`) if (c === game.discard) { discard_card(game.what) @@ -851,10 +933,12 @@ states.play_final = { view.actions.military = 1 }, political() { + push_undo() discard_final() goto_operations(4, POLITICAL) }, military() { + push_undo() discard_final() goto_operations(4, MILITARY) }, @@ -873,6 +957,7 @@ function advance_revolutionary_momentum(x) { game.red_momentum += x for (let i = game.red_momentum; i < 3; ++i) for_each_commune_cube(RED_CUBE_POOL[i], p => game.pieces[p] = -1) + game.momentum_active = game.active game.active = VERSAILLES if (x > 0 && game.red_momentum >= 2) game.state = "revolutionary_momentum_trigger" @@ -884,6 +969,7 @@ function advance_prussian_collaboration(x) { game.blue_momentum += x for (let i = 0; i < game.blue_momentum; ++i) for_each_versailles_cube(PRUSSIAN_COLLABORATION[i], p => game.pieces[p] = BLUE_CUBE_POOL) + game.momentum_active = game.active game.active = COMMUNE if (x > 0 && game.blue_momentum >= 2) game.state = "prussian_collaboration_trigger" @@ -895,11 +981,12 @@ states.revolutionary_momentum_trigger = { prompt() { view.prompt = "Revolutionary Momentum: Place a cube in an Institutional space." for (let s of INSTITUTIONAL) - gen_action_space(s) + if (can_place_cube(s)) + gen_action_space(s) view.actions.skip = 1 }, space(s) { - place_piece(find_available_cube(), s) + place_cube(s) end_momentum_trigger() }, skip() { @@ -911,11 +998,12 @@ states.prussian_collaboration_trigger = { prompt() { view.prompt = "Prussian Collaboration: Place a cube in a Public Opinion space." for (let s of PUBLIC_OPINION) - gen_action_space(s) + if (can_place_cube(s)) + gen_action_space(s) view.actions.skip = 1 }, space(s) { - place_piece(find_available_cube(), s) + place_cube(s) end_momentum_trigger() }, skip() { @@ -924,8 +1012,12 @@ states.prussian_collaboration_trigger = { } function end_momentum_trigger() { - game.active = enemy_player() - resume_strategy_phase() + game.active = game.momentum_active + delete game.momentum_active + if (game.vm) + vm_next() + else + resume_strategy_phase() } // === OPERATIONS === @@ -1121,11 +1213,11 @@ function can_operations_place() { function can_operations_place_space(s) { if (is_present(s) || is_adjacent_to_control(s)) { - if (count_friendly_cubes(s) >= 4) - return false - let d = has_enemy_disc(s) - if (!d || game.count >= 2) - return true + if (can_place_cube(s)) { + let d = has_enemy_disc(s) + if (!d || game.count >= 2) + return true + } } return false } @@ -1136,7 +1228,7 @@ states.operations_place = { for (let s of game.spaces) if (can_operations_place_space(s)) gen_action_space(s) - view.actions.end_turn = 1 + view.actions.end_ops = 1 }, space(s) { push_undo() @@ -1144,10 +1236,10 @@ states.operations_place = { game.count -= 2 else game.count -= 1 - place_piece(find_available_cube(), s) + place_cube(s) resume_operations_place() }, - end_turn() { + end_ops() { end_operations() }, } @@ -1166,9 +1258,9 @@ function goto_operations_done() { states.operations_done = { prompt() { view.prompt = "Operations: All done." - view.actions.end_turn = 1 + view.actions.end_ops = 1 }, - end_turn() { + end_ops() { end_operations() }, } @@ -1200,12 +1292,510 @@ function goto_pivotal_space_bonus_actions() { // === EVENTS === function goto_play_event(c) { - switch (c) { - // TODO - } + update_presence_and_control() + goto_vm(c) +} + +function end_event() { + game.vm = null resume_strategy_phase() } +function goto_vm(proc) { + game.state = "vm" + game.vm = { + prompt: 0, + fp: proc, + ip: 0, + } + vm_exec() +} + +function event_prompt(str) { + if (typeof str === "undefined") + str = CODE[game.vm.fp][game.vm.prompt][1] + if (typeof str === "function") + str = str() + view.prompt = card_names[game.vm.fp] + ": " + str +} + +function vm_inst(a) { + return CODE[game.vm.fp][game.vm.ip][a] +} + +function vm_operand(a) { + let x = CODE[game.vm.fp][game.vm.ip][a] + if (a > 0 && typeof x === "function") + return x() + return x +} + +function vm_exec() { + console.log("VM", game.vm.fp, game.vm.ip, vm_inst(0).name) + vm_inst(0)() +} + +function vm_next() { + game.vm.ip ++ + vm_exec() +} + +function vm_asm() { + vm_operand(1) + vm_next() +} + +function vm_goto() { + game.state = vm_operand(1) +} + +function vm_return() { + game.state = "vm_return" +} + +states.vm_return = { + prompt() { + event_prompt("All done.") + view.actions.end_event = 1 + }, + end_event, +} + +function vm_if() { + if (!vm_operand(1)) { + let balance = 1 + while (balance > 0) { + ++game.vm.ip + switch (vm_operand(0)) { + case vm_if: + ++balance + break + case vm_endif: + --balance + break + case vm_else: + if (balance === 1) + --balance + break + } + if (game.vm.ip < 0 || game.vm.ip > CODE[game.vm.fp].length) + throw "ERROR" + } + } + vm_next() +} + +function vm_else() { + vm_goto(vm_endif, vm_if, 1, 1) +} + +function vm_endif() { + vm_next() +} + +function vm_endswitch() { + vm_next() +} + +function vm_switch() { + game.vm.choice = null + game.state = "vm_switch" +} + +function vm_case() { + if (game.vm.choice === vm_operand(1)) { + vm_next() + } else { + do + ++game.vm.ip + while (vm_inst(0) !== vm_case && vm_inst(0) !== vm_endswitch) + vm_exec() + } +} + +function vm_player() { + // TODO: pause for undo? + game.active = vm_operand(1) + vm_next() +} + +function vm_ops() { + goto_operations(vm_operand(1), vm_operand_spaces(2)) +} + +function vm_increase_revolutionary_momentum() { + if (game.red_momentum < 3) + game.state = "vm_increase_revolutionary_momentum" + else + vm_next() +} + +function vm_increase_prussian_collaboration() { + if (game.blue_momentum < 3) + game.state = "vm_increase_prussian_collaboration" + else + vm_next() +} + +function vm_decrease_revolutionary_momentum() { + if (game.red_momentum > 1) + game.state = "vm_decrease_revolutionary_momentum" + else + vm_next() +} + +function vm_decrease_prussian_collaboration() { + if (game.blue_momentum > 1) + game.state = "vm_decrease_prussian_collaboration" + else + vm_next() +} + +function vm_operand_spaces(x) { + let s = vm_operand(x) + if (typeof s === "number") + return [ s ] + return s +} + +function vm_remove_up_to() { + game.vm.upto = 1 + game.vm.count = vm_operand(1) + game.vm.spaces = vm_operand_spaces(2) + goto_vm_remove() +} + +function vm_remove() { + game.vm.count = vm_operand(1) + game.vm.spaces = vm_operand_spaces(2) + goto_vm_remove() +} + +function vm_remove_own() { + game.vm.spaces = vm_operand_spaces(1) + game.state = "vm_remove_own" +} + +function vm_replace_up_to() { + game.vm.upto = 1 + game.vm.count = vm_operand(1) + game.vm.spaces = vm_operand_spaces(2) + game.state = "vm_replace" + goto_vm_replace() +} + +function vm_replace_different() { + game.vm.count = vm_operand(1) + game.vm.spaces = vm_operand_spaces(2).slice() // make a copy for safe mutation + game.state = "vm_replace_different" +} + +function vm_replace() { + game.vm.count = vm_operand(1) + game.vm.spaces = vm_operand_spaces(2) + goto_vm_replace() +} + +function vm_place_removed_up_to() { + game.vm.removed = 1 + game.vm.upto = 1 + game.vm.count = vm_operand(1) + game.vm.spaces = vm_operand_spaces(2) + goto_vm_place() +} + +function vm_place_up_to() { + game.vm.upto = 1 + game.vm.count = vm_operand(1) + game.vm.spaces = vm_operand_spaces(2) + goto_vm_place() +} + +function vm_place() { + game.vm.count = vm_operand(1) + game.vm.spaces = vm_operand_spaces(2) + goto_vm_place() +} + +function vm_may_place_disc() { + game.vm.upto = 1 + game.vm.count = 1 + game.vm.spaces = vm_operand_spaces(1) + game.state = "vm_place_disc" +} + +function vm_place_disc() { + game.vm.count = 1 + game.vm.spaces = vm_operand_spaces(1) + game.state = "vm_place_disc" +} + +function vm_move_up_to() { + game.vm.count = 1 + game.vm.a = vm_operand_spaces(1) + game.vm.b = vm_operand_spaces(2) + game.state = "vm_move" +} + +function vm_move_between_up_to() { + game.vm.count = 1 + game.vm.a = vm_operand_spaces(1) + game.vm.b = vm_operand_spaces(2) + game.state = "vm_move_between" +} + +// === EVENT STATES === + +states.vm_switch = { + prompt() { + event_prompt() + for (let choice of vm_operand(1)) { + if (choice === "mont_valerien") + gen_action_space(MONT_VALERIEN) + else if (choice === "butte_montmartre") + gen_action_space(BUTTE_MONTMARTRE) + else + view.actions[choice] = 1 + } + }, + place() { + push_undo() + game.vm.choice = "place" + vm_next() + }, + replace() { + push_undo() + game.vm.choice = "replace" + vm_next() + }, + remove() { + push_undo() + game.vm.choice = "remove" + vm_next() + }, + momentum() { + push_undo() + game.vm.choice = "momentum" + vm_next() + }, + ops() { + push_undo() + game.vm.choice = "ops" + vm_next() + }, + public_opinion() { + push_undo() + game.vm.choice = "public_opinion" + vm_next() + }, + paris() { + push_undo() + game.vm.choice = "paris" + vm_next() + }, + space(s) { + push_undo() + if (s === MONT_VALERIEN) + game.vm.choice = "mont_valerien" + if (s === BUTTE_MONTMARTRE) + game.vm.choice = "butte_montmartre" + vm_next() + }, +} + +states.vm_increase_revolutionary_momentum = { + prompt() { + event_prompt("Increase Revolutionary Momentum.") + view.actions.red_momentum = 1 + }, + red_momentum() { + push_undo() + advance_revolutionary_momentum(1) + }, +} + +states.vm_increase_prussian_collaboration = { + prompt() { + event_prompt("Increase Prussian Collaboration.") + view.actions.blue_momentum = 1 + }, + blue_momentum() { + push_undo() + advance_prussian_collaboration(1) + }, +} + +states.vm_decrease_revolutionary_momentum = { + prompt() { + event_prompt("Decrease Revolutionary Momentum.") + view.actions.red_momentum = 1 + }, + red_momentum() { + push_undo() + advance_revolutionary_momentum(-1) + }, +} + +states.vm_decrease_prussian_collaboration = { + prompt() { + event_prompt("Decrease Prussian Collaboration.") + view.actions.blue_momentum = 1 + }, + blue_momentum() { + push_undo() + advance_prussian_collaboration(-1) + }, +} + +function can_vm_place() { + for (let s of game.vm.spaces) + if (can_place_cube(s)) + return true + return false +} + +function goto_vm_place() { + if (can_vm_place()) + game.state = "vm_place" + else + vm_next() +} + +states.vm_place = { + prompt() { + event_prompt("Place " + game.vm.count + " cube.") + if (game.vm.upto) + view.actions.skip = 1 + for (let s of game.vm.spaces) + if (can_place_cube(s)) + gen_action_space(s) + }, + space(s) { + push_undo() + place_cube(s) + if (--game.vm.count === 0 || !can_vm_place()) + vm_next() + }, + skip() { + push_undo() + vm_next() + }, +} + +function can_vm_place_disc() { + for (let s of game.vm.spaces) + if (can_place_disc(s)) + return true + return false +} + +function goto_vm_place_disc() { + if (can_vm_place_disc()) + game.state = "vm_place_disc" + else + vm_next() +} + +states.vm_place_disc = { + prompt() { + event_prompt("Place a disc.") + if (game.vm.upto) + view.actions.skip = 1 + for (let s of game.vm.spaces) + if (can_place_disc(s)) + gen_action_space(s) + }, + space(s) { + push_undo() + place_disc(s) + vm_next() + }, + skip() { + push_undo() + vm_next() + }, +} + +function can_vm_replace() { + for (let s of game.vm.spaces) + if (can_replace_cube(s)) + return true + return false +} + +function goto_vm_replace() { + if (can_vm_replace()) + game.state = "vm_replace" + else + vm_next() +} + +states.vm_replace = { + prompt() { + event_prompt("Replace " + game.vm.count + " cubes.") + if (game.vm.upto) + view.actions.skip = 1 + for (let s of game.vm.spaces) + if (can_replace_cube(s)) + for_each_enemy_cube(s, gen_action_piece) + }, + piece(p) { + push_undo() + let s = game.pieces[p] + remove_piece(p) + place_cube(s) + if (--game.vm.count === 0 || !can_vm_replace()) + vm_next() + }, + skip() { + push_undo() + vm_next() + }, +} + +function can_vm_remove() { + for (let s of game.vm.spaces) + if (can_remove_cube(s)) + return true + return false +} + +function goto_vm_remove() { + if (can_vm_remove()) + game.state = "vm_remove" + else + vm_next() +} + +states.vm_remove = { + prompt() { + event_prompt("Remove " + game.vm.count + " cubes.") + if (game.vm.upto) + view.actions.skip = 1 + for (let s of game.vm.spaces) + if (can_remove_cube(s)) + for_each_enemy_cube(s, gen_action_piece) + }, + piece(p) { + push_undo() + remove_piece(p) + if (--game.vm.count === 0 || !can_vm_remove()) + vm_next() + }, + skip() { + push_undo() + vm_next() + }, +} + +// === COMPLICATED EVENT STATES === + +function can_play_freemason_parade() { + for (let s of MILITARY) + if (has_commune_cube(s) && has_versailles_cube(s)) + return true + return false +} // === SETUP === @@ -1760,3 +2350,398 @@ function map_delete(map, item) { } } } + +// === GENERATED EVENT CODE === + +const CODE = [] + +CODE[1] = [ // Jules Ducatel + [ vm_if, ()=>(game.round === 4) ], + [ vm_goto, "reveal_commune_hand" ], + [ vm_else ], + [ vm_goto, "reveal_commune_objective" ], + [ vm_endif ], + [ vm_ops, 1, MILITARY ], + [ vm_return ], +] + +CODE[2] = [ // The Murder of Vincenzini + [ vm_increase_revolutionary_momentum ], + [ vm_remove_up_to, 3, POLITICAL ], + [ vm_return ], +] + +CODE[3] = [ // Brassardiers + [ vm_replace, 1, ()=>(where_present(MILITARY)) ], + [ vm_return ], +] + +CODE[4] = [ // Jules Ferry + [ vm_switch, ["place","replace"] ], + [ vm_case, "place" ], + [ vm_place_up_to, 2, REPUBLICANS ], + [ vm_case, "replace" ], + [ vm_replace, 1, NATIONAL_ASSEMBLY ], + [ vm_endswitch ], + [ vm_return ], +] + +CODE[5] = [ // Le Figaro + [ vm_switch, ["place","replace"] ], + [ vm_case, "place" ], + [ vm_place_up_to, 2, PRESS ], + [ vm_case, "replace" ], + [ vm_replace, 1, PUBLIC_OPINION ], + [ vm_endswitch ], + [ vm_return ], +] + +CODE[6] = [ // Général Louis Valentin + [ vm_goto, "general_louis_valentin" ], + [ vm_return ], +] + +CODE[7] = [ // Général Espivent + [ vm_remove_up_to, 2, SOCIAL_MOVEMENTS ], + [ vm_return ], +] + +CODE[8] = [ // Les Amis de l'Ordre + [ vm_place, 2, PARIS ], + [ vm_return ], +] + +CODE[9] = [ // Socialist Newspaper Ban + [ vm_increase_revolutionary_momentum ], + [ vm_remove_up_to, 2, PRESS ], + [ vm_asm, ()=>game.snb=1 ], + [ vm_return ], +] + +CODE[10] = [ // Fortification of Mont-Valérien + [ vm_place_up_to, 1, MONT_VALERIEN ], + [ vm_if, ()=>(is_control(MONT_VALERIEN)) ], + [ vm_may_place_disc, MONT_VALERIEN ], + [ vm_endif ], + [ vm_return ], +] + +CODE[11] = [ // Adolphe Thiers + [ vm_increase_prussian_collaboration ], + [ vm_place_up_to, 2, ROYALISTS ], + [ vm_return ], +] + +CODE[12] = [ // Otto von Bismarck + [ vm_remove_own, NATIONAL_ASSEMBLY ], + [ vm_increase_prussian_collaboration ], + [ vm_ops, 2, MILITARY ], + [ vm_return ], +] + +CODE[13] = [ // Général Ernest de Cissey + [ vm_ops, 4, FORT_D_ISSY ], + [ vm_return ], +] + +CODE[14] = [ // Colonel de Lochner + [ vm_switch, ["mont_valerien","butte_montmartre"] ], + [ vm_case, "mont_valerien" ], + [ vm_ops, 3, MONT_VALERIEN ], + [ vm_case, "butte_montmartre" ], + [ vm_ops, 3, BUTTE_MONTMARTRE ], + [ vm_endswitch ], + [ vm_return ], +] + +CODE[15] = [ // Jules Favre + [ vm_increase_prussian_collaboration ], + [ vm_place_up_to, 1, REPUBLICANS ], + [ vm_return ], +] + +CODE[16] = [ // Hostage Decree + [ vm_remove, 20, CATHOLIC_CHURCH ], + [ vm_return ], +] + +CODE[17] = [ // Maréchal Macmahon + [ vm_ops, 4, PARIS ], + [ vm_return ], +] + +CODE[18] = [ // Paule Minck + [ vm_replace, 1, ()=>(where_present(MILITARY)) ], + [ vm_return ], +] + +CODE[19] = [ // Walery Wroblewski + [ vm_place_disc, ()=>(where_present(PARIS)) ], + [ vm_return ], +] + +CODE[20] = [ // Banque de France + [ vm_decrease_revolutionary_momentum ], + [ vm_place_up_to, 1, PARIS ], + [ vm_may_place_disc, PARIS ], + [ vm_return ], +] + +CODE[21] = [ // Le Réveil + [ vm_increase_revolutionary_momentum ], + [ vm_place_up_to, 1, PRESS ], + [ vm_return ], +] + +CODE[22] = [ // Execution of Generals + [ vm_increase_prussian_collaboration ], + [ vm_replace_up_to, 2, ()=>(where_present(PARIS)) ], + [ vm_return ], +] + +CODE[23] = [ // Les Cantinières + [ vm_place_removed_up_to, 2, ()=>(where_present(MILITARY)) ], + [ vm_return ], +] + +CODE[24] = [ // Eugène Protot + [ vm_ops, 3, INSTITUTIONAL ], + [ vm_return ], +] + +CODE[25] = [ // Paul Cluseret + [ vm_ops, 2, PARIS ], + [ vm_return ], +] + +CODE[26] = [ // Gaston Crémieux + [ vm_increase_revolutionary_momentum ], + [ vm_place_up_to, 2, SOCIAL_MOVEMENTS ], + [ vm_return ], +] + +CODE[27] = [ // Luise Michel + [ vm_increase_revolutionary_momentum ], + [ vm_switch, ["public_opinion","paris"] ], + [ vm_case, "public_opinion" ], + [ vm_ops, 1, PUBLIC_OPINION ], + [ vm_case, "paris" ], + [ vm_ops, 1, PARIS ], + [ vm_endswitch ], + [ vm_return ], +] + +CODE[28] = [ // Jaroslav Dombrowski + [ vm_place_up_to, 1, PARIS ], + [ vm_may_place_disc, PARIS ], + [ vm_return ], +] + +CODE[29] = [ // Raoul Rigault + [ vm_increase_revolutionary_momentum ], + [ vm_move_up_to, 2, CATHOLIC_CHURCH, PARIS ], + [ vm_return ], +] + +CODE[30] = [ // Karl Marx + [ vm_goto, "karl_marx" ], + [ vm_return ], +] + +CODE[31] = [ // Blanquists + [ vm_increase_revolutionary_momentum ], + [ vm_ops, 2, MILITARY ], + [ vm_return ], +] + +CODE[32] = [ // Général Lullier + [ vm_ops, 4, CHATEAU_DE_VINCENNES ], + [ vm_return ], +] + +CODE[33] = [ // Jules Vallès + [ vm_increase_revolutionary_momentum ], + [ vm_ops, 2, PUBLIC_OPINION ], + [ vm_return ], +] + +CODE[34] = [ // Charles Delescluze + [ vm_switch, ["military","political"] ], + [ vm_case, "military" ], + [ vm_ops, 3, MILITARY ], + [ vm_case, "political" ], + [ vm_ops, 3, POLITICAL ], + [ vm_endswitch ], + [ vm_return ], +] + +CODE[35] = [ // Conciliation + [ vm_move_between_up_to, 2, PUBLIC_OPINION, PARIS ], + [ vm_return ], +] + +CODE[36] = [ // Georges Clemenceau + [ vm_move_up_to, 3, PARIS, INSTITUTIONAL ], + [ vm_return ], +] + +CODE[37] = [ // Archbishop Georges Darboy + [ vm_move_up_to, 4, ANY, CATHOLIC_CHURCH ], + [ vm_return ], +] + +CODE[38] = [ // Victor Hugo + [ vm_decrease_revolutionary_momentum ], + [ vm_decrease_prussian_collaboration ], + [ vm_ops, 4, PUBLIC_OPINION ], + [ vm_return ], +] + +CODE[39] = [ // Léon Gambetta + [ vm_replace_up_to, 1, INSTITUTIONAL ], + [ vm_if, ()=>(game.active === COMMUNE) ], + [ vm_decrease_prussian_collaboration ], + [ vm_else ], + [ vm_decrease_revolutionary_momentum ], + [ vm_endif ], + [ vm_return ], +] + +CODE[40] = [ // Elihu Washburne + [ vm_if, ()=>(game.active === COMMUNE) ], + [ vm_increase_revolutionary_momentum ], + [ vm_else ], + [ vm_increase_prussian_collaboration ], + [ vm_endif ], + [ vm_ops, 2, INSTITUTIONAL ], + [ vm_return ], +] + +CODE[41] = [ // Freemason Parade + [ vm_goto, "freemason_parade" ], + [ vm_switch, ["place","replace"] ], + [ vm_case, "place" ], + [ vm_place_up_to, 2, INSTITUTIONAL ], + [ vm_case, "replace" ], + [ vm_replace, 1, INSTITUTIONAL ], + [ vm_endswitch ], + [ vm_return ], +] + +CODE[42] = [ // Paris Cannons + [ vm_switch, ["momentum","ops"] ], + [ vm_case, "momentum" ], + [ vm_if, ()=>(game.active === COMMUNE) ], + [ vm_increase_revolutionary_momentum ], + [ vm_else ], + [ vm_increase_prussian_collaboration ], + [ vm_endif ], + [ vm_case, "ops" ], + [ vm_ops, 3, PARIS ], + [ vm_endswitch ], + [ vm_return ], +] + +CODE[43] = [ // Aux Barricades! + [ vm_ops, 2, PARIS ], + [ vm_player, COMMUNE ], + [ vm_may_place_disc, BUTTE_AUX_CAILLES ], + [ vm_return ], +] + +CODE[44] = [ // Commune's Stronghold + [ vm_switch, ["ops","remove"] ], + [ vm_case, "ops" ], + [ vm_ops, 2, MILITARY ], + [ vm_case, "remove" ], + [ vm_remove, 1, ANY ], + [ vm_endswitch ], + [ vm_return ], +] + +CODE[45] = [ // Fighting in Issy Village + [ vm_ops, 2, FORTS ], + [ vm_player, VERSAILLES ], + [ vm_may_place_disc, FORT_D_ISSY ], + [ vm_return ], +] + +CODE[46] = [ // Battle of Mont-Valérien + [ vm_ops, 3, FORTS ], + [ vm_if, ()=>(game.current === COMMUNE) ], + [ vm_decrease_prussian_collaboration ], + [ vm_else ], + [ vm_increase_prussian_collaboration ], + [ vm_endif ], + [ vm_return ], +] + +CODE[47] = [ // Raid on Château de Vincennes + [ vm_switch, ["ops","remove"] ], + [ vm_case, "ops" ], + [ vm_ops, 2, MILITARY ], + [ vm_case, "remove" ], + [ vm_remove, 1, ANY ], + [ vm_endswitch ], + [ vm_return ], +] + +CODE[48] = [ // Revolution in the Press + [ vm_switch, ["ops","replace"] ], + [ vm_case, "ops" ], + [ vm_ops, 3, PUBLIC_OPINION ], + [ vm_case, "replace" ], + [ vm_replace, 1, ANY ], + [ vm_endswitch ], + [ vm_return ], +] + +CODE[49] = [ // Pius IX + [ vm_switch, ["replace","remove"] ], + [ vm_case, "replace" ], + [ vm_replace_different, 2, POLITICAL ], + [ vm_case, "remove" ], + [ vm_remove, 1, ANY ], + [ vm_endswitch ], + [ vm_return ], +] + +CODE[50] = [ // Socialist International + [ vm_ops, 2, PUBLIC_OPINION ], + [ vm_if, ()=>(game.current === COMMUNE) ], + [ vm_increase_revolutionary_momentum ], + [ vm_else ], + [ vm_decrease_revolutionary_momentum ], + [ vm_endif ], + [ vm_return ], +] + +CODE[51] = [ // Royalists Dissension + [ vm_switch, ["ops","remove"] ], + [ vm_case, "ops" ], + [ vm_ops, 2, INSTITUTIONAL ], + [ vm_case, "remove" ], + [ vm_remove, 1, ANY ], + [ vm_endswitch ], + [ vm_return ], +] + +CODE[52] = [ // Rise of Republicanism + [ vm_switch, ["ops","replace"] ], + [ vm_case, "ops" ], + [ vm_ops, 3, INSTITUTIONAL ], + [ vm_case, "replace" ], + [ vm_replace, 1, MILITARY ], + [ vm_endswitch ], + [ vm_return ], +] + +CODE[53] = [ // Legitimacy + [ vm_ops, 3, POLITICAL ], + [ vm_if, ()=>(game.active === COMMUNE) ], + [ vm_increase_revolutionary_momentum ], + [ vm_else ], + [ vm_increase_prussian_collaboration ], + [ vm_endif ], + [ vm_return ], +] |