summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--rules.js46
-rw-r--r--ui.js37
2 files changed, 71 insertions, 12 deletions
diff --git a/rules.js b/rules.js
index bf67092..c37c2f6 100644
--- a/rules.js
+++ b/rules.js
@@ -7,6 +7,7 @@
// TODO: optional rule - force marches
// TODO: strict move order for group moves?
+// Move Phase -> Group Move / Muster / Sea Move -> Move Phase
exports.scenarios = [
"Third Crusade"
@@ -595,6 +596,9 @@ function disband(who) {
}
function eliminate_block(who) {
+ remove_from_array(game.castle, who);
+ if (game.sallying) remove_from_array(game.sallying, who);
+ if (game.storming) remove_from_array(game.storming, who);
if (block_plural(who))
log(block_name(who) + " are eliminated.");
else
@@ -1606,9 +1610,9 @@ states.declare_sally = {
if (n == 0)
log(game.active + " declines to sally.");
else if (n == 1)
- log(game.active + " sallies " + n + "block.");
+ log(game.active + " sallies with 1 block.");
else
- log(game.active + " sallies " + n + "blocks.");
+ log(game.active + " sallies with " + n + " blocks.");
if (is_contested_battle_field()) {
if (!game.was_contested) {
log(game.active + " is now the attacker.");
@@ -1720,7 +1724,24 @@ states.retreat_to = {
function goto_siege_attrition() {
console.log("SIEGE ATTRITION");
- end_combat();
+ game.active = besieging_player(game.where);
+ for (let b in BLOCKS) {
+ if (is_block_in_castle_in(game.where)) {
+ let die = roll_d6();
+ if (die <= 3) {
+ log("Siege attrition: " + DIE_HIT[die] + ".");
+ reduce_block(b);
+ } else {
+ log("Siege attrition: " + DIE_MISS[die] + ".");
+ }
+ }
+ }
+ if (!is_under_siege(game.where)) {
+ log(game.where + " falls to siege attrition.");
+ goto_regroup();
+ } else {
+ end_combat();
+ }
}
// FIELD BATTLE
@@ -1751,14 +1772,14 @@ function resume_field_battle() {
if (is_friendly_field(game.where)) {
console.log("FIELD BATTLE WON BY", game.active);
- log("Field battle won by", game.active);
+ log("Field battle won by " + game.active);
return goto_regroup();
}
if (is_enemy_field(game.where)) {
game.active = ENEMY[game.active];
console.log("FIELD BATTLE WON BY", game.active);
- log("Field battle won by", game.active + ".");
+ log("Field battle won by " + game.active + ".");
return goto_regroup();
}
@@ -1795,7 +1816,7 @@ states.field_battle = {
gen_action(view, 'battle_fire', b);
if (game.sallying.includes(b)) {
// Only sallying forces may withdraw into the castle
- gen_action(view, 'battle_withdraw');
+ gen_action(view, 'battle_withdraw', b);
} else {
if (can_block_retreat(b)) {
gen_action(view, 'battle_retreat', b);
@@ -1966,7 +1987,10 @@ function charge_with_block(b) {
}
function field_withdraw_with_block(b) {
- log(game.active[0] + ": " + b + " withdraws.");
+ if (block_plural(b))
+ log(game.active[0] + ": " + b + " withdraw.");
+ else
+ log(game.active[0] + ": " + b + " withdraws.");
game.moved[b] = true;
remove_from_array(game.sallying, b);
game.castle.push(b);
@@ -2115,6 +2139,12 @@ function setup_game() {
// VIEW
+function compare_block_initiative(a, b) {
+ let aa = BLOCKS[a].combat;
+ let bb = BLOCKS[b].combat;
+ return (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
+}
+
function make_battle_view() {
let battle = {
FA: [], FC: [], FR: [],
@@ -2133,6 +2163,8 @@ function make_battle_view() {
for (let b in BLOCKS)
if (game.location[b] == game.where & block_owner(b) == owner && fn(b))
cell.push([b, game.steps[b], game.moved[b]?1:0])
+ cell.sort((a,b) => compare_block_initiative(a[0], b[0]));
+ console.log("CELL", cell);
}
fill_cell(battle.FR, FRANK, b => is_battle_reserve(b));
diff --git a/ui.js b/ui.js
index 71ca0ce..a0273a6 100644
--- a/ui.js
+++ b/ui.js
@@ -161,6 +161,16 @@ function on_focus_battle_withdraw(evt) {
"Withdraw with " + block_name(evt.target.block);
}
+function on_focus_battle_storm(evt) {
+ document.getElementById("status").textContent =
+ "Storm with " + block_name(evt.target.block);
+}
+
+function on_focus_battle_sally(evt) {
+ document.getElementById("status").textContent =
+ "Sally with " + block_name(evt.target.block);
+}
+
function on_focus_battle_hit(evt) {
document.getElementById("status").textContent =
"Take hit on " + block_name(evt.target.block);
@@ -176,6 +186,8 @@ function on_click_battle_retreat(evt) { send_action('battle_retreat', evt.target
function on_click_battle_charge(evt) { send_action('battle_charge', evt.target.block); }
function on_click_battle_harry(evt) { send_action('battle_harry', evt.target.block); }
function on_click_battle_withdraw(evt) { send_action('battle_withdraw', evt.target.block); }
+function on_click_battle_storm(evt) { send_action('battle_storm', evt.target.block); }
+function on_click_battle_sally(evt) { send_action('battle_sally', evt.target.block); }
function on_click_card(evt) {
let c = evt.target.id.split("+")[1] | 0;
@@ -185,10 +197,12 @@ function on_click_card(evt) {
function on_button_next(evt) { send_action('next'); }
function on_button_pass(evt) { send_action('pass'); }
function on_button_undo(evt) { send_action('undo'); }
+function on_button_group_move(evt) { send_action('group_move'); }
+function on_button_end_group_move(evt) { send_action('end_group_move'); }
function on_button_sea_move(evt) { send_action('sea_move'); }
+function on_button_end_sea_move(evt) { send_action('end_sea_move'); }
function on_button_muster(evt) { send_action('muster'); }
function on_button_end_muster(evt) { send_action('end_muster'); }
-function on_button_end_sea_move(evt) { send_action('end_sea_move'); }
function on_button_end_move_phase(evt) { send_action('end_move_phase'); }
function on_button_end_regroup(evt) { send_action('end_regroup'); }
function on_button_end_retreat(evt) { send_action('end_retreat'); }
@@ -240,6 +254,12 @@ function build_battle_block(b, block) {
build_battle_button(menu_list, b, "withdraw",
on_click_battle_withdraw, on_focus_battle_withdraw,
"/images/stone-tower.svg");
+ build_battle_button(menu_list, b, "storm",
+ on_click_battle_storm, on_focus_battle_storm,
+ "/images/siege-tower.svg");
+ build_battle_button(menu_list, b, "sally",
+ on_click_battle_sally, on_focus_battle_sally,
+ "/images/doorway.svg");
let menu = document.createElement("div");
menu.classList.add("battle_menu");
@@ -585,6 +605,10 @@ function update_battle() {
for (let [block, steps, moved] of list) {
ui.present.add(block);
+ // TODO: insert in correct order!
+ if (!cell.contains(ui.battle_menu[block]))
+ cell.appendChild(ui.battle_menu[block]);
+
if (block == game.who)
ui.battle_block[block].classList.add("selected");
else
@@ -596,6 +620,8 @@ function update_battle() {
ui.battle_menu[block].classList.remove('fire');
ui.battle_menu[block].classList.remove('harry');
ui.battle_menu[block].classList.remove('withdraw');
+ ui.battle_menu[block].classList.remove('storm');
+ ui.battle_menu[block].classList.remove('sally');
ui.battle_menu[block].classList.remove('retreat');
if (game.actions && game.actions.block && game.actions.block.includes(block))
@@ -610,6 +636,10 @@ function update_battle() {
ui.battle_menu[block].classList.add('charge');
if (game.actions && game.actions.battle_withdraw && game.actions.battle_withdraw.includes(block))
ui.battle_menu[block].classList.add('withdraw');
+ if (game.actions && game.actions.battle_storm && game.actions.battle_storm.includes(block))
+ ui.battle_menu[block].classList.add('storm');
+ if (game.actions && game.actions.battle_sally && game.actions.battle_sally.includes(block))
+ ui.battle_menu[block].classList.add('sally');
if (game.actions && game.actions.battle_hit && game.actions.battle_hit.includes(block))
ui.battle_menu[block].classList.add('hit');
if (game.actions && game.actions.battle_charge && game.actions.battle_charge.includes(block))
@@ -633,10 +663,7 @@ function update_battle() {
}
for (let b in BLOCKS) {
- if (ui.present.has(b)) {
- if (!cell.contains(ui.battle_menu[b]))
- cell.appendChild(ui.battle_menu[b]);
- } else {
+ if (!ui.present.has(b)) {
if (cell.contains(ui.battle_menu[b]))
cell.removeChild(ui.battle_menu[b]);
}