diff options
author | Tor Andersson <tor@ccxvii.net> | 2024-10-17 10:48:13 +0200 |
---|---|---|
committer | Tor Andersson <tor@ccxvii.net> | 2024-10-17 10:54:45 +0200 |
commit | 9d4e9253df7b3430bbe7e8313320388970ae494f (patch) | |
tree | 45579e73cbd9438cd1acc568b4c8c9ff848b7c64 | |
parent | e654baad3c06b56b6076688b11bfb0e6ef9ea84f (diff) | |
download | maria-9d4e9253df7b3430bbe7e8313320388970ae494f.tar.gz |
Use singleton game.selected for movement and setup.
Only multi-select during combat and retreat.
-rw-r--r-- | rules.js | 165 |
1 files changed, 63 insertions, 102 deletions
@@ -2,6 +2,8 @@ // TODO: game.selected - singleton instead of array +// TODO: re-entering supply trains during movement (10.2) + // TODO: austria/pragmatic action step - show both sides cards and interleave movement on flanders map // PLAN: move all austria on bohemia first, then alternate pragmatic and austria activations on flanders map // TODO: confirm mixed stack creation on flanders map (force "undo" to previous location if denied?) @@ -376,19 +378,25 @@ function format_card_list_prompt(list) { } function format_selected() { - if (game.selected.length === 0) - return "nobody" - return game.selected.map(p => piece_name[p]).join(" and ") + if (Array.isArray(game.selected)) { + if (game.selected.length === 0) + return "nobody" + return game.selected.map(p => piece_name[p]).join(" and ") + } else { + if (game.selected < 0) + return "nobody" + return piece_name[game.selected] + } } function log_move_to(to) { - let from = game.pos[game.selected[0]] - log("@" + game.selected.join(",") + ";" + from + "," + to) + let from = game.pos[game.selected] + log("@" + game.selected + ";" + from + "," + to) } function log_move_path() { if (game.move_path.length > 1) - log("@" + game.selected.join(",") + ";" + game.move_path.join(",")) + log("@" + game.selected + ";" + game.move_path.join(",")) } /* OBJECTIVES */ @@ -701,7 +709,7 @@ function goto_start_turn() { log("# Turn " + game.turn) - game.selected = null + game.selected = -1 delete game.ia_lost // MARIA: politics @@ -962,76 +970,44 @@ function end_tactical_cards() { /* TRANSFER TROOPS */ +function find_unstacked_general() { + let here = game.pos[game.selected] + for (let p of all_power_generals[game.power]) + if (game.pos[p] === here && game.selected !== p) + return p + return -1 +} + function count_stacked_take() { - let n = 0 - for (let p of game.selected) - n += 8 - game.troops[p] - return n + return 8 - game.troops[game.selected] } function count_unstacked_take() { - let here = game.pos[game.selected[0]] - let n = 0 - for (let p of all_power_generals[game.power]) - if (game.pos[p] === here && !set_has(game.selected, p)) - n += 8 - game.troops[p] - return n + let p = find_unstacked_general() + if (p < 0) + return 0 + return 8 - game.troops[p] } function count_stacked_give() { - let n = 0 - for (let p of game.selected) - n += game.troops[p] - 1 - return n + return game.troops[game.selected] - 1 } function count_unstacked_give() { - let here = game.pos[game.selected[0]] - let n = 0 - for (let p of all_power_generals[game.power]) - if (game.pos[p] === here && !set_has(game.selected, p)) - n += game.troops[p] - 1 - return n + let p = find_unstacked_general() + if (p < 0) + return 0 + return game.troops[p] - 1 } function take_troops(total) { - let here = game.pos[game.selected[0]] - - let n = total - for (let p of game.selected) { - let x = Math.max(0, Math.min(n, 8 - game.troops[p])) - game.troops[p] += x - n -= x - } - - n = total - for (let p of all_power_generals_rev[game.power]) { - if (game.pos[p] === here && !set_has(game.selected, p)) { - let x = Math.max(0, Math.min(n, game.troops[p] - 1)) - game.troops[p] -= x - n -= x - } - } + game.troops[game.selected] += total + game.troops[find_unstacked_general()] -= total } function give_troops(total) { - let here = game.pos[game.selected[0]] - - let n = total - for (let p of all_power_generals[game.power]) { - if (game.pos[p] === here && !set_has(game.selected, p)) { - let x = Math.max(0, Math.min(n, 8 - game.troops[p])) - game.troops[p] += x - n -= x - } - } - - n = total - for (let p of game.selected) { - let x = Math.max(0, Math.min(n, game.troops[p] - 1)) - game.troops[p] -= x - n -= x - } + game.troops[game.selected] -= total + game.troops[find_unstacked_general()] += total } /* MOVEMENT */ @@ -1111,8 +1087,7 @@ states.movement = { set_active_to_power(piece_power[p]) - // Note: Can only move one piece at a time in Maria! - game.selected = [ p ] + game.selected = p game.count = 0 @@ -1183,14 +1158,12 @@ function can_move_general_to(from, to) { function move_general_to(to, is_force_march) { let pow = game.power - let who = game.selected[0] + let who = game.selected let from = game.pos[who] let stop = false - for (let p of game.selected) { - set_add(game.moved, p) - game.pos[p] = to - } + set_add(game.moved, game.selected) + game.pos[game.selected] = to // Cannot conquer if force marching. // Cannot conquer if out of supply. @@ -1231,7 +1204,7 @@ function move_general_to(to, is_force_march) { // uniting stacks: flag all as moved and stop moving for (let p of all_coop_generals(pow)) { - if (game.pos[p] === to && !set_has(game.selected, p)) { + if (game.pos[p] === to && game.selected !== p) { set_add(game.moved, p) stop = true } @@ -1256,7 +1229,7 @@ states.move_supply_train = { prompt("Move supply train" + format_move(2)) view.selected = game.selected - let who = game.selected[0] + let who = game.selected let here = game.pos[who] if (game.count < 2 + game.main) @@ -1276,12 +1249,12 @@ states.move_supply_train = { this.stop() }, stop() { - let who = game.selected[0] + let who = game.selected set_add(game.moved, who) end_move_piece() }, space(to) { - let who = game.selected[0] + let who = game.selected let from = game.pos[who] game.move_path.push(to) @@ -1303,16 +1276,10 @@ states.move_general = { prompt("Move " + format_selected() + format_move(movement_range())) view.selected = game.selected - let who = game.selected[0] + let who = game.selected let here = game.pos[who] if (game.count === 0) { - if (game.selected.length > 1) { - for (let p of game.selected) { - gen_action_piece(p) - } - } - if (data.cities.main_roads[here].length > 0) view.actions.force_march = 1 @@ -1352,19 +1319,18 @@ states.move_general = { if (game.count === 0) { this.space(game.pos[p]) } else { - if (p === game.selected[0]) + if (p === game.selected) this.stop() else this.space(game.pos[p]) } }, stop() { - for (let p of game.selected) - set_add(game.moved, p) + set_add(game.moved, game.selected) end_move_piece() }, space(to) { - let who = game.selected[0] + let who = game.selected let from = game.pos[who] game.move_path.push(to) @@ -1423,12 +1389,12 @@ states.force_march = { prompt("Force March " + format_selected() + ".") view.selected = game.selected - let here = game.pos[game.selected[0]] + let here = game.pos[game.selected] for (let s of search_force_march(null, here)) gen_action_space(s) }, space(to) { - let here = game.pos[game.selected[0]] + let here = game.pos[game.selected] let came_from = [] search_force_march(came_from, here) @@ -1500,7 +1466,7 @@ function end_move_piece() { } delete game.move_path - game.selected = null + game.selected = -1 game.state = "movement" set_active_to_current_action_step() @@ -1724,7 +1690,7 @@ states.recruit = { spend_recruit_cost() if (game.pos[p] === ELIMINATED) { - game.selected = [ p ] + game.selected = p game.state = "re_enter" } else { game.recruit.troops += 1 @@ -1769,7 +1735,7 @@ states.re_enter = { prompt("Re-enter " + format_selected() + ".") view.selected = game.selected - let p = game.selected[0] + let p = game.selected let can_re_enter_at = is_general(p) ? can_re_enter_general : can_re_enter_supply_train if (is_map_space(game.recruit.re_enter)) { @@ -1782,14 +1748,14 @@ states.re_enter = { } }, space(s) { - let p = game.selected[0] + let p = game.selected game.pos[p] = s map_set(game.recruit.pieces, p, s) if (is_general(p)) { game.recruit.troops += 1 game.troops[p] = 1 } - game.selected = null + game.selected = -1 game.state = "recruit" }, } @@ -2326,6 +2292,7 @@ function search_retreat(loser, winner, range) { return result } +// TODO: remove hussars when retreating across them states.retreat = { inactive: "retreat defeated general", prompt() { @@ -2789,7 +2756,7 @@ exports.setup = function (seed, _scenario, _options) { moved: [], retro: [], - selected: [], + selected: -1, count: 0, } @@ -2818,7 +2785,7 @@ states.setup = { } else { let n_stacks = 0 for (let p of all_power_generals[game.power]) { - if (is_map_space(game.pos[p]) && !set_has(game.moved, p)) { + if (game.pos[p] !== ELIMINATED && !set_has(game.moved, p)) { gen_action_piece(p) n_stacks ++ } @@ -2834,7 +2801,7 @@ states.setup = { piece(p) { push_undo() set_add(game.moved, p) - game.selected = [ p ] + game.selected = p game.state = "setup_general" }, end_setup() { @@ -2865,7 +2832,7 @@ states.setup_general = { prompt("Add troops to " + format_selected() + ".") view.selected = game.selected - let who = game.selected[0] + let who = game.selected let n_self_min = setup_min_troops[who] let n_self_max = setup_max_troops[who] @@ -2884,14 +2851,8 @@ states.setup_general = { view.actions.value.push(i) }, value(v) { - let save = game.selected.length - 1 - for (let p of game.selected) { - let n = Math.min(8, v - save) - game.troops[p] += n - v -= n - --save - } - game.selected = null + game.troops[game.selected] += v + game.selected = -1 game.state = "setup" }, } |