diff options
-rw-r--r-- | rules.js | 169 | ||||
-rw-r--r-- | ui.js | 78 |
2 files changed, 125 insertions, 122 deletions
@@ -390,7 +390,7 @@ function count_friendly_in_field_excluding_reserves(where) { let count = 0; for (let b in BLOCKS) if (game.location[b] == where && block_owner(b) == p) - if (!is_block_in_castle(b) && !is_battle_reserve(b)) + if (!is_block_in_castle(b) && !is_reserve(b)) ++count; return count; } @@ -400,7 +400,7 @@ function count_enemy_in_field_excluding_reserves(where) { let count = 0; for (let b in BLOCKS) if (game.location[b] == where && block_owner(b) == p) - if (!is_block_in_castle(b) && !is_battle_reserve(b)) + if (!is_block_in_castle(b) && !is_reserve(b)) ++count; return count; } @@ -441,7 +441,7 @@ function count_pinned(where) { let count = 0; for (let b in BLOCKS) if (game.location[b] == where && block_owner(b) == game.active) - if (!is_battle_reserve(b)) + if (!is_reserve(b)) ++count; return count; } @@ -706,53 +706,53 @@ function can_muster_anywhere() { return false; } -function is_battle_reserve(who) { +function is_reserve(who) { return game.reserves1.includes(who) || game.reserves2.includes(who); } function is_attacker(who) { if (game.location[who] == game.where && block_owner(who) == game.attacker[game.where]) - return !is_battle_reserve(who); + return !is_reserve(who); return false; } function is_defender(who) { if (game.location[who] == game.where && block_owner(who) != game.attacker[game.where]) - return !is_battle_reserve(who); + return !is_reserve(who); return false; } function is_field_attacker(who) { if (game.location[who] == game.where && block_owner(who) == game.attacker[game.where]) - return !is_battle_reserve(who) && !is_block_in_castle(who); + return !is_reserve(who) && !is_block_in_castle(who); return false; } function is_field_defender(who) { if (game.location[who] == game.where && block_owner(who) != game.attacker[game.where]) - return !is_battle_reserve(who) && !is_block_in_castle(who); + return !is_reserve(who) && !is_block_in_castle(who); return false; } function is_field_combatant(who) { if (game.location[who] == game.where) - return !is_battle_reserve(who) && !is_block_in_castle(who); + return !is_reserve(who) && !is_block_in_castle(who); return false; } function is_block_in_field(who) { - return !is_battle_reserve(who) && !is_block_in_castle(who); + return !is_reserve(who) && !is_block_in_castle(who); } -function is_storm_attacker(who) { +function is_siege_attacker(who) { return game.storming.includes(who); } -function is_storm_defender(who) { +function is_siege_defender(who) { return is_block_in_castle_in(who, game.where); } -function is_storm_combatant(who) { +function is_siege_combatant(who) { return game.storming.includes(who) || is_block_in_castle_in(who, game.where); } @@ -796,7 +796,7 @@ function count_reserves(where) { let n = 0; for (let b in BLOCKS) if (block_owner(b) == game.active) - if (game.location[b] == where && is_battle_reserve(b)) + if (game.location[b] == where && is_reserve(b)) ++n; return n; } @@ -1940,9 +1940,9 @@ states.combat_deployment = { let n = count_blocks_in_castle(game.where); if (n < max) { for (let b in BLOCKS) { - if (block_owner(b) == game.active && !is_battle_reserve(b)) { + if (block_owner(b) == game.active && !is_reserve(b)) { if (game.location[b] == game.where && !game.castle.includes(b)) { - gen_action(view, 'battle_withdraw', b); + gen_action(view, 'withdraw', b); gen_action(view, 'block', b); } } @@ -1951,7 +1951,7 @@ states.combat_deployment = { gen_action_undo(view); gen_action(view, 'next'); }, - battle_withdraw: function (who) { + withdraw: function (who) { push_undo(); game.castle.push(who); }, @@ -2105,7 +2105,7 @@ function goto_combat_round(combat_round) { function goto_declare_storm() { if (game.storming.length == castle_limit(game.where)) - return goto_storm_battle(); + return goto_siege_battle(); game.active = besieging_player(game.where); game.state = 'declare_storm'; } @@ -2118,9 +2118,9 @@ states.declare_storm = { view.prompt = "Siege Declaration: Declare which blocks should storm the castle."; if (game.storming.length < castle_limit(game.where)) { for (let b in BLOCKS) { - if (block_owner(b) == game.active && !is_battle_reserve(b)) { + if (block_owner(b) == game.active && !is_reserve(b)) { if (game.location[b] == game.where && !game.storming.includes(b)) { - gen_action(view, 'battle_storm', b); + gen_action(view, 'storm', b); gen_action(view, 'block', b); } } @@ -2129,7 +2129,7 @@ states.declare_storm = { gen_action_undo(view); gen_action(view, 'next'); }, - battle_storm: storm_with_block, + storm: storm_with_block, block: storm_with_block, next: function () { clear_undo(); @@ -2139,7 +2139,7 @@ states.declare_storm = { log(game.active + " decline to storm."); goto_declare_sally(); } else { - goto_storm_battle(); + goto_siege_battle(); } }, undo: pop_undo @@ -2170,9 +2170,9 @@ states.declare_sally = { return view.prompt = "Siege Declaration: Waiting for " + game.active + " to declare sally."; view.prompt = "Siege Declaration: Declare which blocks should sally onto the field."; for (let b in BLOCKS) { - if (block_owner(b) == game.active && !is_battle_reserve(b) && is_block_in_castle(b)) { + if (block_owner(b) == game.active && !is_reserve(b) && is_block_in_castle(b)) { if (game.location[b] == game.where && !game.sallying.includes(b)) { - gen_action(view, 'battle_sally', b); + gen_action(view, 'sally', b); gen_action(view, 'block', b); } } @@ -2180,7 +2180,7 @@ states.declare_sally = { gen_action_undo(view); gen_action(view, 'next'); }, - battle_sally: sally_with_block, + sally: sally_with_block, block: sally_with_block, next: function () { clear_undo(); @@ -2335,7 +2335,7 @@ function goto_siege_attrition() { } } -// FIELD AND STORM BATTLE HELPERS +// FIELD AND SIEGE BATTLE HELPERS function filter_battle_blocks(ci, is_candidate) { let output = null; @@ -2405,8 +2405,11 @@ function resume_field_battle() { return goto_regroup(); } - if (!is_contested_battle_field()) + if (!is_contested_battle_field()) { + console.log("won in battle round, swap att/def!"); + // TODO swap defender/attacker if applicable return next_combat_round(); + } game.state = 'field_battle'; pump_battle_step(is_field_attacker, is_field_defender); @@ -2420,89 +2423,89 @@ states.field_battle = { view.prompt = "Field Battle: Choose a combat action."; for (let b of game.battle_list) { gen_action(view, 'block', b); // take default action - gen_action(view, 'battle_fire', b); + gen_action(view, 'fire', b); if (game.sallying.includes(b)) { // Only sallying forces may withdraw into the castle - gen_action(view, 'battle_withdraw', b); + gen_action(view, 'withdraw', b); } else { if (can_block_retreat(b)) { - gen_action(view, 'battle_retreat', b); + gen_action(view, 'retreat', b); // Turcopoles and Nomads can Harry (fire and retreat) if (block_type(b) == 'turcopoles' || block_type(b) == 'nomads') - gen_action(view, 'battle_harry', b); + gen_action(view, 'harry', b); } // Defender can withdraw into castle if friendly and there is room. if (game.active != game.attacker[game.where] && game.active == game.castle_owner) { // TODO: allow swapping place of sallying block, leaving it to die if it cannot withdraw? if (game.sallying.length + count_blocks_in_castle(game.where) < castle_limit(game.where)) - gen_action(view, 'battle_withdraw', b); + gen_action(view, 'withdraw', b); } } // All Frank B blocks are knights who can Charge if (block_owner(b) == FRANKS && block_initiative(b) == 'B') - gen_action(view, 'battle_charge', b); + gen_action(view, 'charge', b); } }, block: field_fire_with_block, - battle_fire: field_fire_with_block, - battle_withdraw: field_withdraw_with_block, - battle_charge: charge_with_block, - battle_harry: harry_with_block, - battle_retreat: retreat_with_block, + fire: field_fire_with_block, + withdraw: field_withdraw_with_block, + charge: charge_with_block, + harry: harry_with_block, + retreat: retreat_with_block, } -// STORM BATTLE +// SIEGE BATTLE -function goto_storm_battle() { +function goto_siege_battle() { game.attacker[game.where] = besieging_player(game.where); - console.log("STORM BATTLE", game.attacker[game.where]); - resume_storm_battle(); + console.log("SIEGE BATTLE", game.attacker[game.where]); + resume_siege_battle(); } -function resume_storm_battle() { +function resume_siege_battle() { game.active = game.attacker[game.where]; if (is_friendly_town(game.where)) { - console.log("STORM BATTLE WON BY ATTACKER", game.active); + console.log("SIEGE BATTLE WON BY ATTACKER", game.active); log("Siege battle won by " + game.active + "."); return goto_regroup(); } if (is_enemy_town(game.where)) { - console.log("STORM BATTLE WON BY DEFENDER", ENEMY[game.active]); + console.log("SIEGE BATTLE WON BY DEFENDER", ENEMY[game.active]); game.halfhit = null; log("Storming repulsed."); return goto_regroup(); } if (game.storming.length == 0) { - console.log("STORM BATTLE WON BY DEFENDER", ENEMY[game.active]); + console.log("SIEGE BATTLE WON BY DEFENDER", ENEMY[game.active]); game.halfhit = null; log("Storming repulsed."); return next_combat_round(); } - game.state = 'storm_battle'; - pump_battle_step(is_storm_attacker, is_storm_defender); + game.state = 'siege_battle'; + pump_battle_step(is_siege_attacker, is_siege_defender); } -states.storm_battle = { +states.siege_battle = { show_battle: true, prompt: function (view, current) { if (is_inactive_player(current)) - return view.prompt = "Storm: Waiting for " + game.active + "."; - view.prompt = "Storm: Choose a combat action."; + return view.prompt = "Siege Battle: Waiting for " + game.active + "."; + view.prompt = "Siege Battle: Choose a combat action."; for (let b of game.battle_list) { gen_action(view, 'block', b); // take default action - gen_action(view, 'battle_fire', b); + gen_action(view, 'fire', b); if (game.storming.includes(b)) - gen_action(view, 'battle_retreat', b); + gen_action(view, 'retreat', b); } }, - block: storm_fire_with_block, - battle_fire: storm_fire_with_block, - battle_retreat: storm_withdraw_with_block, + block: siege_fire_with_block, + fire: siege_fire_with_block, + retreat: siege_withdraw_with_block, } // FIELD BATTLE HITS @@ -2535,11 +2538,11 @@ states.field_battle_hits = { return view.prompt = "Field Battle: Waiting for " + game.active + " to assign hits."; view.prompt = "Field Battle: Assign " + game.hits + (game.hits != 1 ? " hits" : " hit") + " to your armies."; for (let b of game.battle_list) { - gen_action(view, 'battle_hit', b); + gen_action(view, 'hit', b); gen_action(view, 'block', b); } }, - battle_hit: apply_field_battle_hit, + hit: apply_field_battle_hit, block: apply_field_battle_hit, } @@ -2561,47 +2564,47 @@ function apply_field_battle_hit(who) { } } -// STORM BATTLE HITS +// SIEGE BATTLE HITS -function goto_storm_battle_hits() { +function goto_siege_battle_hits() { game.active = ENEMY[game.active]; - game.battle_list = list_storm_victims(); + game.battle_list = list_siege_victims(); if (game.battle_list.length == 0) - resume_storm_battle(); + resume_siege_battle(); else - game.state = 'storm_battle_hits'; + game.state = 'siege_battle_hits'; } -function list_storm_victims() { +function list_siege_victims() { if (game.halfhit && block_owner(game.halfhit) == game.active) return [ game.halfhit ]; let max = 0; for (let b in BLOCKS) - if (block_owner(b) == game.active && is_storm_combatant(b) && game.steps[b] > max) + if (block_owner(b) == game.active && is_siege_combatant(b) && game.steps[b] > max) max = game.steps[b]; let list = []; for (let b in BLOCKS) - if (block_owner(b) == game.active && is_storm_combatant(b) && game.steps[b] == max) + if (block_owner(b) == game.active && is_siege_combatant(b) && game.steps[b] == max) list.push(b); return list; } -states.storm_battle_hits = { +states.siege_battle_hits = { show_battle: true, prompt: function (view, current) { if (is_inactive_player(current)) - return view.prompt = "Storm: Waiting for " + game.active + " to assign hits."; - view.prompt = "Storm: Assign " + game.hits + (game.hits != 1 ? " hits" : " hit") + " to your armies."; + return view.prompt = "Siege Battle: Waiting for " + game.active + " to assign hits."; + view.prompt = "Siege Battle: Assign " + game.hits + (game.hits != 1 ? " hits" : " hit") + " to your armies."; for (let b of game.battle_list) { - gen_action(view, 'battle_hit', b); + gen_action(view, 'hit', b); gen_action(view, 'block', b); } }, - battle_hit: apply_storm_battle_hit, - block: apply_storm_battle_hit, + hit: apply_siege_battle_hit, + block: apply_siege_battle_hit, } -function apply_storm_battle_hit(who) { +function apply_siege_battle_hit(who) { if (block_plural(who)) game.flash = block_name(who) + " take a hit."; else @@ -2618,11 +2621,11 @@ function apply_storm_battle_hit(who) { game.hits--; if (game.hits == 0) { - resume_storm_battle(); + resume_siege_battle(); } else { - game.battle_list = list_storm_victims(); + game.battle_list = list_siege_victims(); if (game.battle_list.length == 0) { - resume_storm_battle(); + resume_siege_battle(); } else { game.flash += " " + game.hits + (game.hits == 1 ? " hit left." : " hits left."); } @@ -2699,16 +2702,16 @@ function field_fire_with_block(b) { } } -function storm_fire_with_block(b) { +function siege_fire_with_block(b) { game.moved[b] = true; if (block_plural(b)) roll_attack(game.active, b, "fire", 0); else roll_attack(game.active, b, "fires", 0); if (game.hits > 0) { - goto_storm_battle_hits(); + goto_siege_battle_hits(); } else { - resume_storm_battle(); + resume_siege_battle(); } } @@ -2737,7 +2740,7 @@ function field_withdraw_with_block(b) { resume_field_battle(); } -function storm_withdraw_with_block(b) { +function siege_withdraw_with_block(b) { if (block_plural(b)) game.flash = b + " withdraw."; else @@ -2745,7 +2748,7 @@ function storm_withdraw_with_block(b) { log(game.active[0] + ": " + game.flash); game.moved[b] = true; remove_from_array(game.storming, b); - resume_storm_battle(); + resume_siege_battle(); } function harry_with_block(b) { @@ -3266,14 +3269,14 @@ function make_battle_view() { // cell.sort((a,b) => compare_block_initiative(a[0], b[0])); } - fill_cell(battle.FR, FRANKS, b => is_battle_reserve(b)); + fill_cell(battle.FR, FRANKS, b => is_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)); + fill_cell(battle.SR, SARACENS, b => is_reserve(b)); return battle; } @@ -120,15 +120,15 @@ function on_focus_battle_block(evt) { msg = block_name(b); } - if (game.actions && game.actions.battle_fire && game.actions.battle_fire.includes(b)) + if (game.actions && game.actions.fire && game.actions.fire.includes(b)) msg = "Fire with " + msg; - else if (game.actions && game.actions.battle_storm && game.actions.battle_storm.includes(b)) + else if (game.actions && game.actions.storm && game.actions.storm.includes(b)) msg = "Storm with " + msg; - else if (game.actions && game.actions.battle_sally && game.actions.battle_sally.includes(b)) + else if (game.actions && game.actions.sally && game.actions.sally.includes(b)) msg = "Sally with " + msg; - else if (game.actions && game.actions.battle_withdraw && game.actions.battle_withdraw.includes(b)) + else if (game.actions && game.actions.withdraw && game.actions.withdraw.includes(b)) msg = "Withdraw with " + msg; - else if (game.actions && game.actions.battle_hit && game.actions.battle_hit.includes(b)) + else if (game.actions && game.actions.hit && game.actions.hit.includes(b)) msg = "Take hit on " + msg; document.getElementById("status").textContent = msg; @@ -143,12 +143,12 @@ function on_click_battle_block(evt) { send_action('block', b); } -function on_focus_battle_fire(evt) { +function on_focus_fire(evt) { document.getElementById("status").textContent = "Fire with " + block_name(evt.target.block); } -function on_focus_battle_retreat(evt) { +function on_focus_retreat(evt) { if (game.battle.storming.includes(evt.target.block)) document.getElementById("status").textContent = "Withdraw with " + block_name(evt.target.block); @@ -157,32 +157,32 @@ function on_focus_battle_retreat(evt) { "Retreat with " + block_name(evt.target.block); } -function on_focus_battle_harry(evt) { +function on_focus_harry(evt) { document.getElementById("status").textContent = "Harry with " + block_name(evt.target.block); } -function on_focus_battle_charge(evt) { +function on_focus_charge(evt) { document.getElementById("status").textContent = "Charge with " + block_name(evt.target.block); } -function on_focus_battle_withdraw(evt) { +function on_focus_withdraw(evt) { document.getElementById("status").textContent = "Withdraw with " + block_name(evt.target.block); } -function on_focus_battle_storm(evt) { +function on_focus_storm(evt) { document.getElementById("status").textContent = "Storm with " + block_name(evt.target.block); } -function on_focus_battle_sally(evt) { +function on_focus_sally(evt) { document.getElementById("status").textContent = "Sally with " + block_name(evt.target.block); } -function on_focus_battle_hit(evt) { +function on_focus_hit(evt) { document.getElementById("status").textContent = "Take hit on " + block_name(evt.target.block); } @@ -191,14 +191,14 @@ function on_blur_battle_button(evt) { document.getElementById("status").textContent = ""; } -function on_click_battle_hit(evt) { send_action('battle_hit', evt.target.block); } -function on_click_battle_fire(evt) { send_action('battle_fire', evt.target.block); } -function on_click_battle_retreat(evt) { send_action('battle_retreat', evt.target.block); } -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_hit(evt) { send_action('hit', evt.target.block); } +function on_click_fire(evt) { send_action('fire', evt.target.block); } +function on_click_retreat(evt) { send_action('retreat', evt.target.block); } +function on_click_charge(evt) { send_action('charge', evt.target.block); } +function on_click_harry(evt) { send_action('harry', evt.target.block); } +function on_click_withdraw(evt) { send_action('withdraw', evt.target.block); } +function on_click_storm(evt) { send_action('storm', evt.target.block); } +function on_click_sally(evt) { send_action('sally', evt.target.block); } function on_click_card(evt) { let c = evt.target.id.split("+")[1] | 0; @@ -249,28 +249,28 @@ function build_battle_block(b, block) { menu_list.classList.add("battle_menu_list"); build_battle_button(menu_list, b, "hit", - on_click_battle_hit, on_focus_battle_hit, + on_click_hit, on_focus_hit, "/images/cross-mark.svg"); build_battle_button(menu_list, b, "charge", - on_click_battle_charge, on_focus_battle_charge, + on_click_charge, on_focus_charge, "/images/mounted-knight.svg"); build_battle_button(menu_list, b, "fire", - on_click_battle_fire, on_focus_battle_fire, + on_click_fire, on_focus_fire, "/images/pointy-sword.svg"); build_battle_button(menu_list, b, "harry", - on_click_battle_harry, on_focus_battle_harry, + on_click_harry, on_focus_harry, "/images/arrow-flights.svg"); build_battle_button(menu_list, b, "retreat", - on_click_battle_retreat, on_focus_battle_retreat, + on_click_retreat, on_focus_retreat, "/images/flying-flag.svg"); build_battle_button(menu_list, b, "withdraw", - on_click_battle_withdraw, on_focus_battle_withdraw, + on_click_withdraw, on_focus_withdraw, "/images/stone-tower.svg"); build_battle_button(menu_list, b, "storm", - on_click_battle_storm, on_focus_battle_storm, + on_click_storm, on_focus_storm, "/images/siege-tower.svg"); build_battle_button(menu_list, b, "sally", - on_click_battle_sally, on_focus_battle_sally, + on_click_sally, on_focus_sally, "/images/doorway.svg"); let menu = document.createElement("div"); @@ -696,25 +696,25 @@ function update_battle() { if (game.actions && game.actions.block && game.actions.block.includes(block)) ui.battle_block[block].classList.add("highlight"); - if (game.actions && game.actions.battle_fire && game.actions.battle_fire.includes(block)) + if (game.actions && game.actions.fire && game.actions.fire.includes(block)) ui.battle_menu[block].classList.add('fire'); - if (game.actions && game.actions.battle_retreat && game.actions.battle_retreat.includes(block)) + if (game.actions && game.actions.retreat && game.actions.retreat.includes(block)) ui.battle_menu[block].classList.add('retreat'); - if (game.actions && game.actions.battle_harry && game.actions.battle_harry.includes(block)) + if (game.actions && game.actions.harry && game.actions.harry.includes(block)) ui.battle_menu[block].classList.add('harry'); - if (game.actions && game.actions.battle_charge && game.actions.battle_charge.includes(block)) + if (game.actions && game.actions.charge && game.actions.charge.includes(block)) ui.battle_menu[block].classList.add('charge'); - if (game.actions && game.actions.battle_withdraw && game.actions.battle_withdraw.includes(block)) + if (game.actions && game.actions.withdraw && game.actions.withdraw.includes(block)) ui.battle_menu[block].classList.add('withdraw'); - if (game.actions && game.actions.battle_storm && game.actions.battle_storm.includes(block)) + if (game.actions && game.actions.storm && game.actions.storm.includes(block)) ui.battle_menu[block].classList.add('storm'); - if (game.actions && game.actions.battle_sally && game.actions.battle_sally.includes(block)) + if (game.actions && game.actions.sally && game.actions.sally.includes(block)) ui.battle_menu[block].classList.add('sally'); - if (game.actions && game.actions.battle_hit && game.actions.battle_hit.includes(block)) + if (game.actions && game.actions.hit && game.actions.hit.includes(block)) ui.battle_menu[block].classList.add('hit'); - if (game.actions && game.actions.battle_charge && game.actions.battle_charge.includes(block)) + if (game.actions && game.actions.charge && game.actions.charge.includes(block)) ui.battle_menu[block].classList.add('charge'); - if (game.actions && game.actions.battle_treachery && game.actions.battle_treachery.includes(block)) + if (game.actions && game.actions.treachery && game.actions.treachery.includes(block)) ui.battle_menu[block].classList.add('treachery'); update_steps(block, game.steps[block], ui.battle_block[block], false); |