summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Andersson <tor@ccxvii.net>2021-06-23 15:42:49 +0200
committerTor Andersson <tor@ccxvii.net>2022-11-16 19:08:56 +0100
commitbba2352b38b5ad5d25bb07198eed2d426ce1831d (patch)
treec238d30bbe72ec7338bbcdab4c1ccb2c56d383cb
parent7eebbf33f8e84cc6ca468cfe1aa23297100f0bfe (diff)
downloadjulius-caesar-bba2352b38b5ad5d25bb07198eed2d426ce1831d.tar.gz
caesar: Pick Mars and Neptune battles after movement.
This is like the Jihad card in Crusader Rex where the rules clarify that the surprise attack is declared before player two moves. We can then also mark the surprise attacking blocks on the map.
-rw-r--r--mars.svg4
-rw-r--r--neptune.svg3
-rw-r--r--play.html11
-rw-r--r--rules.js96
-rw-r--r--ui.js54
5 files changed, 86 insertions, 82 deletions
diff --git a/mars.svg b/mars.svg
new file mode 100644
index 0000000..2c35696
--- /dev/null
+++ b/mars.svg
@@ -0,0 +1,4 @@
+<?xml version="1.0" standalone="no"?>
+<svg xmlns="http://www.w3.org/2000/svg" width="50" height="50">
+<path opacity="0.3" fill="none" stroke="#000" stroke-width="3.3" d="m30,21a12.2,12.2 0 1,0 2,2zl1,1 11-11m-9,0h9v9"/>
+</svg>
diff --git a/neptune.svg b/neptune.svg
new file mode 100644
index 0000000..cd47261
--- /dev/null
+++ b/neptune.svg
@@ -0,0 +1,3 @@
+<svg width="50" height="50" version="1.0" xmlns="http://www.w3.org/2000/svg">
+<path d="M15.12 9.15c-2.65 18.03 1.77 20.74 10.62 20.74S39.01 27.18 36.36 9.15m-10.62 1.8V44.31M18.66 37.1H32.82M10.23 11.63l5.02-3.8 3.73 5.12m2.25 2.99 4.38-4.55 4.47 4.45m2.35-2.58 3.8-5.07 4.97 3.87" opacity="0.3" fill="none" stroke="#000" stroke-width="3"/>
+</svg>
diff --git a/play.html b/play.html
index dd5b468..578b0bb 100644
--- a/play.html
+++ b/play.html
@@ -80,6 +80,7 @@
.battle .battle_separator { background-color: brown; }
.battle_line.enemy .battle_menu_list { min-height: 0; }
+.battle_reserves .battle_menu_list { min-height: 0; }
.battle_reserves > td > div { height: 75px; padding: 5px; }
.battle_a_cell > div { min-width: 90px; padding: 5px 5px; }
.battle_b_cell > div { min-width: 270px; padding: 5px 5px; }
@@ -178,6 +179,16 @@ body.shift .block.known:hover {
.columbia-labels .block.r2 { transform: rotate(-180deg); }
.columbia-labels .block.r3 { transform: rotate(-270deg); }
+.block.mars {
+ background-image: url("mars.svg");
+ background-size: 80%;
+ background-position: center;
+}
+.block.neptune {
+ background-image: url("neptune.svg");
+ background-size: 80%;
+ background-position: center;
+}
.block { box-shadow: 0px 0px 4px 0px black; }
diff --git a/rules.js b/rules.js
index 54e33a4..f82928a 100644
--- a/rules.js
+++ b/rules.js
@@ -809,6 +809,7 @@ function start_turn() {
game.active = "Both";
game.state = 'play_card';
game.show_cards = false;
+ game.surprise = 0;
log("");
log("Start Turn ", game.turn, " of Year ", game.year, ".");
}
@@ -1094,6 +1095,41 @@ states.vulcan = {
},
}
+function goto_mars_and_neptune() {
+ game.surprise_list = [];
+ for (let where in SPACES)
+ if (is_map_space(where) && is_contested_space(where))
+ game.surprise_list.push(where);
+ if (game.surprise_list.length == 0) {
+ delete game.surprise_list;
+ return end_player_turn();
+ }
+ if (game.surprise_list.length == 1) {
+ game.surprise = game.surprise_list[0];
+ log("Surprise attack in " + game.surprise + ".");
+ delete game.surprise_list;
+ return end_player_turn();
+ }
+ game.state = 'mars_and_neptune';
+}
+
+states.mars_and_neptune = {
+ prompt: function (view, current) {
+ let god = game.mars == game.active ? "Mars: " : "Neptune: ";
+ if (is_inactive_player(current))
+ return view.prompt = god + ": Waiting for " + game.active + ".";
+ view.prompt = god + "Select battle for surprise attack.";
+ for (let space of game.surprise_list)
+ gen_action(view, 'space', space);
+ },
+ space: function (where) {
+ game.surprise = where;
+ log("Surprise attack in " + game.surprise + ".");
+ delete game.surprise_list;
+ end_player_turn();
+ },
+}
+
function is_amphibious_move(who, from, to) {
if (BLOCKS[who].type == 'navis')
return false;
@@ -1386,10 +1422,10 @@ states.mercury_move_3 = {
function end_movement() {
print_turn_log("moves");
- if (game.pluto == game.active ||
- game.mars == game.active ||
- game.neptune == game.active ||
- game.mercury == game.active)
+ if (game.mars == game.active || game.neptune == game.active)
+ return goto_mars_and_neptune();
+
+ if (game.pluto == game.active || game.mercury == game.active)
return end_player_turn();
game.who = null;
@@ -1500,35 +1536,8 @@ states.pick_battle = {
},
space: function (where) {
game.where = where;
- if (game.mars == game.attacker[where]) {
- game.state = 'use_battle_event';
- } else if (game.neptune == game.attacker[where]) {
- game.state = 'use_battle_event';
- } else {
- start_battle(false);
- }
- },
-}
-
-states.use_battle_event = {
- prompt: function (view, current) {
- if (is_inactive_player(current))
- return view.prompt = "Waiting for " + game.active + " to pick a battle...";
- if (game.mars)
- view.prompt = "Do you want to use the surprise attack granted by Mars?";
- else
- view.prompt = "Do you want to use the surprise attack granted by Neptune?";
- gen_action(view, 'surprise');
- gen_action_pass(view, "No");
+ start_battle();
},
- surprise: function () {
- delete game.mars; /* Used up the event! */
- delete game.neptune; /* Used up the event! */
- start_battle(true);
- },
- pass: function () {
- start_battle(false);
- }
}
function is_attacker(b) {
@@ -1561,12 +1570,11 @@ function count_defenders() {
return count;
}
-function start_battle(surprise) {
- game.surprise = surprise;
+function start_battle() {
game.battle_round = 0;
game.flash = "";
log("");
- if (game.surprise)
+ if (game.surprise == game.where)
log("Surprise attack in ", game.where, ".");
else
log("Battle in ", game.where, ".");
@@ -1609,7 +1617,8 @@ function start_battle_round() {
game.moved = {};
if (game.battle_round == 2) {
- game.surprise = false;
+ if (game.surprise == game.where)
+ game.surprise = 0;
if (count_defenders() == 0) {
log("Defending main force was eliminated.");
log("Defending reserves are disrupted.");
@@ -1664,7 +1673,7 @@ function pump_battle_round() {
let attacker = game.attacker[game.where];
let defender = enemy(attacker);
- if (game.surprise) {
+ if (game.surprise == game.where) {
if (battle_step(attacker, 'A', is_attacker)) return;
if (battle_step(attacker, 'B', is_attacker)) return;
if (battle_step(attacker, 'C', is_attacker)) return;
@@ -1689,6 +1698,8 @@ function pump_battle_round() {
}
function end_battle() {
+ if (game.surprise == game.where)
+ game.surprise = 0;
game.flash = "";
game.battle_round = 0;
reset_road_limits();
@@ -2369,7 +2380,7 @@ function make_battle_view() {
};
bv.title = game.attacker[game.where];
- if (game.surprise && game.battle_round == 1)
+ if (game.surprise == game.where)
bv.title += " surprise attacks ";
else
bv.title += " attacks ";
@@ -2431,6 +2442,15 @@ exports.view = function(state, current) {
if (states[game.state].show_battle)
view.battle = make_battle_view();
+ if (game.mars && game.surprise) {
+ view.mars = game.p1;
+ view.surprise = game.surprise;
+ }
+ if (game.neptune && game.surprise) {
+ view.neptune = game.p1;
+ view.surprise = game.surprise;
+ }
+
for (let b in BLOCKS) {
if (game.state == 'game_over') {
if (game.location[b] != LEVY)
diff --git a/ui.js b/ui.js
index 4629578..362408c 100644
--- a/ui.js
+++ b/ui.js
@@ -454,8 +454,17 @@ function update_map() {
element.classList.remove('moved');
else
element.classList.add('moved');
- element.style.visibility = 'visible';
+ if (color == game.mars && location == game.surprise)
+ element.classList.add("mars");
+ else
+ element.classList.remove("mars");
+ if (color == game.neptune && location == game.surprise)
+ element.classList.add("neptune");
+ else
+ element.classList.remove("neptune");
+
+ element.style.visibility = 'visible';
layout[location].secret.push(element);
}
}
@@ -679,49 +688,6 @@ function on_update() {
for (let b in BLOCKS)
if (!ui.seen.has(b))
ui.battle_steps[b] = 0;
-
- if (game.spaceList) {
- if (game.actionList.includes("secret")) {
- for (let o in ui.secret) {
- for (let s in ui.secret[o]) {
- if (game.spaceList.includes(s)) {
- for (let e of ui.secret[o][s])
- e.classList.add("highlight");
- } else {
- for (let e of ui.secret[o][s])
- e.classList.remove("highlight");
- }
- }
- }
- for (let s in SPACES)
- if (game.spaceList.includes(s))
- ui.spaces[s].classList.remove("highlight");
- } else {
- for (let o in ui.secret)
- for (let s in ui.secret[o])
- for (let e of ui.secret[o][s])
- e.classList.remove("highlight");
- for (let s in SPACES) {
- if (game.spaceList.includes(s))
- ui.spaces[s].classList.add("highlight");
- else
- ui.spaces[s].classList.remove("highlight");
- }
- }
- }
-
- if (game.blockList) {
- for (let b in BLOCKS) {
- if (game.blockList.includes(b))
- ui.known[b].classList.add("highlight");
- else
- ui.known[b].classList.remove("highlight");
- if (b == game.who)
- ui.known[b].classList.add("selected");
- else
- ui.known[b].classList.remove("selected");
- }
- }
}
function select_card(c) {