From 1397f7f5ac4e93cc7e01c3bf9505932722bfc6ef Mon Sep 17 00:00:00 2001 From: Tor Andersson Date: Sun, 5 Mar 2023 19:20:18 +0100 Subject: Terror. --- play.js | 49 +++++++++++++++++++++++++++ rules.js | 115 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 164 insertions(+) diff --git a/play.js b/play.js index 082023c..fda7b3b 100644 --- a/play.js +++ b/play.js @@ -302,6 +302,11 @@ function init_ui() { } } + for (let i = 0; i < 40; ++i) { + ui.terror[i] = e = create("div", { className: "hide" }) + document.getElementById("tokens").appendChild(e) + } + function create_piece(c, action, id, x, y) { let e = create("div", { className: c, @@ -598,6 +603,27 @@ function action_piece_list(list, action) { } } +function layout_terror(tix, s, n) { + let [ tx, ty ] = get_center_xy(s) + tx -= 20 + ty -= 20 + if (s <= last_city) { + let r = get_layout_radius(s) + tx -= r + } else { + ty += -60 + } + for (let i = 0; i < n; ++i) { + ui.terror[tix].className = "token terror" + ui.terror[tix].style.left = tx + "px" + ui.terror[tix].style.top = ty + "px" + tx += 5 + ty += 5 + ++tix + } + return tix +} + function layout_farc_zone(s, elt) { let [x, y] = get_center_xy(s) if (s <= last_pop) { @@ -665,6 +691,8 @@ function on_update() { for (let i = view.farc_zones.length; i < ui.farc_zones.length; ++i) ui.farc_zones[i].className = "hide" + let tix = 0 + let list = [] for (let s = 0; s < data.spaces.length; ++s) { if (s <= last_pop) { @@ -709,6 +737,8 @@ function on_update() { // TODO: shipments with other faction/piece, not space + tix = layout_terror(tix, s, map_get(view.terror, s, 0) * 1) + let xy = get_layout_xy(s) if (xy) layout_pieces(list, xy[0], xy[1]) @@ -729,6 +759,9 @@ function on_update() { ui.spaces[s].classList.toggle("selected", view.where === s) } + for (; tix < 40; ++tix) + ui.terror[tix].className = "hide" + list.length = 0 for (let i = 0; i < 4; ++i) if (view.shipments[i] === AVAILABLE) @@ -891,5 +924,21 @@ function set_has(set, item) { return false } +function map_get(map, key, missing) { + let a = 0 + let b = (map.length >> 1) - 1 + while (a <= b) { + let m = (a + b) >> 1 + let x = map[m << 1] + if (key < x) + b = m - 1 + else if (key > x) + a = m + 1 + else + return map[(m << 1) + 1] + } + return missing +} + init_ui() scroll_with_middle_mouse("main") diff --git a/rules.js b/rules.js index 5e3e4f1..39062f8 100644 --- a/rules.js +++ b/rules.js @@ -473,10 +473,18 @@ function is_dept(s) { return s >= first_dept && s <= last_dept } +function is_city_or_dept(s) { + return s >= first_city && s <= last_dept +} + function is_loc(s) { return s >= first_loc && s <= last_loc } +function is_pop(s) { + return s >= first_pop && s <= last_pop +} + function is_adjacent(a, b) { return set_has(data.spaces[a].adjacent, b) } @@ -536,6 +544,31 @@ function move_piece(p, s) { game.pieces[p] = s } +function count_terror_and_sabotage() { + let n = (game.sabotage.length >> 1) + for (let i = 1; i < game.terror.length; i += 2) + n += game.terror[i] + return n +} + +function place_terror(s) { + if (count_terror_and_sabotage() < 40) + map_set(game.terror, s, map_get(game.terror, s, 0) + 1) +} + +function place_sabotage(s) { + if (count_terror_and_sabotage() < 40) + set_add(game.sabotage, s) +} + +function has_sabotage(s) { + return set_has(game.sabotage, s) +} + +function has_terror(s) { + return map_get(game.terror, s, 0) > 0 +} + function has_govt_control(s) { return game.govt_control & (1 << s) } @@ -1576,9 +1609,91 @@ states.attack_remove = { states.terror = { prompt() { + view.prompt = "Terror: Select space with Underground Guerrilla." + + // TODO: can terror no-pop dept? + + if (can_select_op_space(1)) { + for (let s = first_space; s <= last_dept; ++s) { + if (is_selected_op_space(s)) + continue + if (has_underground_guerrilla(s, game.current)) + gen_action_space(s) + } + } + + if (can_select_op_space(0)) { + for (let s = first_loc; s <= last_loc; ++s) { + if (is_selected_op_space(s)) + continue + if (has_underground_guerrilla(s, game.current)) + gen_action_space(s) + } + } + + gen_operation_common() }, space(s) { + push_undo() + + logi(`S${s}.`) + + if (is_loc(s)) + select_op_space(s, 0) + else + select_op_space(s, 1) + + game.state = "terror_space" + game.op.where = s + }, + done: end_operation, +} + +function add_aid(n) { + game.aid = Math.max(0, game.aid + n) +} + +states.terror_space = { + prompt() { + view.prompt = `Terror in ${space_name[game.op.where]}: Activate an Underground Guerrilla.` + gen_activate_guerrilla(game.op.where, game.current) }, + piece(p) { + set_active(p) + + if (is_loc(game.op.where)) { + place_sabotage(game.op.where) + } else { + place_terror(game.op.where) + + if (is_pop(game.op.where)) { + if (game.current === FARC) { + if (game.support[game.op.where] > -2) + game.support[game.op.where] -- + } else { + if (game.support[game.op.where] > 0) + game.support[game.op.where] -- + else if (game.support[game.op.where] < 0) + game.support[game.op.where] ++ + } + } + } + + if (game.current === AUC) { + console.log("AID CUT: ", game.op.spaces.length) + // if one space, drop aid by 3 + if (game.op.spaces.length === 1) { + logi("Aid Cut by 3.") + add_aid(-3) + // if two or more spaces, drop aid by 5 + } else if (game.op.spaces.length === 2) { + logi("Aid Cut by 2.") + add_aid(-2) + } + } + + game.state = "terror" + } } // === SPECIAL ACTIVITIES === -- cgit v1.2.3