summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--play.html33
-rw-r--r--rules.js109
-rw-r--r--ui.js26
3 files changed, 94 insertions, 74 deletions
diff --git a/play.html b/play.html
index c444ac3..18c1dec 100644
--- a/play.html
+++ b/play.html
@@ -227,21 +227,32 @@ body.shift .block.known:hover {
/* BATTLE BOARD */
-.battle { background-color: darkgray; }
+.battle { background-color: tan; }
.battle .battle_message { background-color: gainsboro; }
.battle .battle_header { background-color: #224467; color: white; font-weight: bold; }
-.battle .battle_separator { background-color: #224467; }
-.battle_line.enemy .battle_menu_list { min-height: 0; }
-.battle_line > td > div { min-width: 800px; }
+#EC .battle_menu_list { min-height: 0; }
+.battle_line > td { min-width: 800px; }
.battle td { border: none; }
#FA, #FB, #FC, #FD, #FR, #EA, #EB, #EC, #ER { margin: 0px; padding: 5px; }
.battle .battle_menu { margin: 10px 5px; }
-#FR, #ER { background-color: mediumseagreen; }
-#FA, #EA { background-color: darkseagreen; }
-#FB, #EB { background-color: darkgray; }
-#FC, #EC { background-color: gray; }
+#FC { min-height: 110px; }
+#EC { min-height: 80px; }
+#FC, #EC {
+ background-color: gray;
+ margin-left: auto;
+ margin-right: auto;
+ border-top: 5px dashed tan;
+}
+#FC.c0, #EC.c0 { display: none; }
+#FC.c1, #EC.c1 { width: 90px; display: block; }
+#FC.c2, #EC.c2 { width: 180px; display: block; }
+#FC.c3, #EC.c3 { width: 270px; display: block; }
+#FC.c4, #EC.c4 { width: 360px; display: block; }
+
+#ER { background-image: linear-gradient(to bottom, skyblue, tan); min-height: 40px; }
+#FR { background-image: linear-gradient(to bottom, tan, darkseagreen); min-height: 40px; }
/* CARD AND BLOCK IMAGES */
@@ -337,10 +348,8 @@ body.shift .block.known:hover {
<th class="battle_header" colspan=4></th>
<tr class="battle_reserves enemy"><td><div id="ER"></div></td>
<tr class="battle_line enemy"><td><div id="EC"></div></td>
-<tr class="battle_line enemy"><td><div id="EB"></div></td>
-<tr class="battle_line enemy"><td><div id="EA"></div></td>
-<tr class="battle_line friendly"><td><div id="FA"></div></td>
-<tr class="battle_line friendly"><td><div id="FB"></div></td>
+<tr class="battle_line enemy"><td><div id="EF"></div></td>
+<tr class="battle_line friendly"><td><div id="FF"></div></td>
<tr class="battle_line friendly"><td><div id="FC"></div></td>
<tr class="battle_reserves friendly"><td><div id="FR"></div></td>
<tr>
diff --git a/rules.js b/rules.js
index ea87a10..0ea4fb8 100644
--- a/rules.js
+++ b/rules.js
@@ -23,8 +23,8 @@ exports.scenarios = [
const { CARDS, BLOCKS, TOWNS, PORTS, ROADS } = require('./data');
-const FRANK = "Franks";
-const SARACEN = "Saracens";
+const FRANKS = "Franks";
+const SARACENS = "Saracens";
const ASSASSINS = "Assassins";
const ENEMY = { Franks: "Saracens", Saracens: "Franks" };
const OBSERVER = "Observer";
@@ -215,7 +215,7 @@ function block_home(who) {
}
function block_pool(who) {
- if (BLOCKS[who].owner == FRANK)
+ if (BLOCKS[who].owner == FRANKS)
return F_POOL;
return S_POOL;
}
@@ -446,7 +446,7 @@ function can_use_richards_sea_legs(who, to) {
// English Crusaders may attack by sea.
// If combined with another attack, the English must be the Main Attacker.
if (is_english_crusader(who)) {
- if (game.attacker[to] == FRANK) {
+ if (game.attacker[to] == FRANKS) {
let road = game.main_road[to];
if (road)
return (road == "England");
@@ -671,6 +671,10 @@ function is_field_combatant(who) {
return false;
}
+function is_block_in_field(who) {
+ return !is_battle_reserve(who) && !is_block_in_castle(who);
+}
+
function is_storm_attacker(who) {
return game.storming.includes(who);
}
@@ -860,7 +864,7 @@ states.play_card = {
prompt: function (view, current) {
if (is_inactive_player(current))
return view.prompt = "Waiting for players to play a card.";
- if (current == FRANK) {
+ if (current == FRANKS) {
view.prior_s_card = game.prior_s_card;
if (game.f_card) {
view.prompt = "Waiting for Saracens to play a card.";
@@ -872,7 +876,7 @@ states.play_card = {
gen_action(view, 'play', c);
}
}
- if (current == SARACEN) {
+ if (current == SARACENS) {
view.prior_f_card = game.prior_f_card;
if (game.s_card) {
view.prompt = "Waiting for Franks to play a card.";
@@ -886,11 +890,11 @@ states.play_card = {
}
},
play: function (card, current) {
- if (current == FRANK) {
+ if (current == FRANKS) {
remove_from_array(game.f_hand, card);
game.f_card = card;
}
- if (current == SARACEN) {
+ if (current == SARACENS) {
remove_from_array(game.s_hand, card);
game.s_card = card;
}
@@ -898,11 +902,11 @@ states.play_card = {
reveal_cards();
},
undo: function (_, current) {
- if (current == FRANK) {
+ if (current == FRANKS) {
game.f_hand.push(game.f_card);
game.f_card = 0;
}
- if (current == SARACEN) {
+ if (current == SARACENS) {
game.s_hand.push(game.s_card);
game.s_card = 0;
}
@@ -937,9 +941,9 @@ function reveal_cards() {
delete game.winter_campaign;
if (is_winter()) {
if (game.f_card == WINTER_CAMPAIGN)
- game.winter_campaign = FRANK;
+ game.winter_campaign = FRANKS;
if (game.s_card == WINTER_CAMPAIGN)
- game.winter_campaign = SARACEN;
+ game.winter_campaign = SARACENS;
}
game.prior_f_card = game.f_card;
@@ -958,11 +962,11 @@ function reveal_cards() {
}
if (fp > sp) {
- game.p1 = FRANK;
- game.p2 = SARACEN;
+ game.p1 = FRANKS;
+ game.p2 = SARACENS;
} else {
- game.p1 = SARACEN;
- game.p2 = FRANK;
+ game.p1 = SARACENS;
+ game.p2 = FRANKS;
}
game.active = game.p1;
@@ -973,7 +977,7 @@ function start_player_turn() {
log("");
log("Start " + game.active + " turn.");
reset_road_limits();
- let card = CARDS[game.active == FRANK ? game.f_card : game.s_card];
+ let card = CARDS[game.active == FRANKS ? game.f_card : game.s_card];
if (card.event)
goto_event_card(card.event);
else
@@ -1381,7 +1385,7 @@ states.sea_move_to = {
} else if (!is_friendly_port(to)) {
// English Crusaders attack!
- game.attacker[to] = FRANK;
+ game.attacker[to] = FRANKS;
game.main_road[to] = "England";
log(game.active + " sea move:\n" + from + " \u2192 " + to + ATTACK_MARK + ".");
@@ -1826,12 +1830,12 @@ function goto_combat_round(combat_round) {
console.log("STORMING CANCELED");
game.storming.length = 0;
}
- }
- let old_attacker = game.attacker[game.where];
- game.attacker[game.where] = besieged_player(game.where);
- if (old_attacker != game.attacker[game.where]) {
- console.log("NEW ATTACKER IS", game.attacker[game.where]);
- log(game.attacker[game.where] + " are now the attacker.");
+ let old_attacker = game.attacker[game.where];
+ game.attacker[game.where] = besieged_player(game.where);
+ if (old_attacker != game.attacker[game.where]) {
+ console.log("NEW ATTACKER IS", game.attacker[game.where]);
+ log(game.attacker[game.where] + " are now the attacker.");
+ }
}
return goto_declare_sally();
}
@@ -2182,7 +2186,7 @@ states.field_battle = {
}
}
// All Frank B blocks are knights who can Charge
- if (block_owner(b) == FRANK && block_initiative(b) == 'B')
+ if (block_owner(b) == FRANKS && block_initiative(b) == 'B')
gen_action(view, 'battle_charge', b);
}
},
@@ -2197,12 +2201,13 @@ states.field_battle = {
// STORM BATTLE
function goto_storm_battle() {
- console.log("STORM BATTLE");
+ game.attacker[game.where] = besieging_player(game.where);
+ console.log("STORM BATTLE", game.attacker[game.where]);
resume_storm_battle();
}
function resume_storm_battle() {
- game.active = besieging_player(game.where);
+ game.active = game.attacker[game.where];
if (is_friendly_town(game.where)) {
console.log("STORM BATTLE WON BY ATTACKER", game.active);
@@ -2351,14 +2356,15 @@ function apply_storm_battle_hit(who) {
}
game.hits--;
- if (game.hits == 0)
+ if (game.hits == 0) {
resume_storm_battle();
- else {
+ } else {
game.battle_list = list_storm_victims();
- if (game.battle_list.length == 0)
+ if (game.battle_list.length == 0) {
resume_storm_battle();
- else
+ } else {
game.flash += " " + game.hits + (game.hits == 1 ? " hit left." : " hits left.");
+ }
}
}
@@ -2592,7 +2598,7 @@ function setup_game() {
reset_blocks();
game.year = 1187;
for (let b in BLOCKS) {
- if (block_owner(b) == FRANK) {
+ if (block_owner(b) == FRANKS) {
switch (block_type(b)) {
case 'pilgrims':
case 'crusaders':
@@ -2603,7 +2609,7 @@ function setup_game() {
break;
}
}
- if (block_owner(b) == SARACEN) {
+ if (block_owner(b) == SARACENS) {
if (block_type(b) == 'emirs')
deploy(b, block_home(b));
if (block_type(b) == 'nomads')
@@ -2624,13 +2630,19 @@ function compare_block_initiative(a, b) {
}
function make_battle_view() {
+ let castle_owner = besieged_player(game.where);
+ if (!castle_owner)
+ castle_owner = ENEMY[game.attacker[game.where]];
+
let battle = {
- FA: [], FB: [], FC: [], FR: [],
- SA: [], SB: [], SC: [], SR: [],
+ FR: [], FC: [], FF: [],
+ SR: [], SC: [], SF: [],
+ FCS: (castle_owner == FRANKS) ? castle_limit(game.where) : 0,
+ SCS: (castle_owner == SARACENS) ? castle_limit(game.where) : 0,
storming: game.storming,
sallying: game.sallying,
halfhit: game.halfhit,
- flash: game.flash
+ flash: game.flash,
};
battle.title = game.attacker[game.where] + " attack " + game.where;
@@ -2642,18 +2654,17 @@ 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]));
+ // cell.sort((a,b) => compare_block_initiative(a[0], b[0]));
}
- fill_cell(battle.FA, FRANK, b => !is_battle_reserve(b) && !is_block_in_castle(b) && game.storming.includes(b));
- fill_cell(battle.FB, FRANK, b => !is_battle_reserve(b) && !is_block_in_castle(b) && !game.storming.includes(b));
- fill_cell(battle.FC, FRANK, b => !is_battle_reserve(b) && is_block_in_castle(b));
- fill_cell(battle.FR, FRANK, b => is_battle_reserve(b));
-
- fill_cell(battle.SA, SARACEN, b => !is_battle_reserve(b) && !is_block_in_castle(b) && game.storming.includes(b));
- fill_cell(battle.SB, SARACEN, b => !is_battle_reserve(b) && !is_block_in_castle(b) && !game.storming.includes(b));
- fill_cell(battle.SC, SARACEN, b => !is_battle_reserve(b) && is_block_in_castle(b));
- fill_cell(battle.SR, SARACEN, b => is_battle_reserve(b));
+ fill_cell(battle.FR, FRANKS, b => is_battle_reserve(b));
+ fill_cell(battle.FC, FRANKS, b => is_block_in_castle(b));
+ fill_cell(battle.FF, FRANKS, b => is_block_in_field(b) && !game.storming.includes(b));
+ fill_cell(battle.FF, SARACENS, b => is_block_in_field(b) && game.storming.includes(b));
+ fill_cell(battle.SF, FRANKS, b => is_block_in_field(b) && game.storming.includes(b));
+ fill_cell(battle.SF, SARACENS, b => is_block_in_field(b) && !game.storming.includes(b));
+ fill_cell(battle.SC, SARACENS, b => is_block_in_castle(b));
+ fill_cell(battle.SR, SARACENS, b => is_battle_reserve(b));
return battle;
}
@@ -2729,9 +2740,9 @@ exports.view = function(state, current) {
year: game.year,
turn: game.turn,
active: game.active,
- f_card: (game.show_cards || current == FRANK) ? game.f_card : 0,
- s_card: (game.show_cards || current == SARACEN) ? game.s_card : 0,
- hand: (current == FRANK) ? game.f_hand : (current == SARACEN) ? game.s_hand : [],
+ f_card: (game.show_cards || current == FRANKS) ? game.f_card : 0,
+ s_card: (game.show_cards || current == SARACENS) ? game.s_card : 0,
+ hand: (current == FRANKS) ? game.f_hand : (current == SARACENS) ? game.s_hand : [],
who: (game.active == current) ? game.who : null,
location: game.location,
castle: game.castle,
diff --git a/ui.js b/ui.js
index c0c0ee4..b6125ad 100644
--- a/ui.js
+++ b/ui.js
@@ -1,7 +1,7 @@
"use strict";
-const FRANK = "Franks";
-const SARACEN = "Saracens";
+const FRANKS = "Franks";
+const SARACENS = "Saracens";
const ASSASSINS = "Assassins";
const ENEMY = { Saracens: "Franks", Franks: "Saracens" }
const DEAD = "Dead";
@@ -379,7 +379,7 @@ function layout_blocks_spread(town, north, south) {
let wrap = TOWNS[town].wrap;
let rows = [];
- if (north.length + south.length > wrap * 3) {
+ if (north.length + south.length > wrap * 2) {
north = north.concat(south);
south = [];
}
@@ -616,7 +616,7 @@ function update_cards() {
function update_battle() {
function fill_cell(name, list, reserve) {
- let cell = window[name];
+ let cell = document.getElementById(name);
ui.present.clear();
@@ -693,24 +693,24 @@ function update_battle() {
}
}
- if (player == FRANK) {
+ if (player == FRANKS) {
fill_cell("FR", game.battle.FR, true);
- fill_cell("FA", game.battle.FA, false);
- fill_cell("FB", game.battle.FB, false);
fill_cell("FC", game.battle.FC, false);
- fill_cell("EA", game.battle.SA, false);
- fill_cell("EB", game.battle.SB, false);
+ fill_cell("FF", game.battle.FF, false);
+ fill_cell("EF", game.battle.SF, false);
fill_cell("EC", game.battle.SC, false);
fill_cell("ER", game.battle.SR, true);
+ document.getElementById("FC").className = "c" + game.battle.FCS;
+ document.getElementById("EC").className = "c" + game.battle.SCS;
} else {
fill_cell("ER", game.battle.FR, true);
- fill_cell("EA", game.battle.FA, false);
- fill_cell("EB", game.battle.FB, false);
fill_cell("EC", game.battle.FC, false);
- fill_cell("FA", game.battle.SA, false);
- fill_cell("FB", game.battle.SB, false);
+ fill_cell("EF", game.battle.FF, false);
+ fill_cell("FF", game.battle.SF, false);
fill_cell("FC", game.battle.SC, false);
fill_cell("FR", game.battle.SR, true);
+ document.getElementById("EC").className = "c" + game.battle.FCS;
+ document.getElementById("FC").className = "c" + game.battle.SCS;
}
}