diff options
-rw-r--r-- | play.css | 4 | ||||
-rw-r--r-- | rules.js | 169 |
2 files changed, 120 insertions, 53 deletions
@@ -19,10 +19,6 @@ button span.suit { line-height: 1; } -button { - min-width: 48px; -} - body { background-color: slategray; } @@ -11,10 +11,8 @@ add undo steps and pauses for saxony neutral return pieces show who controls which power in player list -set-aside victory marker areas - austria/pragmatic move order on flanders (start with pragmatic) - only stack if agree (undo/move to previous space) +only stack if agree (undo/move to previous space) winter scoring @@ -22,26 +20,12 @@ when are subsidies given? example france subsidy to prussia at france's stage? at prussia's stage? - --- advanced -- - -silesia home country for prussia - tc subsidies minor when major fortress enemy occupied subsidy contracts imperial election -expeditionary corps - -political changes - prussia annexes silesia - france reduces military objectives - saxony's defection - -neutrality - */ // TODO: austria/pragmatic action stage - show both sides cards and interleave movement on flanders map @@ -114,6 +98,7 @@ const ELIMINATED = data.cities.name.length const ARENBERG = 17 const SAXONY_GENERAL = 19 const SAXONY_TRAIN = 29 +const PRUSSIAN_TRAIN_2 = 23 const all_powers = [ 0, 1, 2, 3, 4, 5 ] const all_major_powers = [ 0, 1, 2, 3 ] @@ -724,6 +709,7 @@ all_home_country_major_fortresses[P_PRAGMATIC] = set_intersect(data.type.major_f all_home_country_major_fortresses[P_AUSTRIA] = set_intersect(data.type.major_fortress, data.country.Austria) all_home_country_major_fortresses[P_BAVARIA] = set_intersect(data.type.major_fortress, data.country.Bavaria) all_home_country_major_fortresses[P_SAXONY] = set_intersect(data.type.major_fortress, data.country.Saxony) +const all_silesian_major_fortresses = set_intersect(data.type.major_fortress, data.country.Silesia) const all_core_austria_cities = data.country.Austria.filter(is_bohemia_space) const all_core_austria_fortresses = all_home_country_fortresses[P_AUSTRIA].filter(is_bohemia_space) @@ -733,6 +719,11 @@ const all_prussian_and_silesian_fortresses = set_union( all_silesian_fortresses ) +const all_prussian_and_silesian_major_fortresses = set_union( + all_home_country_major_fortresses[P_PRUSSIA], + all_silesian_major_fortresses +) + const all_prussian_and_silesian_cities = set_union(data.country.Prussia, data.country.Silesia) const all_prussian_and_silesian_and_polish_cities = set_union(data.country.Prussia, data.country.Silesia, data.country.Poland) @@ -1852,17 +1843,22 @@ function goto_movement() { function is_forbidden_neutral_space(pow, to) { if (is_saxony_neutral()) { - if (pow === P_SAXONY) - return !set_has(data.country.Saxony, to) - else - return set_has(data.country.Saxony, to) + if (pow === P_SAXONY) { + if (!set_has(data.country.Saxony, to)) + return true + } else { + if (set_has(data.country.Saxony, to)) + return true + } } if (is_prussia_neutral()) { - // TODO: Silesia home country - if (pow === P_PRUSSIA) - return !set_has(data.country.Prussia, to) - else - return set_has(data.country.Prussia, to) + if (pow === P_PRUSSIA) { + if (!set_has(all_prussian_and_silesian_cities, to)) + return true + } else { + if (set_has(all_prussian_and_silesian_cities, to)) + return true + } } return false } @@ -2702,10 +2698,10 @@ states.recruit = { } function enter_piece_at(p, s) { - if (is_general(game.selected)) - enter_general_at(game.selected, s) + if (is_general(p)) + enter_general_at(p, s) else - enter_train_at(game.selected, s) + enter_train_at(p, s) } function enter_general_at(p, s) { @@ -2823,6 +2819,8 @@ function goto_combat() { let to = [] for (let p of all_controlled_generals(game.power)) { + if (piece_power[p] === P_PRUSSIA && is_prussia_neutral()) + continue if (piece_power[p] === P_SAXONY && is_saxony_neutral()) continue if (is_piece_on_map(p)) @@ -2830,6 +2828,8 @@ function goto_combat() { } for (let p of all_enemy_generals(game.power)) { + if (piece_power[p] === P_PRUSSIA && is_prussia_neutral()) + continue if (piece_power[p] === P_SAXONY && is_saxony_neutral()) continue if (is_piece_on_map(p)) @@ -3525,6 +3525,10 @@ function count_vp_markers(pow) { return n } +function count_vp_markers_in_pool(pow) { + return Math.max(0, power_victory_target[pow] - count_vp_markers(pow)) +} + function check_instant_victory() { let margin = [ count_vp_markers(P_FRANCE) - 11, @@ -4146,7 +4150,7 @@ states.bring_expeditionary_corps_on_map = { gen_action_space(s) }, space(s) { - log("P" + game.selected + " to S" + s + ".") + log(`Expeditionary corps P${game.selected} from S${game.pos[game.selected]} to S${s}.`) enter_piece_at(game.selected, s) game.selected = -1 goto_expeditionary_corps() @@ -4162,6 +4166,7 @@ states.send_expeditionary_corps_off_map = { gen_action_piece(p) }, piece(p) { + log(`Expeditionary corps P${p} from S${game.pos[p]} to S${game.selected}.`) if (game.troops[p] === 0) throw "TODO - pay for 2 troops minimum" game.pos[p] = game.selected @@ -4273,23 +4278,32 @@ function goto_saxony_return_foreign_pieces() { return } } - - set_active_to_power(P_SAXONY) - game.state = "saxony_return_home" + goto_saxony_return_home() } states.saxony_return_foreign_who = { inactive: "return foreign pieces from Saxony", prompt() { prompt("Return pieces to the nearest city in their home country.") - for (let p of all_power_pieces[game.power]) - if (set_has(data.country.Saxony, game.pos[p])) + let done = true + for (let p of all_power_pieces[game.power]) { + if (set_has(data.country.Saxony, game.pos[p])) { gen_action_piece(p) + done = false + } + } + if (done) + view.actions.next = 1 }, piece(p) { + push_undo() game.selected = p game.state = "saxony_return_foreign_where" }, + next() { + clear_undo() + goto_saxony_return_foreign_pieces() + }, } states.saxony_return_foreign_where = { @@ -4304,10 +4318,15 @@ states.saxony_return_foreign_where = { log(">P" + game.selected + " to S" + s) enter_piece_at(game.selected, s) game.selected = -1 - goto_saxony_return_foreign_pieces() + game.state = "saxony_return_foreign_who" }, } +function goto_saxony_return_home() { + set_active_to_power(P_SAXONY) + game.state = "saxony_return_home" +} + states.saxony_return_home = { inactive: "become neutral", prompt() { @@ -4392,7 +4411,7 @@ function end_saxony_neutral() { /* PRUSSIA ANNEXES SILESIA */ function is_prussia_neutral() { - return game.flags & F_PRUSSIA_NEUTRAL + return !!(game.flags & F_PRUSSIA_NEUTRAL) } function has_prussia_annexed_silesia() { @@ -4474,13 +4493,6 @@ function goto_annex_silesia() { } goto_annex_silesia_return_austrian_pieces() - - // return austrian pieces in prussia or Poland - // return prussian pieces outside prussia - // enter second supply train - // prussia is neutral until actions stage after next - - // return markers if prussian piece leaves prussia } function goto_annex_silesia_return_austrian_pieces() { @@ -4495,14 +4507,25 @@ states.silesia_return_austrian_who = { inactive: "return Austrian pieces from Prussia and Poland", prompt() { prompt("Return pieces to the nearest city in their home country.") - for (let p of all_power_pieces[P_AUSTRIA]) - if (set_has(all_prussian_and_silesian_and_polish_cities, game.pos[p])) + let done = true + for (let p of all_power_pieces[P_AUSTRIA]) { + if (set_has(all_prussian_and_silesian_and_polish_cities, game.pos[p])) { gen_action_piece(p) + done = false + } + } + if (done) + view.actions.next = 1 }, piece(p) { + push_undo() game.selected = p game.state = "silesia_return_austrian_where" }, + next() { + clear_undo() + goto_annex_silesia_return_prussian_pieces() + }, } states.silesia_return_austrian_where = { @@ -4517,13 +4540,19 @@ states.silesia_return_austrian_where = { log(">P" + game.selected + " to S" + s) enter_piece_at(game.selected, s) game.selected = -1 - goto_annex_silesia_return_austrian_pieces() + game.state = "silesia_return_austrian_who" }, } function goto_annex_silesia_return_prussian_pieces() { set_active_to_power(P_PRUSSIA) - game.state = "silesia_return_prussian_who" + for (let p of all_power_pieces[P_PRUSSIA]) { + if (is_piece_on_map(p) && !set_has(all_prussian_and_silesian_cities, game.pos[p])) { + game.state = "silesia_return_prussian_who" + return + } + } + game.state = "silesia_enter_prussian_train" } states.silesia_return_prussian_who = { @@ -4547,7 +4576,7 @@ states.silesia_return_prussian_who = { }, next() { clear_undo() - end_action_stage_2() + game.state = "silesia_enter_prussian_train" }, } @@ -4567,6 +4596,48 @@ states.silesia_return_prussian_where = { }, } +states.silesia_enter_prussian_train = { + inactive: "enter Prussian supply train", + prompt() { + prompt("Enter second supply train.") + view.selected = PRUSSIAN_TRAIN_2 + let possible = false + for (let s of all_prussian_and_silesian_major_fortresses) { + if (is_friendly_controlled_fortress(s) && !has_any_piece(s)) { + gen_action_space(s) + possible = true + } + } + if (!possible) + view.actions.pass = 1 + }, + space(s) { + let p = PRUSSIAN_TRAIN_2 + log(">P" + p + " to S" + s) + enter_piece_at(p, s) + game.state = "silesia_done" + }, + pass() { + let p = PRUSSIAN_TRAIN_2 + let s = ELIMINATED + log(">P" + p + " to S" + s) + game.pos[p] = s + end_action_stage_2() + }, +} + +states.silesia_done = { + inactive: "annex Silesia", + prompt() { + prompt("Silesian annexation done.") + view.actions.next = 1 + }, + next() { + clear_undo() + end_action_stage_2() + } +} + /* FRANCE REDUCES MILITARY OBJECTIVES */ function count_french_vp_markers_in_core_austria() { |