From cc2e316d2a88a6869965e5fd999f4a8c085da4c5 Mon Sep 17 00:00:00 2001 From: Tor Andersson Date: Wed, 23 Jun 2021 13:09:29 +0200 Subject: crusader: Richard's Sea legs, attacker retreat, siege relief are attackers. --- data.js | 4 ++-- rules.js | 50 +++++++++++++++++++++++++++++++++----------------- 2 files changed, 35 insertions(+), 19 deletions(-) diff --git a/data.js b/data.js index 7ee9dcc..2abeead 100644 --- a/data.js +++ b/data.js @@ -80,7 +80,7 @@ const TOWNS = { "Anjar":{"x":753,"y":1129}, "Antioch":{"x":471,"y":189}, "Artah":{"x":865,"y":149}, - "Ascalon":{"x":367,"y":2081}, + "Ascalon":{"x":365,"y":2077}, "Ashtera":{"x":1038,"y":1419}, "Baalbek":{"x":842,"y":1008}, "Baisan":{"x":707,"y":1685}, @@ -94,7 +94,7 @@ const TOWNS = { "Damiya":{"x":847,"y":1808}, "Dimona":{"x":630,"y":2294}, "Egypt":{"x":202,"y":2318}, - "Gaza":{"x":300,"y":2183}, + "Gaza":{"x":300,"y":2185}, "Hama":{"x":1035,"y":477}, "Harim":{"x":699,"y":124}, "Hebron":{"x":680,"y":2109}, diff --git a/rules.js b/rules.js index 0291248..1ffaf9c 100644 --- a/rules.js +++ b/rules.js @@ -3,7 +3,9 @@ // TODO: optional rule - iron bridge // TODO: optional rule - force marches -// TODO: pause after battle ends (ui maybe?) +// 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 + exports.scenarios = [ "Third Crusade" @@ -330,6 +332,10 @@ function road_was_last_used_by_enemy(from, to) { return game.last_used[road_id(from, to)] == enemy(game.active); } +function road_was_last_used_by_friendly(from, to) { + return game.last_used[road_id(from, to)] == game.active; +} + function road_type(a, b) { return ROADS[road_id(a,b)]; } @@ -532,6 +538,14 @@ function castle_limit(where) { return TOWNS[where].rating; } +function is_more_room_in_castle(where) { + return count_blocks_in_castle(where) < castle_limit(where); +} + +function is_within_castle_limit(where) { + return count_friendly(where) <= Math.max(1, castle_limit(where)); +} + function is_castle_town(where) { return castle_limit(where) > 0; } @@ -649,12 +663,10 @@ function can_use_richards_sea_legs(who, to) { // 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 (game.attacker[to] == FRANKS) { - let road = game.main_road[to]; - if (road) - return (road == "England"); - } - return true; + if (!game.attacker[to]) + return true; + if (game.attacker[to] == FRANKS) + return (game.main_road[to] == "England"); } } return false; @@ -734,8 +746,12 @@ function can_block_continue(who, from, to) { } function can_block_retreat_to(who, to) { + let from = game.location[who]; + if (block_owner(who) == game.attacker[from]) { + if (!road_was_last_used_by_friendly(from, to)) + return false; + } if (is_friendly_field(to) || is_vacant_town(to)) { - let from = game.location[who]; if (can_block_use_road(from, to)) { if (road_was_last_used_by_enemy(from, to)) return false; @@ -1656,7 +1672,7 @@ states.sea_move_to = { remove_from_array(game.castle, game.who); - if (besieged_player(to) == game.active) { + 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."); @@ -1937,8 +1953,9 @@ function start_combat() { game.state = 'combat_deployment'; } else { game.castle_owner = besieged_player(game.where); - game.attacker[game.where] = enemy(game.castle_owner); - console.log("CONTINUE SIEGE"); + if (!game.attacker[game.where]) + game.attacker[game.where] = enemy(game.castle_owner); + console.log("CONTINUE SIEGE", game.attacker[game.where]); log("Existing siege continues."); next_combat_round(); } @@ -2191,6 +2208,7 @@ states.declare_storm = { let n = game.storming.length; console.log("STORM DECLARATION", n); if (n == 0) { + game.flash = game.active + " decline to storm."; log(game.active + " decline to storm."); goto_declare_sally(); } else { @@ -2241,8 +2259,10 @@ states.declare_sally = { clear_undo(); let n = game.sallying.length; console.log("SALLY DECLARATION", n); - if (n == 0) + if (n == 0) { + game.flash = game.active + " decline to sally."; log(game.active + " decline to sally."); + } if (is_contested_battle_field()) { if (!game.was_contested) { log(game.active + " are now the attacker."); @@ -3072,10 +3092,6 @@ function eliminate_besieging_blocks(owner) { // WINTER SUPPLY -function is_within_castle_limit(where) { - return count_friendly(where) <= Math.max(1, castle_limit(where)); -} - function need_winter_supply_check() { for (let town in TOWNS) { if (town == game.winter_campaign) @@ -3308,7 +3324,7 @@ function make_battle_view() { show_castle: game.storming.length > 0 && game.state != 'declare_storm', }; - if (is_under_siege(game.where)) + if (is_under_siege(game.where) && !is_contested_battle_field(game.where)) battle.title = enemy(game.castle_owner) + " besiege " + game.where; else battle.title = game.attacker[game.where] + " attack " + game.where; -- cgit v1.2.3