summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Andersson <tor@ccxvii.net>2023-03-05 19:20:18 +0100
committerTor Andersson <tor@ccxvii.net>2023-05-03 18:48:15 +0200
commit1397f7f5ac4e93cc7e01c3bf9505932722bfc6ef (patch)
treece6e446d4af332e992a93201b1305a4038abb0d2
parentc3e452ce9172f818126e2b15bd46c563c0f2ef88 (diff)
downloadandean-abyss-1397f7f5ac4e93cc7e01c3bf9505932722bfc6ef.tar.gz
Terror.
-rw-r--r--play.js49
-rw-r--r--rules.js115
2 files changed, 164 insertions, 0 deletions
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 ===