diff options
-rw-r--r-- | badges/Cross_of_the_Knights_Templar.svg | 1 | ||||
-rw-r--r-- | badges/Star_and_Crescent.svg | 1 | ||||
-rw-r--r-- | badges/camping-tent.svg | 1 | ||||
-rw-r--r-- | badges/stone-tower.svg | 1 | ||||
-rw-r--r-- | badges/trebuchet.svg | 1 | ||||
-rw-r--r-- | besieged.svg | 1 | ||||
-rw-r--r-- | besieging.svg | 1 | ||||
-rw-r--r-- | jihad-christian.svg | 1 | ||||
-rw-r--r-- | jihad-muslim.svg | 1 | ||||
-rw-r--r-- | play.html | 36 | ||||
-rw-r--r-- | rules.js | 180 | ||||
-rw-r--r-- | ui.js | 18 |
12 files changed, 149 insertions, 94 deletions
diff --git a/badges/Cross_of_the_Knights_Templar.svg b/badges/Cross_of_the_Knights_Templar.svg new file mode 100644 index 0000000..d96e204 --- /dev/null +++ b/badges/Cross_of_the_Knights_Templar.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="600" height="600"><g opacity=".3"><path d="M0 300h600" fill="none" stroke="#000" stroke-width="72"/><path d="M0 216l60 84-60 84zM216 0h168l-84 60z"/><path d="M300 600V0" fill="none" stroke="#000" stroke-width="72"/><path d="M216 600h168l-84-60zm324-300l60 84V216z"/></g></svg>
\ No newline at end of file diff --git a/badges/Star_and_Crescent.svg b/badges/Star_and_Crescent.svg new file mode 100644 index 0000000..e2d7cb9 --- /dev/null +++ b/badges/Star_and_Crescent.svg @@ -0,0 +1 @@ +<svg width="248.87" height="215.85" viewBox="0 0 65.847 57.11" xmlns="http://www.w3.org/2000/svg"><g opacity=".3"><path d="M28.02.53C12.797.82.534 13.264.534 28.553c0 15.47 12.56 28.029 28.03 28.029a27.924 27.924 0 0018.801-7.251 23.821 23.821 0 01-11.906 3.166c-13.21 0-23.928-10.718-23.928-23.928S22.25 4.64 35.46 4.64a23.82 23.82 0 0111.99 3.217A27.922 27.922 0 0028.563.53c-.181 0-.365-.003-.546 0z"/><path d="M65.32 28.57L41.2 36.408l14.906-20.516v25.36L41.201 20.733z"/></g></svg>
\ No newline at end of file diff --git a/badges/camping-tent.svg b/badges/camping-tent.svg new file mode 100644 index 0000000..832d8b8 --- /dev/null +++ b/badges/camping-tent.svg @@ -0,0 +1 @@ +<svg style="height:512px;width:512px" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M361.155 91.245l-18 .193.42 38.98c-45.773 13.285-108.533 19.738-166.474 23.573 35.097 96.284 99.357 173.77 157.845 257.13 20.718-19.655 51.11-31.983 83.46-36.01-20.8-18.109-36.634-27.966-58.833-70.438 31.27 37.085 52.579 48.467 77.623 62.006 3.263-13.094 8.938-24.638 18.721-32.674 8.667-7.12 20.026-10.654 33.53-10.344-46.874-59.763-101.67-117.054-127.83-189.435l-.462-42.98zM163.25 102.92l-17.998.244s.25 18.34.56 36.97c.156 9.316.325 18.703.489 25.929.06 2.636.117 4.58.174 6.542-34.378 83.733-69.154 160.993-123.92 233.442 33.635-1.387 66.326-1.203 98.552-.041C143.37 343.389 144.453 271.151 156.734 204c11.417 68.562 10.566 139.445 33.483 205.83 42.962 3.082 85.69 7.198 129.35 10.926-55.67-79.151-118.213-155.037-155.118-249.365-.05-1.782-.1-3.396-.152-5.737-.162-7.156-.333-16.523-.488-25.82-.31-18.594-.559-36.914-.559-36.914z" opacity=".3"/></svg>
\ No newline at end of file diff --git a/badges/stone-tower.svg b/badges/stone-tower.svg new file mode 100644 index 0000000..7885d8d --- /dev/null +++ b/badges/stone-tower.svg @@ -0,0 +1 @@ +<svg style="height:512px;width:512px" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M71 22.406v102.53h202.25v18.69h-73.22v36.968h-18.686v-36.97H79.156l43.375 53.782h180.44v18.688H180.905v36.97H162.22v-36.97h-39.407v163.562h58.53v-44.75H157.47V316.22h74.155v-33.66H193.72v-18.687h97.218v18.688h-40.625v33.656h73.28v18.686h-32.437v44.75h26.313v18.688h-63.69l-2.686 74.03-18.688-.687 2.656-73.343H93.032V398h-.22l-28.687 92.844h79.844l9.81-70.688 18.5 2.563-9.468 68.124H453.25L424.562 398h-30.03V197.78l51.812-64.25V22.407h-64.406v52.438h-39.22V22.406h-65.124v52.438h-38.53V22.406h-65.126v52.438h-38.5V22.406H71zm129.03 312.5v44.75h72.44v-44.75h-72.44z" fill-opacity=".3"/></svg>
\ No newline at end of file diff --git a/badges/trebuchet.svg b/badges/trebuchet.svg new file mode 100644 index 0000000..aff8da2 --- /dev/null +++ b/badges/trebuchet.svg @@ -0,0 +1 @@ +<svg style="height:512px;width:512px" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M51.984 50.486l-7.968 16.14 11.396 5.626H55V237.85l.977-1.93 7.957-15.647 8.06 15.594c.342.66.667 1.317 1.006 1.977V80.934l216.248 106.742a31.87 31.87 0 00-.248 3.896c0 17.228 13.773 31 31 31 8.558 0 16.26-3.4 21.85-8.93l83.277 41.106-26.832 32.133L454.508 416H480V304l-35.002-41.918 6.986-14.152-101.597-50.15c.4-2.003.613-4.078.613-6.208 0-17.227-13.773-31.002-31-31.002-9.404 0-17.772 4.11-23.44 10.64L51.985 50.487zM282.78 223.34L249.73 279H224v18h15.04L132.386 476.615l-100.375-.11-.02 18 122.53.134 4.376.005L479.99 495l.02-18-18.576-.02L352.99 227.722c-8.722 7.97-20.312 12.847-32.99 12.847-3.074 0-6.08-.3-9-.847V279h-24.05l23.392-39.396c-10.927-2.207-20.56-8.08-27.56-16.264zM329 252.793L340.402 279H329v-26.207zm-265.016 7.172C53.41 280.85 42.212 301.81 27.3 320.367c13.75 18.88 26.382 26.917 36.938 26.996 10.568.08 22.95-7.66 36.49-26.86-15.842-19.27-26.55-40.147-36.744-60.538zM276.26 297H311v179.813l-141.422-.157L276.26 297zm52.74 0h19.232L384 379.21V416h16.006l26.514 60.94-97.52-.106V297z" fill-opacity=".3"/></svg>
\ No newline at end of file diff --git a/besieged.svg b/besieged.svg deleted file mode 100644 index 9328f94..0000000 --- a/besieged.svg +++ /dev/null @@ -1 +0,0 @@ -<svg style="height: 512px; width: 512px;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><g class="" style="" transform="translate(0,0)"><path d="M71 22.406v102.53h202.25v18.69h-73.22v36.968h-18.686v-36.97H79.156l43.375 53.782h180.44v18.688H180.905v36.97H162.22v-36.97h-39.407v163.562h58.53v-44.75H157.47V316.22h74.155V282.56H193.72v-18.687h97.218v18.688h-40.625v33.656h73.28v18.686h-32.437v44.75h26.313v18.688h-63.69l-2.686 74.03-18.688-.687 2.656-73.343H93.032V398h-.22l-28.687 92.844h79.844l9.81-70.688 18.5 2.563-9.468 68.124H453.25L424.562 398h-30.03V197.78l51.812-64.25V22.407h-64.406v52.438h-39.22V22.406h-65.124v52.438h-38.53V22.406h-65.126v52.438h-38.5V22.406H71zm129.03 312.5v44.75h72.44v-44.75h-72.44z" fill="#000" fill-opacity="0.3"></path></g></svg> diff --git a/besieging.svg b/besieging.svg deleted file mode 100644 index 57bb874..0000000 --- a/besieging.svg +++ /dev/null @@ -1 +0,0 @@ -<svg style="height: 512px; width: 512px;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><g class="" style="" transform="translate(0,0)"><path d="M51.984 50.486l-7.968 16.14 11.396 5.626H55V237.85l.977-1.93 7.957-15.647 8.06 15.594c.342.66.667 1.317 1.006 1.977V80.934l216.248 106.742c-.157 1.276-.248 2.575-.248 3.896 0 17.228 13.773 31 31 31 8.558 0 16.26-3.4 21.85-8.93l83.277 41.106-26.832 32.133L454.508 416H480V304l-35.002-41.918 6.986-14.152-101.597-50.15c.4-2.003.613-4.078.613-6.208 0-17.227-13.773-31.002-31-31.002-9.404 0-17.772 4.11-23.44 10.64L51.985 50.487zM282.78 223.34L249.73 279H224v18h15.04L132.386 476.615l-100.375-.11-.02 18 122.53.134 4.376.005L479.99 495l.02-18-18.576-.02L352.99 227.722c-8.722 7.97-20.312 12.847-32.99 12.847-3.074 0-6.08-.3-9-.847V279h-24.05l23.392-39.396c-10.927-2.207-20.56-8.08-27.56-16.264zM329 252.793L340.402 279H329v-26.207zm-265.016 7.172C53.41 280.85 42.212 301.81 27.3 320.367c13.75 18.88 26.382 26.917 36.938 26.996 10.568.08 22.95-7.66 36.49-26.86-15.842-19.27-26.55-40.147-36.744-60.538zM276.26 297H311v179.813l-141.422-.157L276.26 297zm52.74 0h19.232L384 379.21V416h16.006l26.514 60.94-97.52-.106V297z" fill="#000" fill-opacity="0.3"></path></g></svg> diff --git a/jihad-christian.svg b/jihad-christian.svg deleted file mode 100644 index 196101e..0000000 --- a/jihad-christian.svg +++ /dev/null @@ -1 +0,0 @@ -<svg xmlns="http://www.w3.org/2000/svg" width="600" height="600"><g opacity="0.3"><path d="M0 300h600" fill="none" stroke="#000" stroke-width="72"/><path fill="#000" d="M0 216l60 84-60 84zM216 0h168l-84 60z"/><path d="M300 600V0" fill="none" stroke="#000" stroke-width="72"/><path fill="#000" d="M216 600h168l-84-60zM540 300l60 84V216z"/></g></svg> diff --git a/jihad-muslim.svg b/jihad-muslim.svg deleted file mode 100644 index a1538be..0000000 --- a/jihad-muslim.svg +++ /dev/null @@ -1 +0,0 @@ -<svg width="248.87" height="215.85" viewBox="0 0 65.847 57.11" xmlns="http://www.w3.org/2000/svg"><g fill="#000" opacity="0.3"><path d="M28.02.53C12.797.82.534 13.264.534 28.553c0 15.47 12.56 28.029 28.03 28.029a27.924 27.924 0 0018.801-7.251 23.821 23.821 0 01-11.906 3.166c-13.21 0-23.928-10.718-23.928-23.928S22.25 4.64 35.46 4.64a23.82 23.82 0 0111.99 3.217A27.922 27.922 0 0028.563.53c-.181 0-.365-.003-.546 0z"/><path d="M65.32 28.57L41.2 36.408l14.906-20.516v25.36L41.201 20.733z"/></g></svg> @@ -188,35 +188,52 @@ body.shift .block.known:hover { .block.Franks.selected { border-color: gold; } .block.Saracens.selected { border-color: gold; } .block.Assassins.selected { border-color: hotpink; } +.block.Franks.highlight:not(.selected) { box-shadow: 0 0 3px white; } .block.highlight { cursor: pointer; } .block.moved { filter: brightness(80%) grayscale(40%); } .block.highlight.moved { filter: brightness(95%) grayscale(40%); } + .map .block.castle.known { filter: grayscale(50%); } .map.stack_layout .block.castle { filter: grayscale(90%); } -.map .block.castle:not(.known) { - background-image: url("/crusader-rex/besieged.svg"); +.block.castle:not(.known) { + background-image: url("badges/stone-tower.svg"); background-size: 60%; background-position: center; } -.map .block.besieging:not(.known) { - background-image: url("/crusader-rex/besieging.svg"); +.block.besieging:not(.known) { + background-image: url("badges/trebuchet.svg"); + background-size: 60%; + background-position: center; +} +.block.winter_campaign:not(.known) { + background-image: url("badges/camping-tent.svg"); background-size: 60%; background-position: center; } - .block.Franks.jihad { - background-image: url("/crusader-rex/jihad-christian.svg"); + background-image: url("badges/Cross_of_the_Knights_Templar.svg"); background-size: 60%; background-position: center; } .block.Saracen.jihad { - background-image: url("/crusader-rex/jihad-muslim.svg"); + background-image: url("badges/Star_and_Crescent.svg"); background-size: 60%; background-position: center; } +.block.besieging.Franks.jihad:not(.known) { + background-image: url("badges/trebuchet.svg"), url("badges/Cross_of_the_Knights_Templar.svg"); + background-size: 60%, 40%; + background-position: 30% 80%, 85% 15%; +} +.block.besieging.Saracens.jihad:not(.known) { + background-image: url("badges/trebuchet.svg"), url("badges/Star_and_Crescent.svg"); + background-size: 60%, 40%; + background-position: 30% 80%, 85% 15%; +} + .block.r0 { transform: rotate(0deg); } .block.r1 { transform: rotate(-90deg); } .block.r2 { transform: rotate(-180deg); } @@ -398,10 +415,11 @@ body.shift .block.known:hover { <div id="prompt" class="prompt">$PROMPT</div> <button id="eliminate_button" class="hide" onclick="on_button_eliminate()">Eliminate</button> - <button id="group_move_button" class="hide" onclick="on_button_group_move()">Group move</button> - <button id="end_group_move_button" class="hide" onclick="on_button_end_group_move()">End group move</button> + <button id="winter_campaign_button" class="hide" onclick="on_button_winter_campaign()">Winter campaign</button> <button id="sea_move_button" class="hide" onclick="on_button_sea_move()">Sea move</button> <button id="end_sea_move_button" class="hide" onclick="on_button_end_sea_move()">End sea move</button> + <button id="group_move_button" class="hide" onclick="on_button_group_move()">Group move</button> + <button id="end_group_move_button" class="hide" onclick="on_button_end_group_move()">End group move</button> <button id="muster_button" class="hide" onclick="on_button_muster()">Muster</button> <button id="end_muster_button" class="hide" onclick="on_button_end_muster()">End muster</button> <button id="end_retreat_button" class="hide" onclick="on_button_end_retreat()">End retreat</button> @@ -3,9 +3,10 @@ // TODO: optional rule - iron bridge // TODO: optional rule - force marches -// TODO: can sea move into fortified port that is under attack but not yet besieged? -// TODO: pause after battle ends to show final result/action +// TODO: can sea move into fortified port that is under attack but not yet besieged? no... +// TODO: pause after battle ends to show final result/action? // TODO: optional retreat after combat round 3 if storming +// TODO: new combat deployment in round 2/3 if defenders are wiped out? maybe... exports.scenarios = [ "Third Crusade" @@ -256,9 +257,14 @@ function list_seats(who) { if (is_saladin_family(who)) who = SALADIN; switch (block_type(who)) { - case 'nomads': return [ block_home(who) ]; - case 'turcopoles': who = "Turcopoles"; break; - case 'military_orders': who = BLOCKS[who].name; break; + case 'nomads': + return [ block_home(who) ]; + case 'turcopoles': + who = "Turcopoles"; + break; + case 'military_orders': + who = BLOCKS[who].name; + break; } let list = []; for (let town in SHIELDS) @@ -271,9 +277,14 @@ function is_home_seat(where, who) { if (is_saladin_family(who)) who = SALADIN; switch (block_type(who)) { - case 'nomads': return [ block_home(who) ]; - case 'turcopoles': who = "Turcopoles"; break; - case 'military_orders': who = BLOCKS[who].name; break; + case 'nomads': + return where == block_home(who); + case 'turcopoles': + who = "Turcopoles"; + break; + case 'military_orders': + who = BLOCKS[who].name; + break; } for (let town in SHIELDS) if (SHIELDS[town].includes(who)) @@ -482,6 +493,9 @@ function is_friendly_or_vacant_town(where) { function is_contested_or_enemy_town(where) { return is_contested_town(where) || is_enemy_town(where); } +function is_enemy_occupied_town(where) { + return count_enemy(where) > 0; +} /* Field queries exclude castles. */ function is_friendly_field(where) { @@ -675,8 +689,8 @@ function can_block_land_move(who) { 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_contested_or_enemy_town(to)) { - if (is_english_crusader(who)) { + if (is_english_crusader(who)) { + if (is_enemy_field(to)) { if (!game.attacker[to]) return true; if (game.attacker[to] == FRANKS) @@ -787,7 +801,7 @@ function can_block_retreat(who) { function can_block_regroup_to(who, to) { // regroup during winter campaign - if (is_winter() && is_contested_or_enemy_town(to)) + if (is_winter() && is_enemy_occupied_town(to)) return false; if (is_friendly_field(to) || is_vacant_town(to)) { let from = game.location[who]; @@ -1028,7 +1042,7 @@ states.saracen_deployment = { start_year(); }, pass: function () { - game.who = SALADIN; + game.who = null; start_year(); } } @@ -1477,6 +1491,11 @@ function end_move_phase() { game.who = null; game.where = null; game.moves = 0; + + // declined to use winter campaign + if (game.winter_campaign == game.active) + delete game.winter_campaign; + if (game.active == game.jihad) goto_select_jihad(); else @@ -1484,18 +1503,18 @@ function end_move_phase() { } function format_moves(phase, prompt) { - if (game.moves == 0) - return phase + "No moves left."; - if (game.moves == 1) - return phase + prompt + " \u2014 1 move left."; - return phase + prompt + " \u2014 " + game.moves + " moves left."; } states.move_phase = { prompt: function (view, current) { if (is_inactive_player(current)) return view.prompt = "Move Phase: Waiting for " + game.active + "."; - view.prompt = format_moves("Move Phase: ", "Group Move, Sea Move, or Muster"); + if (game.moves == 0) + view.prompt = "Move Phase: No moves left."; + else if (game.moves == 1) + view.prompt = "Move Phase: 1 move left."; + else + view.prompt = "Move Phase: " + game.moves + " moves left."; gen_action_undo(view); gen_action(view, 'end_move_phase'); if (game.moves > 0) { @@ -1504,8 +1523,15 @@ states.move_phase = { gen_action(view, 'sea_move'); if (can_muster_anywhere()) gen_action(view, 'muster'); + if (game.winter_campaign == game.active) + gen_action(view, 'winter_campaign'); } }, + winter_campaign: function () { + push_undo(); + --game.moves; + game.state = 'winter_campaign'; + }, group_move: function () { push_undo(); --game.moves; @@ -1604,13 +1630,13 @@ states.group_move_to = { let from = game.location[game.who]; if (game.distance > 0) { // cannot start or reinforce battles in winter - if (!(is_winter() && is_contested_or_enemy_town(from))) + if (!(is_winter() && is_enemy_occupied_town(from))) gen_action(view, 'town', from); } for (let to of TOWNS[from].exits) { if (to != game.last_from && can_block_land_move_to(game.who, from, to)) { // cannot start or reinforce battles in winter - if (is_winter() && is_contested_or_enemy_town(to)) { + if (is_winter() && is_enemy_occupied_town(to)) { // but can move through friendly sieges if (!is_friendly_field(to)) continue; @@ -1666,7 +1692,7 @@ states.sea_move = { prompt: function (view, current) { if (is_inactive_player(current)) return view.prompt = "Move Phase: Waiting for " + game.active + "."; - view.prompt = format_moves("Sea Move: ", "Choose a block to sea move"); + view.prompt = "Sea Move: Choose a block to move."; gen_action_undo(view); for (let b in BLOCKS) if (can_block_sea_move(b)) @@ -1756,7 +1782,7 @@ states.muster = { prompt: function (view, current) { if (is_inactive_player(current)) return view.prompt = "Move Phase: Waiting for " + game.active + "."; - view.prompt = "Muster: Choose one friendly or vacant muster town."; + view.prompt = "Muster: Choose a friendly muster town."; gen_action_undo(view); for (let where in TOWNS) { // cannot start or reinforce battles in winter @@ -1918,6 +1944,26 @@ function end_muster_move() { game.state = 'muster_who'; } +// WINTER CAMPAIGN + +states.winter_campaign = { + prompt: function (view, current) { + if (is_inactive_player(current)) + return view.prompt = "Move Phase: Waiting for " + game.active + "."; + view.prompt = "Winter Campaign: Select a siege to maintain over the winter."; + gen_action_undo(view); + for (let town in TOWNS) + if (is_friendly_field(town) && is_under_siege(town)) + gen_action(view, 'town', town); + }, + town: function (where) { + log(game.active + " winter campaign in " + where + "."); + game.winter_campaign = where; + game.state = 'move_phase'; + }, + undo: pop_undo +} + // COMBAT PHASE function goto_combat_phase() { @@ -2094,7 +2140,7 @@ states.regroup = { clear_undo(); print_summary(game.active + " regroup:"); if (is_winter()) - end_winter_campaign(); + goto_winter_2(); else if (is_contested_town(game.where)) next_combat_round(); else @@ -3008,10 +3054,10 @@ states.draw_phase = { town: function (where) { let type = block_type(game.who); - log(game.active + " arrive in " + where + "."); + log(game.active + " draw to " + where + "."); game.location[game.who] = where; - if ((type == 'outremers' || type == 'emirs' || type == 'nomads') && is_home_seat(where, game.who)); + if ((type == 'outremers' || type == 'emirs' || type == 'nomads') && is_home_seat(where, game.who)) game.steps[game.who] = 1; else game.steps[game.who] = block_max_steps(game.who); @@ -3035,7 +3081,7 @@ function end_draw_phase() { function end_game_turn() { if (is_winter()) { - goto_winter_campaign(); + goto_winter_1(); } else { if (check_sudden_death()) return; @@ -3044,64 +3090,45 @@ function end_game_turn() { } } -// WINTER CAMPAIGN +// WINTER SUPPLY -function goto_winter_campaign() { +function goto_winter_1() { log(""); - if (game.winter_campaign) { - log("Start Winter Campaign."); - game.active = game.winter_campaign; - game.state = 'winter_campaign'; - } else { - log("Start Winter."); - end_winter_campaign(); - } + log("Start Winter of " + game.year + "."); + if (game.winter_campaign) + winter_siege_attrition(); + else + goto_winter_2(); } -states.winter_campaign = { - prompt: function (view, current) { - if (is_inactive_player(current)) - return view.prompt = "Winter Campaign: Waiting for " + game.active + "."; - view.prompt = "Winter Campaign: Select a siege to maintain over the winter."; - gen_action(view, 'pass'); - for (let town in TOWNS) - if (is_friendly_field(town) && is_under_siege(town)) - gen_action(view, 'town', town); - }, - town: function (where) { - log(game.active + " maintain siege of " + where + "."); - game.winter_campaign = where; - game.where = where; +function winter_siege_attrition() { + log(game.active + " winter campaign in " + game.winter_campaign + "."); + game.where = game.winter_campaign; - let target = (game.where == TYRE || game.where == TRIPOLI) ? 2 : 4; - for (let b in BLOCKS) { - if (is_block_in_castle_in(b, game.where)) { - let die = roll_d6(); - if (die <= target) { - log("Attrition roll " + DIE_HIT[die] + "."); - reduce_block(b); - } else { - log("Attrition roll " + DIE_MISS[die] + "."); - } + let target = (game.where == TYRE || game.where == TRIPOLI) ? 2 : 4; + for (let b in BLOCKS) { + if (is_block_in_castle_in(b, game.where)) { + let die = roll_d6(); + if (die <= target) { + log("Attrition roll " + DIE_HIT[die] + "."); + reduce_block(b); + } else { + log("Attrition roll " + DIE_MISS[die] + "."); } } + } - if (!is_under_siege(game.where)) { - log(game.where + " falls to siege attrition."); - goto_regroup(); - } else { - log("Siege continues."); - end_winter_campaign(); - } - }, - pass: function () { - log(game.active + " decline to winter campaign."); - game.winter_campaign = null; - end_winter_campaign(); - }, + if (!is_under_siege(game.where)) { + log(game.where + " falls to siege attrition."); + goto_regroup(); + } else { + log("Siege continues."); + game.where = null; + goto_winter_2(); + } } -function end_winter_campaign() { +function goto_winter_2() { eliminate_besieging_blocks(FRANKS); eliminate_besieging_blocks(SARACENS); lift_all_sieges(); @@ -3128,8 +3155,6 @@ function eliminate_besieging_blocks(owner) { game.summary = null; } -// WINTER SUPPLY - function need_winter_supply_check() { for (let town in TOWNS) { if (town == game.winter_campaign) @@ -3468,6 +3493,7 @@ exports.view = function(state, current) { year: game.year, turn: game.turn, active: game.active, + p1: game.p1, f_vp: game.f_vp, s_vp: game.s_vp, f_card: (game.show_cards || current == FRANKS) ? game.f_card : 0, @@ -3487,6 +3513,8 @@ exports.view = function(state, current) { if (game.jihad && game.jihad != game.p1) view.jihad = game.jihad; + if (game.winter_campaign && game.winter_campaign != game.p1 && game.winter_campaign != game.p2) + view.winter_campaign = game.winter_campaign; states[game.state].prompt(view, current); @@ -226,6 +226,7 @@ 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_winter_campaign(evt) { send_action('winter_campaign'); } 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'); } @@ -590,8 +591,16 @@ function update_map() { known = ""; element.classList = info.owner + known + " block" + image + steps + moved; } else { - let besieging = (game.sieges[town] == info.owner) ? " besieging" : ""; - let jihad = (game.jihad == town) ? " jihad" : ""; + let besieging = ""; + if (game.sieges[town] == info.owner) { + if (game.winter_campaign == town) + besieging = " winter_campaign"; + else + besieging = " besieging"; + } + let jihad = ""; + if (game.jihad == town && info.owner == game.p1) + jihad = " jihad"; element.classList = info.owner + " block" + moved + besieging + jihad; } if (info.owner == FRANKS) @@ -626,10 +635,8 @@ function update_map() { if (game.who) ui.blocks[game.who].classList.add('selected'); } - for (let b of game.castle) { + for (let b of game.castle) ui.blocks[b].classList.add('castle'); - ui.battle_block[b].classList.add('castle'); - } } function update_card_display(element, card, prior_card) { @@ -790,6 +797,7 @@ function on_update() { show_action_button("#next_button", "next"); show_action_button("#pass_button", "pass"); show_action_button("#undo_button", "undo"); + show_action_button("#winter_campaign_button", "winter_campaign"); show_action_button("#group_move_button", "group_move"); show_action_button("#end_group_move_button", "end_group_move"); show_action_button("#sea_move_button", "sea_move"); |