diff options
-rw-r--r-- | play.css | 1 | ||||
-rw-r--r-- | rules.js | 157 |
2 files changed, 138 insertions, 20 deletions
@@ -144,6 +144,7 @@ header.your_turn.ve { background-color: #ffbf32 } #log div.indent { padding-left: 32px; text-indent: -12px; } #log .h1 { border-bottom: 2px solid #444; border-top: 2px solid #444; } #log .h2 { border-bottom: 1px solid #444; border-top: 1px solid #444; } +#log .h3 { text-decoration: underline;} #log .adice { font-size: 14px; @@ -417,11 +417,13 @@ function goto_pass() { function goto_advance() { init_command("Advance") + game.cmd.free -= 1 game.state = "advance" } function goto_amass() { init_command("Amass") + game.cmd.free -= 1 game.state = "amass" } @@ -482,13 +484,21 @@ function end_march_space() { function goto_mi_attack() { init_command("Attack & Plunder") + game.cmd.free -= 1 + game.cmd.selected = [] + game.cmd.cavalry = false game.state = "mi_attack" } function goto_mongol_invaders(faction) { - game.cmd = {} + game.cmd = { + pieces: [], + spaces: [], + limited: 0, + free: 2, + sa_faction: faction + } game.current = faction - game.cmd.free = 2 goto_strategic_assistance() } @@ -974,6 +984,9 @@ function roll_attack() { for (let d = 0; d < 6; ++d) game.dice[d] = random(6) + 1 + if (game.cmd.target === DS && game.cmd.attacker === MI && game.cmd.where === S_DELHI) + game.dice[3] = 0 + if (game.cmd.target === BK && has_piece(game.cmd.where, BK, DISC)) game.dice[3] = 0 } @@ -993,6 +1006,11 @@ function attack_use_cavalry(d, f) { } else if (!is_a_die && !is_attacker) { charge_die(d) } + + if (game.cmd.cav_faction === MI) { + game.cmd.step += 1 + next_attack_cavalry_step() + } } function charge_die(d) { @@ -1142,8 +1160,8 @@ states.attack_space = { roll() { // clear_undo() TODO: remove for prd roll_attack() - log(">.ad " + game.dice.slice(0,4).map(d => AD[d]).join(" ")) - log(">.dd " + game.dice.slice(4).map(d => DD[d]).join(" ")) + log(">.ad " + game.dice.slice(0,4).filter(d => d > 0).map(d => AD[d]).join(" ")) + log(">.dd " + game.dice.slice(4).filter(d => d > 0).map(d => DD[d]).join(" ")) log_br() game.cmd.step = 0 @@ -1178,33 +1196,51 @@ function goto_attack_cavalry(curr) { } game.cmd.step += 1 next_attack_cavalry_step() + } else if (curr === MI) { + game.current = game.cmd.sa_faction, + game.cmd.cav_faction = MI + game.state = "attack_cavalry" } else { game.current = curr + game.cmd.cav_faction = curr game.state = "attack_cavalry" } } states.attack_cavalry = { prompt() { - view.prompt = "Attack: Use cavalry to Charge your dice or Screen your opponent's dice." - view.who = game.cmd.selected - let curr_die = [0, 1, 2, 3, 4, 5] - // TODO: restrict range for MI player + let can_charge = false + if (game.cmd.cav_faction === MI) { + view.prompt = "Attack: Use the Mongol Cavalry to Charge a die." + curr_die = [0, 1, 2, 3] + if (has_cavalry(game.cmd.cav_faction)) + for (let d of curr_die) + if (game.dice[d] === 2 || game.dice[d] === game.cmd.n_units[0] + 1) { + gen_action_die(d) + can_charge = true + } + if (!can_charge) + view.prompt = "Attack: No Charge possible for the Mongol Cavalry." + } else { + view.prompt = "Attack: Use cavalry to Charge your dice or Screen your opponent's dice." + if (has_cavalry(game.cmd.cav_faction)) + for (let d of curr_die) + if (game.dice[d] > 1) + gen_action_die(d) + } - if (has_cavalry(game.current)) - for (let d of curr_die) - if (game.dice[d] > 1) - gen_action_die(d) + if (game.cmd.cav_faction !== MI || game.cmd.cavalry || !can_charge) + view.actions.next = 1 - view.actions.next = 1 + view.who = game.cmd.selected }, die(d) { if (!game.cmd.cavalry) { - log(`${faction_acronyms[game.current]} is using Cavalry.`) + log(`${faction_acronyms[game.cmd.cav_faction]} is using Cavalry.`) game.cmd.cavalry = true } - attack_use_cavalry(d, game.current) + attack_use_cavalry(d, game.cmd.cav_faction) }, next() { game.cmd.step += 1 @@ -1286,7 +1322,11 @@ function goto_attack_resolution() { game.dice = [0, 0, 0, 0, 0, 0] if (is_rebel_faction(game.cmd.target) && is_rebel_faction(game.cmd.attacker)) attack_influence_shift() - game.state = "attack" + if (game.cmd.attacker === MI) { + game.current = game.cmd.sa_faction + game.state = "plunder" + } else + game.state = "attack" } function attack_influence_shift() { @@ -2242,7 +2282,6 @@ states.advance_space = { place_piece(p, game.cmd.where) }, end_advance() { - game.cmd.free -= 1 log_space(game.cmd.where, "Advance") pop_summary() goto_strategic_assistance() @@ -2261,7 +2300,6 @@ states.amass = { }, space(s) { amass() - game.cmd.free -= 1 goto_strategic_assistance() } } @@ -2307,6 +2345,84 @@ function can_mi_attack() { return false } +states.mi_attack = { + prompt() { + view.prompt = "Attack & Plunder: Select a Space to attack the Sultanate units and plunder resources." + + for (let s = first_space; s <= last_space; ++s) + if (has_piece_faction(s, MI)) + gen_action_space(s) + + }, + space(s) { + log_space(s, "Attack") + game.cmd.where = s + game.cmd.attacker = MI + game.cmd.target = DS + set_add(game.cmd.spaces, s) + goto_attack_space() + } +} + +states.plunder = { + prompt() { + let n = Math.min(game.resources[DS] - 3, count_pieces(game.cmd.where, MI, TROOPS)) + view.prompt = `Attack & Plunder: Plunder ${n} resources from the Delhi Sultanate!` + gen_action_resources(DS) + }, + resources(f) { + log_space(game.cmd.where, "Plunder") + + let n = Math.min(game.resources[DS] - 3, count_pieces(game.cmd.where, MI, TROOPS)) + logi_resources(f, -n) + add_resources(f, -n) + goto_plunder_remove() + } +} + +function goto_plunder_remove() { + game.cmd.count = count_pieces(game.cmd.where, MI, TROOPS) + if (game.cmd.where === S_MOUNTAIN_PASSES || game.cmd.count === 0) + end_plunder() + else { + if (game.cmd.where === S_DELHI) + game.cmd.count *= 2 + push_summary() + game.current = DS + game.state = "plunder_remove" + } +} + +states.plunder_remove = { + prompt() { + if (game.cmd.count > 0) { + view.prompt = `Attack & Plunder: Remove ${game.cmd.count} Troops from any Provinces.` + + for (let s = first_space; s <= last_province; ++s) { + if (has_piece(s, DS, TROOPS)) + gen_action_space(s) + } + } else { + view.prompt = "Attack & Plunder: Done." + view.actions.next = 1 + } + }, + space(s) { + game.cmd.count -= 1 + let p = find_piece(s, DS, TROOPS) + log_summary_move_from(p) + remove_piece(p) + }, + next: end_plunder +} + +function end_plunder() { + if (game.summary && game.summary.length > 0) { + pop_summary() + } + game.current = game.cmd.sa_faction + goto_strategic_assistance() +} /* TRIBUTARY AND REBELS */ @@ -2769,6 +2885,8 @@ function find_cavalry(faction) { } function has_cavalry(faction) { + if (!game.cmd.cavalry && faction === MI) + return true return find_cavalry(faction) != -1 } @@ -2996,7 +3114,7 @@ function log_h2(msg) { function log_action(msg) { log_br() - log(msg) + log(".h3 " + msg) } function log_transfer(msg) { @@ -4168,7 +4286,6 @@ function vm_govern() { where: -1, pass: 1 } - console.log(game.vm) game.state = "govern" } |