diff options
-rw-r--r-- | about.html | 3 | ||||
-rw-r--r-- | rules.js | 188 |
2 files changed, 110 insertions, 81 deletions
@@ -9,7 +9,8 @@ important Victory Cities such as Jerusalem, Acre, Damascus, and Antioch. Designer: Jerry Taylor and Tom Dalgliesh. <p> -Publisher: <a href="https://columbiagames.com/cgi-bin/query/cfg/zoom.cfg?product_id=3151">Columbia Games</a>. +Copyright © 2005-2011 +<a href="https://columbiagames.com/cgi-bin/query/cfg/zoom.cfg?product_id=3151">Columbia Games</a>. <ul> <li><a href="/crusader-rex/info/rules.html">Rulebook</a> @@ -3,9 +3,8 @@ // 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? 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 and reserves are coming? // see https://boardgamegeek.com/thread/423599/article/3731006 @@ -705,6 +704,30 @@ function can_block_land_move_to(who, from, to) { return false; } +function can_germans_move(who) { + let from = game.location[who]; + if (from == GERMANIA) { + if (can_activate(who)) { + for (let to of GERMAN_ROADS) + if (can_germans_move_to(who, to)) + return true; + } + } + return false; +} + +function can_germans_move_to(who, to) { + if (is_winter() && is_enemy_occupied_town(to)) + return false; + if (to == ALEPPO) + return true; + if (to == ANTIOCH) + return true; + if (to == ST_SIMEON) + return road_limit(GERMANIA, ST_SIMEON) < 2; + return false; +} + function can_block_land_move(who) { if (can_activate(who)) { let from = game.location[who]; @@ -715,11 +738,6 @@ function can_block_land_move(who) { if (can_block_land_move_to(who, from, to)) return true; } - if (from == GERMANIA) { - for (let to of GERMAN_ROADS) - if (can_block_land_move_to(who, from, to)) - return true; - } } return false; } @@ -1118,23 +1136,15 @@ function count_victory_points() { game.f_vp = 0; game.active = FRANKS; - for (let town of VICTORY_TOWNS) { - if (is_friendly_town_for_vp(town)) { - console.log("VP", town, "friendly", game.active); + for (let town of VICTORY_TOWNS) + if (is_friendly_town_for_vp(town)) ++ game.f_vp; - } else - console.log("VP", town, "enemy", game.active); - } game.s_vp = 0; game.active = SARACENS; - for (let town of VICTORY_TOWNS) { - if (is_friendly_town_for_vp(town)) { - console.log("VP", town, "friendly", game.active); + for (let town of VICTORY_TOWNS) + if (is_friendly_town_for_vp(town)) ++ game.s_vp; - } else - console.log("VP", town, "enemy", game.active); - } game.active = save_active; } @@ -1419,13 +1429,13 @@ function assassinate(who, where) { function goto_guide() { game.guide = game.active; - game.state = 'group_move_first'; + game.state = 'move_phase_event'; game.summary = []; } function goto_jihad() { game.jihad = game.active; - game.state = 'group_move_first'; + game.state = 'move_phase_event'; game.summary = []; } @@ -1590,9 +1600,12 @@ states.move_phase = { gen_action_undo(view); gen_action(view, 'end_move_phase'); if (game.moves > 0) { - let sea_moves_allowed = (game.active != game.guide && game.active != game.jihad); for (let b in BLOCKS) { - if (can_block_land_move(b) || (sea_moves_allowed && can_block_sea_move(b))) + if (can_block_land_move(b)) + gen_action(view, 'block', b); + if (can_block_sea_move(b)) + gen_action(view, 'block', b); + if (can_germans_move(b)) gen_action(view, 'block', b); } if (can_muster_anywhere()) @@ -1616,7 +1629,9 @@ states.move_phase = { push_undo(); game.who = who; game.where = game.location[who]; - if (game.where == GERMANIA || game.where == FRANCE || game.where == ENGLAND) { + if (game.where == GERMANIA) { + game.state = 'german_move_to'; + } else if (game.where == FRANCE || game.where == ENGLAND) { game.state = 'sea_move_to'; } else { game.state = 'move_phase_to'; @@ -1626,6 +1641,29 @@ states.move_phase = { undo: pop_undo } +states.move_phase_event = { + prompt: function (view, current) { + if (is_inactive_player(current)) + return view.prompt = group_move_name(1) + "Waiting for " + game.active + "."; + view.prompt = group_move_name(0) + "Choose a block to group move."; + gen_action_undo(view); + gen_action(view, 'end_move_phase'); + for (let b in BLOCKS) + if (can_block_land_move(b)) + gen_action(view, 'block', b); + }, + block: function (who) { + push_undo(); + game.where = game.location[who]; + game.who = who; + game.distance = 0; + game.last_from = null; + game.state = 'group_move_to'; + }, + end_move_phase: end_move_phase, + undo: pop_undo +} + // Start new group move or sea move. states.move_phase_to = { prompt: function (view, current) { @@ -1701,30 +1739,6 @@ function can_group_move_more() { return false; } -states.group_move_first = { - prompt: function (view, current) { - if (is_inactive_player(current)) - return view.prompt = group_move_name(1) + "Waiting for " + game.active + "."; - view.prompt = group_move_name(0) + "Choose a block to group move."; - gen_action_undo(view); - if (game.active == game.guide || game.active == game.jihad) - gen_action(view, 'end_move_phase'); - for (let b in BLOCKS) - if (can_block_land_move(b)) - gen_action(view, 'block', b); - }, - block: function (who) { - push_undo(); - game.where = game.location[who]; - game.who = who; - game.distance = 0; - game.last_from = null; - game.state = 'group_move_to'; - }, - end_move_phase: end_move_phase, - undo: pop_undo -} - states.group_move_who = { prompt: function (view, current) { if (is_inactive_player(current)) @@ -1816,27 +1830,50 @@ function end_group_move() { // SEA MOVE +states.german_move_to = { + prompt: function (view, current) { + if (is_inactive_player(current)) + return view.prompt = "Move Phase: Waiting for " + game.active + "."; + view.prompt = "Move Phase: Move " + block_name(game.who) + " to Aleppo, Antioch, or St. Simeon."; + gen_action_undo(view); + gen_action(view, 'block', game.who); + for (let to of GERMAN_ROADS) + if (can_germans_move_to(game.who, to)) + gen_action(view, 'town', to); + }, + town: function (to) { + --game.moves; + let from = GERMANIA; + game.location[game.who] = to; + game.moved[game.who] = 1; + game.distance = 0; + let mark = move_block(game.who, from, to); + if (mark) + log(game.active + " move:\n Germania \u2192 " + to + mark + "."); + else + log(game.active + " move:\n Germania \u2192 " + to + "."); + game.who = null; + game.state = 'move_phase'; + }, + block: pop_undo, + undo: pop_undo, +} + states.sea_move_to = { prompt: function (view, current) { if (is_inactive_player(current)) return view.prompt = "Move Phase: Waiting for " + game.active + "."; if (is_english_crusader(game.who)) view.prompt = "Sea Move: Move " + block_name(game.who) + " to a port."; - else if (game.where == GERMANIA) - view.prompt = "Move Phase: Move " + block_name(game.who) + " to Aleppo, Antioch, or St. Simeon."; else view.prompt = "Sea Move: Move " + block_name(game.who) + " to a friendly port."; gen_action_undo(view); gen_action(view, 'block', game.who); let from = game.location[game.who]; if (from == GERMANIA) { - if (!(is_winter() && is_enemy_occupied_town(ALEPPO))) - gen_action(view, 'town', ALEPPO); - if (!(is_winter() && is_enemy_occupied_town(ANTIOCH))) - gen_action(view, 'town', ANTIOCH); - if (!(is_winter() && is_enemy_occupied_town(ST_SIMEON))) - if (road_limit(GERMANIA, ST_SIMEON) < 2) - gen_action(view, 'town', ST_SIMEON); + for (let to of GERMAN_ROADS) + if (can_germans_move_to(game.who, to)) + gen_action(view, 'town', to); } else { for (let to of PORTS) if (to != game.where && can_block_sea_move_to(game.who, to)) @@ -1850,33 +1887,24 @@ states.sea_move_to = { game.location[game.who] = to; game.moved[game.who] = 1; - if (from == GERMANIA) { - game.distance = 0; - let mark = move_block(game.who, from, to); - if (mark) - log(game.active + " move:\n Germania \u2192 " + to + mark + "."); - else - log(game.active + " move:\n Germania \u2192 " + to + "."); - } else { - lift_siege(from); + lift_siege(from); - remove_from_array(game.castle, game.who); + remove_from_array(game.castle, game.who); - if (besieged_player(to) == game.active && is_more_room_in_castle(to)) { - // Move into besieged fortified port - game.castle.push(game.who); - log(game.active + " sea move:\n" + from + " \u2192 " + to + " castle."); + if (besieged_player(to) == game.active && is_more_room_in_castle(to)) { + // Move into besieged fortified port + game.castle.push(game.who); + log(game.active + " sea move:\n" + from + " \u2192 " + to + " castle."); - } else if (!is_friendly_port(to)) { - // English Crusaders attack! - game.attacker[to] = FRANKS; - game.main_road[to] = "England"; - log(game.active + " sea move:\n" + from + " \u2192 " + to + ATTACK_MARK + "."); + } else if (!is_friendly_port(to)) { + // English Crusaders attack! + game.attacker[to] = FRANKS; + game.main_road[to] = "England"; + log(game.active + " sea move:\n" + from + " \u2192 " + to + ATTACK_MARK + "."); - } else { - // Normal move. - log(game.active + " sea move:\n" + from + " \u2192 " + to + "."); - } + } else { + // Normal move. + log(game.active + " sea move:\n" + from + " \u2192 " + to + "."); } game.who = null; |