diff options
Diffstat (limited to 'rules.js')
-rw-r--r-- | rules.js | 250 |
1 files changed, 232 insertions, 18 deletions
@@ -543,6 +543,14 @@ function all_enemy_powers(pow) { } } +function is_allied_power(a, b) { + return !all_enemy_powers(a).includes(b) +} + +function is_controlled_power(major, other) { + return player_from_power(major) === player_from_power(other) +} + function all_non_coop_powers(pow) { switch (pow) { case P_FRANCE: @@ -2485,13 +2493,12 @@ states.re_enter_train_power = { inactive: "move", prompt() { prompt("Re-enter supply train from which power?") - view.actions.power = [] for (let pow of all_controlled_powers(game.power)) { if (game.move_re_entered & (1 << pow)) continue for (let p of all_power_trains[pow]) { if (can_train_re_enter(p)) { - view.actions.power.push(pow) + gen_action_power(pow) break } } @@ -4530,12 +4537,12 @@ states.accept_peace = { prompt() { prompt("Accept Prussia's offer of temporary peace to annex Silesia?") view.actions.accept = 1 - view.actions.deny = 1 + view.actions.refuse = 1 }, accept() { goto_annex_silesia() }, - deny() { + refuse() { end_action_stage_2() }, } @@ -4874,6 +4881,195 @@ function end_imperial_election() { goto_start_turn() } +/* SUBSIDY CONTRACTS - CREATE */ + +function goto_propose_subsidy() { + game.proposal = { save_power: game.power, save_state: game.state, from: -1, to: -1, n: 0 } + game.state = "propose_subsidy_from" +} + +states.propose_subsidy_from = { + inactive: "create subsidy contract", + prompt() { + prompt("Subsidy contract from which major power?") + for (let from of all_major_powers) + if (is_allied_power(game.power, from)) + gen_action_power(from) + }, + power(from) { + game.proposal.from = from + game.state = "propose_subsidy_to" + } +} + +states.propose_subsidy_to = { + inactive: "create subsidy contract", + prompt() { + let player = game.power + let from = game.proposal.from + prompt(`Subsidy contract between ${power_name[from]} and who?`) + for (let to of all_powers) { + if (from !== to && is_allied_power(from, to)) { + if (is_controlled_power(player, from) || is_controlled_power(player, to)) + gen_action_power(to) + } + } + }, + power(to) { + game.proposal.to = to + game.state = "propose_subsidy_length" + } +} + +states.propose_subsidy_length = { + inactive: "create subsidy contract", + prompt() { + let from = game.proposal.from + let to = game.proposal.to + prompt(`Subsidy contract between ${power_name[from]} and ${power_name[to]} for how many turns?`) + view.actions.value = [ 1, 2, 3, 4, 5, 6 ] + }, + value(n) { + clear_undo() + game.proposal.n = n + set_active_to_power(game.proposal.from) + game.state = "propose_subsidy_approve" + }, +} + +states.propose_subsidy_approve = { + inactive: "approve subsidy contract", + prompt() { + let from = game.proposal.from + let to = game.proposal.to + let n = game.proposal.n + prompt(`Subsidy contract between ${power_name[from]} and ${power_name[to]} for ${n} turns?`) + view.actions.accept = 1 + view.actions.refuse = 1 + }, + accept() { + let from = game.proposal.from + let to = game.proposal.to + let n = game.proposal.n + log(`Subsidy contract between ${power_name[from]} and ${power_name[to]} for ${n} turns.`) + map_set(game.contracts[from], to, map_get(game.contracts[from], to, 0) + n) + end_propose_subsidy() + }, + refuse() { + let from = game.proposal.from + let to = game.proposal.to + let n = game.proposal.n + log(`${power_name[from]} refused to create subsidy contract to ${power_name[to]} for ${n} turns.`) + end_propose_subsidy() + }, +} + +function end_propose_subsidy() { + set_active_to_power(game.proposal.save_power) + game.state = game.proposal.save_state + delete game.proposal +} + +/* SUBSIDY CONTRACTS - CANCEL */ + +function may_cancel_subsidy() { + let player = game.power + let result = false + for (let from of all_major_powers) { + map_for_each(game.contracts[from], (to, n) => { + // cannot cancel initial contract! + if (from === P_FRANCE && to === P_BAVARIA && game.turn < 3) + return + if (is_controlled_power(player, from) || is_controlled_power(player, to)) + result = true + }) + } + return result +} + +function goto_cancel_subsidy() { + game.proposal = { save_power: game.power, save_state: game.state, from: -1, to: -1 } + game.state = "cancel_subsidy_from" +} + +states.cancel_subsidy_from = { + inactive: "cancel subsidy contract", + prompt() { + let player = game.power + prompt("Cancel which subsidy contract?") + for (let from of all_major_powers) { + map_for_each(game.contracts[from], (to, n) => { + // cannot cancel initial contract! + if (from === P_FRANCE && to === P_BAVARIA && game.turn < 3) + return + if (is_controlled_power(player, from) || is_controlled_power(player, to)) + gen_action_power(from) + }) + } + }, + power(from) { + game.proposal.from = from + game.state = "cancel_subsidy_to" + } +} + +states.cancel_subsidy_to = { + inactive: "cancel subsidy contract", + prompt() { + let player = game.power + let from = game.proposal.from + prompt(`Cancel subsidy contract between ${power_name[from]} and who?`) + map_for_each(game.contracts[from], (to, n) => { + // cannot cancel initial contract! + if (from === P_FRANCE && to === P_BAVARIA && game.turn < 3) + return + if (is_controlled_power(player, from) || is_controlled_power(player, to)) + gen_action_power(to) + }) + }, + power(to) { + let player = game.power + let from = game.proposal.from + clear_undo() + game.proposal.to = to + if (is_controlled_power(player, from)) + set_active_to_power(to) + else + set_active_to_power(from) + game.state = "cancel_subsidy_approve" + } +} + +states.cancel_subsidy_approve = { + inactive: "cancel subsidy contract", + prompt() { + let from = game.proposal.from + let to = game.proposal.to + prompt(`Cancel subsidy contract between ${power_name[from]} and ${power_name[to]}?`) + view.actions.accept = 1 + view.actions.refuse = 1 + }, + accept() { + let from = game.proposal.from + let to = game.proposal.to + log(`Canceled subsidy contract between ${power_name[from]} and ${power_name[to]}.`) + map_delete(game.contracts[from], to) + end_cancel_subsidy() + }, + refuse(n) { + let from = game.proposal.from + let to = game.proposal.to + log(power_name[game.power] + ` refused to cancel subsidy contract from ${power_name[from]}.`) + end_cancel_subsidy() + }, +} + +function end_cancel_subsidy() { + set_active_to_power(game.proposal.save_power) + game.state = game.proposal.save_state + delete game.proposal +} + /* SETUP */ const POWER_FROM_SETUP_STAGE = [ @@ -5334,11 +5530,39 @@ exports.view = function (state, player) { else view.actions.undo = 0 } + + // subsidy contracts actions for active player + if (!game.proposal) { + if (may_cancel_subsidy()) + view.actions.cancel_subsidy = 1 + view.actions.propose_subsidy = 1 + } + } return view } +exports.action = function (state, _player, action, arg) { + game = state + let S = states[game.state] + if (S && action in S) { + S[action](arg) + } else { + if (action === "undo" && game.undo && game.undo.length > 0) { + pop_undo() + } else if (action === "propose_subsidy") { + push_undo() + goto_propose_subsidy() + } else if (action === "cancel_subsidy") { + push_undo() + goto_cancel_subsidy() + } else + throw new Error("Invalid action: " + action) + } + return game +} + /* COMMON FRAMEWORK */ function goto_game_over(result, victory) { @@ -5355,20 +5579,6 @@ function prompt(str) { view.prompt = power_name[game.power] + ": " + str } -exports.action = function (state, _player, action, arg) { - game = state - let S = states[game.state] - if (S && action in S) { - S[action](arg) - } else { - if (action === "undo" && game.undo && game.undo.length > 0) - pop_undo() - else - throw new Error("Invalid action: " + action) - } - return game -} - function gen_action(action, argument) { if (view.actions[action] === undefined) view.actions[action] = [ argument ] @@ -5376,6 +5586,10 @@ function gen_action(action, argument) { set_add(view.actions[action], argument) } +function gen_action_power(p) { + gen_action("power", p) +} + function gen_action_piece(p) { gen_action("piece", p) } |