diff options
author | Tor Andersson <tor@ccxvii.net> | 2024-10-29 01:32:09 +0100 |
---|---|---|
committer | Tor Andersson <tor@ccxvii.net> | 2024-10-29 01:34:29 +0100 |
commit | f350952a89532d25da841b642c47c63703475e14 (patch) | |
tree | 67136d181ca928d76ef012eefd403d7e30076b44 /rules.js | |
parent | a20df50959feced99132b6b12bcfd7956d5ee41f (diff) | |
download | maria-f350952a89532d25da841b642c47c63703475e14.tar.gz |
must grant permission for mixed stacks on flanders map.
Cannot pass on remaining moves while alternating moves!
Diffstat (limited to 'rules.js')
-rw-r--r-- | rules.js | 239 |
1 files changed, 217 insertions, 22 deletions
@@ -2,7 +2,8 @@ /* -TODO: confirm austria/pragmatic stacking cooperation +TODO: confirm stacking when re-entering Arenberg on Flanders map? +TODO: stacking order (supreme) when re-entering genarals. OPTIMIZE: fewer/smarter/smaller lists, smarter power control checks OPTIMIZE: range checks instead of set checks @@ -1945,6 +1946,7 @@ function goto_movement_flanders() { } function goto_movement_bohemia() { + log_br() game.flags &= ~F_MOVE_FLANDERS game.state = "movement" if (!has_unmoved_piece_on_bohemia_map(game.power)) @@ -1962,10 +1964,12 @@ function resume_movement() { let row = sequence_of_play[game.stage+1] if (row.action === goto_movement_flanders) { let next = game.power === P_PRAGMATIC ? P_AUSTRIA : P_PRAGMATIC - if (!has_unmoved_piece_on_flanders_map(next)) + if (!has_unmoved_piece_on_flanders_map(next)) { + ++game.stage // no unmoved pieces, so can skip next step next_sequence_of_play() - else + } else { game.state = "movement_flanders_next" + } } else { game.state = "movement" } @@ -1974,6 +1978,20 @@ function resume_movement() { } } +function resume_movement_after_flanders_stacking() { + set_active_to_power(coop_major_power(game.power)) + game.selected = -1 + let row = sequence_of_play[game.stage+1] + if (row.action === goto_movement_flanders) { + next_sequence_of_play() + } else { + if (has_unmoved_piece_on_flanders_map(game.power)) + game.state = "movement" + else + next_sequence_of_play() + } +} + function is_forbidden_neutral_space(pow, to) { if (is_saxony_neutral()) { if (pow === P_SAXONY) { @@ -2054,6 +2072,17 @@ function has_moved_any_bohemia_pieces() { return false } +function may_end_movement() { + if (game.flags & F_MOVE_FLANDERS) { + // No passing of movement on Flanders map while alternating moves. + if (game.power === P_AUSTRIA) + return !has_unmoved_piece_on_flanders_map(P_PRAGMATIC) + if (game.power === P_PRAGMATIC) + return !has_unmoved_piece_on_flanders_map(P_AUSTRIA) + } + return true +} + states.movement = { inactive: "move", prompt() { @@ -2099,12 +2128,7 @@ states.movement = { else prompt("Move your generals and supply trains.") - if (game.power === P_AUSTRIA && (game.flags & F_MOVE_FLANDERS)) { - if (!has_moved_any_pieces()) - view.actions.confirm_end_flanders = 1 - else - view.actions.end_flanders = 1 - } else { + if (may_end_movement()) { if (!has_moved_any_pieces()) view.actions.confirm_end_movement = 1 else @@ -2139,12 +2163,6 @@ states.movement = { game.state = "move_general" } }, - confirm_end_flanders() { - this.end_flanders() - }, - end_flanders() { - this.end_movement() - }, confirm_end_movement() { this.end_movement() }, @@ -2197,6 +2215,8 @@ function is_illegal_cross_map_move(from, to) { } function can_move_general_to(p, from, to) { + if (to === game.forbidden) + return false if (is_forbidden_neutral_space(piece_power[p], to)) return false if (is_illegal_cross_map_move(from, to)) @@ -2349,7 +2369,10 @@ states.move_general = { if (s_give > 0 && u_take > 0) view.actions.give = 1 - view.actions.stop = 1 + if (here === game.forbidden) + view.actions.stop = 0 + else + view.actions.stop = 1 } else { gen_action_piece(who) view.actions.stop = 1 @@ -2517,6 +2540,35 @@ states.move_give = { }, } +function is_flanders_stack_move() { + let here = game.pos[game.selected] + if (is_flanders_space(here)) { + if (game.power === P_PRAGMATIC) { + if (find_general_of_power(here, P_AUSTRIA) >= 0) + return true + } + if (game.power === P_AUSTRIA) { + if (find_general_of_power(here, P_PRAGMATIC) >= 0) + return true + } + } + return false +} + +function is_alternating_move() { + if (game.flags & F_MOVE_FLANDERS) { + if (game.power === P_PRAGMATIC) { + if (has_unmoved_piece_on_flanders_map(P_AUSTRIA)) + return true + } + if (game.power === P_AUSTRIA) { + if (has_unmoved_piece_on_flanders_map(P_PRAGMATIC)) + return true + } + } + return false +} + function end_move_piece() { let here = game.pos[game.selected] @@ -2536,6 +2588,12 @@ function end_move_piece() { delete game.move_path + if (is_alternating_move()) { + log_conquest(game.move_conq) + game.move_conq = [] + log_br() + } + // uniting stacks: flag all as moved let supreme = false if (is_general(game.selected)) { @@ -2548,8 +2606,13 @@ function end_move_piece() { } } + if (game.flags & F_MOVE_FLANDERS) + delete game.forbidden + if (supreme) game.state = "move_supreme" + else if (is_flanders_stack_move()) + goto_confirm_flanders_stack() else resume_movement() } @@ -2572,13 +2635,110 @@ states.move_supreme = { if (game.pos[p] === here) game.supreme &= ~(1<<p) game.supreme |= (1<<p) - resume_movement() + if (is_flanders_stack_move()) + goto_confirm_flanders_stack() + else + resume_movement() }, piece(p) { this.supreme(p) }, } +function goto_confirm_flanders_stack() { + game.state = "confirm_flanders_stack_1" +} + +states.confirm_flanders_stack_1 = { + inactive: "move", + prompt() { + let p = game.selected + let s = game.pos[p] + let other = -1 + view.selected = game.selected + if (game.power === P_AUSTRIA) { + other = find_general_of_power(s, P_PRAGMATIC) + view.actions.power = [ P_PRAGMATIC ] + } else { + other = find_general_of_power(s, P_AUSTRIA) + view.actions.power = [ P_AUSTRIA ] + } + prompt(`${piece_name[p]} needs permission to stack with ${piece_name[other]} at ${data.cities.name[s]}.`) + }, + power(_) { + // save last undo step in game.proposal + game.proposal = game.undo[game.undo.length - 1] + + if (game.power === P_AUSTRIA) + set_active_to_power(P_PRAGMATIC) + else + set_active_to_power(P_AUSTRIA) + game.state = "confirm_flanders_stack_2" + }, +} + +states.confirm_flanders_stack_2 = { + inactive: "confirm mixed stack", + prompt() { + let p = game.selected + let s = game.pos[p] + view.selected = game.selected + let other = -1 + if (game.power === P_AUSTRIA) + other = find_general_of_power(s, P_AUSTRIA) + else + other = find_general_of_power(s, P_PRAGMATIC) + prompt(`${piece_name[p]} wants to stack with ${piece_name[other]} at ${data.cities.name[s]}.`) + view.actions.accept = 1 + view.actions.refuse = 1 + }, + accept() { + delete game.proposal + if (game.power === P_AUSTRIA) + set_active_to_power(P_PRAGMATIC) + else + set_active_to_power(P_AUSTRIA) + resume_movement_after_flanders_stacking() + }, + refuse() { + // remember who moved, then restore back to saved undo point + // select general to move to another city + let p = game.selected + let s = game.pos[game.selected] + game.undo = [ game.proposal ] + delete game.proposal + pop_undo() + game.selected = p + game.forbidden = s + game.state = "confirm_flanders_stack_3" + }, +} + +states.confirm_flanders_stack_3 = { + inactive: "move", + prompt() { + prompt(`${piece_name[game.selected]} is not allowed to stack at ${data.cities.name[game.forbidden]}.`) + gen_action_piece(game.selected) + //view.selected = game.selected + //view.actions.next = 1 + }, + piece(p) { + this.next() + }, + next() { + push_undo() + let s = game.forbidden + /* + if (game.power === P_AUSTRIA) + log("Pragmatic Army refused to stack at S" + s + ".") + else + log("Austria refused to stack at S" + s + ".") + */ + states.movement.piece(game.selected) + game.undo.pop() + }, +} + /* RE-ENTER SUPPLY TRAIN */ function goto_re_enter_train() { @@ -3674,12 +3834,23 @@ function finish_combat() { /* RETRO-ACTIVE CONQUEST */ +function get_fortress_control_power(s) { + for (let pow of all_major_powers) + if (is_power_controlled_fortress(pow, s)) + return pow + return -1 +} + function log_conquest(conq) { if (conq.length > 0) { - log_br() - log("Conquered") - for (let s of conq) - log(">S" + s) + let groups = map_group_by(conq, get_fortress_control_power) + map_for_each(groups, (pow, list) => { + log_br() + log(power_name[pow] + " Conquered") + for (let s of list) + log(">S" + s) + }) + } } @@ -5834,7 +6005,7 @@ function log_br() { /* COMMON LIBRARY */ function clear_undo() { - game.undo.length = 0 + game.undo = [] } function push_undo() { @@ -6101,3 +6272,27 @@ function map_for_each(map, f) { for (let i = 0; i < map.length; i += 2) f(map[i], map[i+1]) } + +function map_group_by(items, callback) { + let groups = [] + if (typeof callback === "function") { + for (let item of items) { + let key = callback(item) + let arr = map_get(groups, key) + if (arr) + arr.push(item) + else + map_set(groups, key, [ item ]) + } + } else { + for (let item of items) { + let key = item[callback] + let arr = map_get(groups, key) + if (arr) + arr.push(item) + else + map_set(groups, key, [ item ]) + } + } + return groups +} |