summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--play.css1
-rw-r--r--rules.js157
2 files changed, 138 insertions, 20 deletions
diff --git a/play.css b/play.css
index 00d50ce..0fdc4aa 100644
--- a/play.css
+++ b/play.css
@@ -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;
diff --git a/rules.js b/rules.js
index efebb00..371d052 100644
--- a/rules.js
+++ b/rules.js
@@ -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"
}