summaryrefslogtreecommitdiff
path: root/rules.js
diff options
context:
space:
mode:
Diffstat (limited to 'rules.js')
-rw-r--r--rules.js153
1 files changed, 92 insertions, 61 deletions
diff --git a/rules.js b/rules.js
index 2c06cc5..756374b 100644
--- a/rules.js
+++ b/rules.js
@@ -39,7 +39,7 @@ exports.roles = function (scenario, options) {
// === CONSTANTS ===
-const PLAYER_NAMES = [ P1, P2, P3, P4 ]
+const PLAYER_NAME = [ P1, P2, P3, P4 ]
const PLAYER_INDEX = {
[P1]: 0,
@@ -350,25 +350,25 @@ const CARD_INFO = [
{ name: "M1", type: 0, value: 1, event: "None" },
{ name: "S1", type: 1, value: 1, event: "None" },
{ name: "P1", type: 2, value: 1, event: "None" },
- { name: "M2 Castra", type: 0, value: 2, event: "Castra" },
- { name: "S2 Tribute", type: 1, value: 2, event: "Tribute" },
- { name: "P2 Quaestor", type: 2, value: 2, event: "Quaestor" },
- { name: "M2 Cavalry", type: 0, value: 2, event: "Cavalry" },
- { name: "S2 Princeps Senatus", type: 1, value: 2, event: "Princeps Senatus" },
- { name: "P2 Ambitus", type: 2, value: 2, event: "Ambitus" },
- { name: "M3 Flanking Maneuver", type: 0, value: 3, event: "Flanking Maneuver" },
- { name: "S3 Foederati", type: 1, value: 3, event: "Foederati" },
- { name: "P3 Mob", type: 2, value: 3, event: "Mob" },
- { name: "M3 Force March", type: 0, value: 3, event: "Force March" },
- { name: "S3 Frumentarii", type: 1, value: 3, event: "Frumentarii" },
- { name: "P3 Mobile Vulgus", type: 2, value: 3, event: "Mobile Vulgus" },
- { name: "M4 Praetorian Guard", type: 0, value: 4, event: "Praetorian Guard" },
- { name: "S4 Damnatio Memoriae", type: 1, value: 4, event: "Damnatio Memoriae" },
- { name: "S4 Damnatio Memoriae", type: 1, value: 4, event: "Damnatio Memoriae (exp)" },
- { name: "P4 Pretender", type: 2, value: 4, event: "Pretender" },
- { name: "M4 Spiculum", type: 0, value: 4, event: "Spiculum" },
- { name: "S4 Triumph", type: 1, value: 4, event: "Triumph" },
- { name: "P4 Demagogue", type: 2, value: 4, event: "Demagogue" },
+ { name: "M2(Castra)", type: 0, value: 2, event: "Castra" },
+ { name: "S2(Tribute)", type: 1, value: 2, event: "Tribute" },
+ { name: "P2(Quaestor)", type: 2, value: 2, event: "Quaestor" },
+ { name: "M2(Cavalry)", type: 0, value: 2, event: "Cavalry" },
+ { name: "S2(Princeps Senatus)", type: 1, value: 2, event: "Princeps Senatus" },
+ { name: "P2(Ambitus)", type: 2, value: 2, event: "Ambitus" },
+ { name: "M3(Flanking Maneuver)", type: 0, value: 3, event: "Flanking Maneuver" },
+ { name: "S3(Foederati)", type: 1, value: 3, event: "Foederati" },
+ { name: "P3(Mob)", type: 2, value: 3, event: "Mob" },
+ { name: "M3(Force March)", type: 0, value: 3, event: "Force March" },
+ { name: "S3(Frumentarii)", type: 1, value: 3, event: "Frumentarii" },
+ { name: "P3(Mobile Vulgus)", type: 2, value: 3, event: "Mobile Vulgus" },
+ { name: "M4(Praetorian Guard)", type: 0, value: 4, event: "Praetorian Guard" },
+ { name: "S4(Damnatio Memoriae)", type: 1, value: 4, event: "Damnatio Memoriae" },
+ { name: "S4(Damnatio Memoriae)", type: 1, value: 4, event: "Damnatio Memoriae (exp)" },
+ { name: "P4(Pretender)", type: 2, value: 4, event: "Pretender" },
+ { name: "M4(Spiculum)", type: 0, value: 4, event: "Spiculum" },
+ { name: "S4(Triumph)", type: 1, value: 4, event: "Triumph" },
+ { name: "P4(Demagogue)", type: 2, value: 4, event: "Demagogue" },
]
function card_name(c) {
@@ -1129,7 +1129,7 @@ states.setup_province = {
capital(where) {
push_undo()
- log(PLAYER_NAMES[game.current] + " started in %" + where + ".")
+ log(PLAYER_NAME[game.current] + " in %" + where + ".")
set_governor_location(game.current * 6 + 0, where)
@@ -1172,7 +1172,7 @@ states.setup_hand = {
// === UPKEEP ===
function goto_start_turn() {
- log_h1(PLAYER_NAMES[game.current])
+ log_h1(PLAYER_NAME[game.current])
game.killed = 0
game.battled = 0
@@ -1849,7 +1849,6 @@ states.take_actions = {
let hand = current_hand()
while (hand.length > 0) {
let c = hand[0]
- log("Played " + card_name(c) + ".")
set_delete(hand, c)
set_add(game.played, c)
add_card_ip(c)
@@ -1860,7 +1859,6 @@ states.take_actions = {
push_undo()
let hand = current_hand()
if (set_has(hand, c)) {
- log("Played " + card_name(c) + ".")
set_delete(hand, c)
set_add(game.played, c)
add_card_ip(c)
@@ -2096,7 +2094,7 @@ function increase_support(where) {
}
function remove_governor(where) {
- log("Removed Governor from %" + where + ".")
+ log("Removed governor from %" + where + ".")
eliminate_militia(where)
set_mobs(where, 0)
@@ -2918,27 +2916,24 @@ function play_flanking_maneuver() {
}
function goto_battle_vs_general(where, attacker, target) {
- log_h3("Battle " + PLAYER_NAMES[target/6|0] + " in %" + where)
goto_battle("general", where, attacker, target)
}
function goto_battle_vs_barbarian(where, attacker, target) {
let tribe = get_barbarian_tribe(target)
- log_h3("Battle " + BARBARIAN_NAME[tribe] + " in %" + where)
goto_battle("barbarians", where, attacker, tribe)
}
function goto_battle_vs_rival_emperor(where, attacker, target) {
- log_h3("Battle " + RIVAL_EMPEROR_NAME[target] + " in %" + where)
goto_battle("rival_emperor", where, attacker, target)
}
function goto_battle_vs_militia(where, attacker) {
- log_h3("Battle militia in %" + where)
goto_battle("militia", where, attacker, -1)
}
function goto_battle(type, where, attacker, target) {
+ log_h2("Battle in %" + where)
spend_military(1)
game.where = where
game.battle = { type, attacker, target, flanking: 0, killed: 0 }
@@ -2983,9 +2978,9 @@ function gen_initiate_battle(where) {
function format_battle_target() {
switch (game.battle.type) {
- case "militia": return PLAYER_NAMES[get_province_player(game.battle.target)] + " militia"
+ case "militia": return PLAYER_NAME[get_province_player(game.battle.target)] + " militia"
case "barbarians": return BARBARIAN_NAME[game.battle.target]
- case "general": return PLAYER_NAMES[game.battle.target / 6 | 0] + " army"
+ case "general": return PLAYER_NAME[game.battle.target / 6 | 0] + " army"
case "rival_emperor": return RIVAL_EMPEROR_NAME[game.battle.target]
}
}
@@ -3074,7 +3069,7 @@ function roll_general_dice(general) {
let drm = get_roman_drm()
- log(GENERAL_NAME[general])
+ log(PLAYER_NAME[general/6|0])
if (is_general_inside_capital(general) && has_militia(game.where)) {
log("Militia")
@@ -3425,6 +3420,8 @@ states.combat_victory = {
}
function goto_combat_victory() {
+ log_br()
+ log("VICTORY")
let de = is_defender_eliminated()
let ae = is_attacker_eliminated()
if (de && ae)
@@ -3437,9 +3434,9 @@ function goto_combat_victory() {
function award_legacy(p, reason, n) {
if (n > 0)
- log(PLAYER_NAMES[p] + " +" + n + " Legacy for " + reason + ".")
+ log(PLAYER_NAME[p] + " +" + n + " Legacy for " + reason + ".")
if (n < 0)
- log(PLAYER_NAMES[p] + " " + n + " Legacy for " + reason + ".")
+ log(PLAYER_NAME[p] + " " + n + " Legacy for " + reason + ".")
game.legacy[p] += n
}
@@ -3452,11 +3449,13 @@ function award_legacy_summary(p, reason, n) {
}
function goto_combat_no_victory() {
+ log("Nobody")
game.battle.killed = 0
end_battle()
}
function goto_combat_victory_defender() {
+ log("Defender")
game.battle.killed = 0
if (game.battle.type === "general")
award_legacy(game.battle.target / 6 | 0, "Victory", 2)
@@ -3466,6 +3465,8 @@ function goto_combat_victory_defender() {
}
function goto_combat_victory_attacker() {
+ log("Attacker")
+
if (game.battle.type === "barbarians") {
award_legacy(game.current, "Victory", 2 + game.battle.dtaken)
@@ -3570,6 +3571,8 @@ function goto_support_check() {
}
game.count = 0
+ if (needs_any_support_check())
+ log_h2("Support Check")
resume_support_check()
}
@@ -3583,18 +3586,24 @@ function is_any_rival_emperor_or_pretender() {
return false
}
+function needs_any_support_check() {
+ return needs_support_check() || needs_support_check_emperor() || needs_support_check_mobs()
+}
+
+function needs_support_check() {
+ for (let where = 0; where < 12; ++where)
+ if ((game.count & (1 << where)) === 0)
+ if (is_own_province(where))
+ if (has_active_barbarians(where) || has_rival_emperor(where) || has_enemy_general_in_capital(where))
+ return true
+ return false
+}
+
function resume_support_check() {
- for (let where = 0; where < 12; ++where) {
- if ((game.count & (1 << where)) === 0) {
- if (is_own_province(where)) {
- if (has_active_barbarians(where) || has_rival_emperor(where) || has_enemy_general_in_capital(where)) {
- game.state = "support_check"
- return
- }
- }
- }
- }
- goto_support_check_emperor()
+ if (needs_support_check())
+ game.state = "support_check"
+ else
+ goto_support_check_emperor()
}
states.support_check = {
@@ -3611,17 +3620,21 @@ states.support_check = {
region(where) {
push_undo()
game.count |= (1 << where)
+ log("Reduced support level in %" + where + ".")
reduce_support(where)
resume_support_check()
},
}
+function needs_support_check_emperor() {
+ return is_emperor_player() && is_any_rival_emperor_or_pretender()
+}
+
function goto_support_check_emperor() {
- if (is_emperor_player() && is_any_rival_emperor_or_pretender()) {
+ if (needs_support_check_emperor())
game.state = "support_check_emperor"
- return
- }
- goto_support_check_mobs()
+ else
+ goto_support_check_mobs()
}
states.support_check_emperor = {
@@ -3634,19 +3647,23 @@ states.support_check_emperor = {
region(where) {
push_undo()
game.count |= (1 << where)
+ log("Reduced support level in %" + where + ".")
reduce_support(where)
goto_support_check_mobs()
},
}
+function needs_support_check_mobs() {
+ for (let where = 0; where < 12; ++where)
+ if (is_own_province(where) && get_mobs(where) >= get_support(where))
+ return true
+}
+
function goto_support_check_mobs() {
- for (let where = 0; where < 12; ++where) {
- if (is_own_province(where) && get_mobs(where) >= get_support(where)) {
- game.state = "support_check_mobs"
- return
- }
- }
- goto_expand_pretender_empire()
+ if (needs_support_check_mobs())
+ game.state = "support_check_mobs"
+ else
+ goto_expand_pretender_empire()
}
states.support_check_mobs = {
@@ -3660,6 +3677,7 @@ states.support_check_mobs = {
},
region(where) {
push_undo()
+ log("More mobs than support in %" + where + ".")
remove_governor(where)
goto_support_check_mobs()
},
@@ -3670,6 +3688,7 @@ states.support_check_mobs = {
function goto_expand_pretender_empire() {
for (let where = 1; where < 12; ++where) {
if (is_expand_pretender_province(where)) {
+ log_h4("Expand Pretender Empire")
game.state = "expand_pretender_empire"
return
}
@@ -3688,6 +3707,7 @@ states.expand_pretender_empire = {
},
region(where) {
push_undo()
+ logi("Breakaway %" + where)
add_breakaway(where)
remove_quaestor(where) // no effect anymore
goto_expand_pretender_empire()
@@ -3697,8 +3717,7 @@ states.expand_pretender_empire = {
// === GAIN LEGACY ===
function goto_gain_legacy() {
- log_br()
- log("Gain Legacy")
+ log_h4("Gain Legacy")
if (is_only_pretender_player())
award_legacy_summary(game.current, "Pretender", count_own_breakaway_provinces())
@@ -3768,11 +3787,16 @@ function count_political_points() {
}
function goto_buy_trash_cards() {
+ //log_h4("Played")
+ //logi(game.played.map(c=>card_name(c)).join(", "))
+ log_br()
+ log("Played " + game.played.map(c=>card_name(c)).join(", ") + ".")
log_br()
let discard = current_discard()
for (let c of game.played)
set_add(discard, c)
+
game.played.length = 0
game.count = 0
game.pp = count_political_points()
@@ -3795,6 +3819,7 @@ states.buy_trash_discard = {
},
card(c) {
push_undo()
+ log("Discarded " + card_name(c) + ".")
set_delete(current_hand(), c)
set_add(current_discard(), c)
},
@@ -4070,6 +4095,12 @@ function vp_tie(p) {
function goto_game_end() {
log_h2("Game End")
+ game.crisis[0] = -1
+ game.crisis[1] = 0
+ game.crisis[2] = 0
+ game.crisis[3] = 0
+ game.crisis[4] = 0
+
let cutoff = award_emperor_turns(10, 1000)
cutoff = award_emperor_turns(6, cutoff)
cutoff = award_emperor_turns(3, cutoff)
@@ -4077,7 +4108,7 @@ function goto_game_end() {
let victor = game.legacy.map((legacy,p) => [vp_tie(p),p]).sort((a,b) => b[0] - a[0])[0][1]
- goto_game_over(PLAYER_NAMES[victor], PLAYER_NAMES[victor] + " won!")
+ goto_game_over(PLAYER_NAME[victor], PLAYER_NAME[victor] + " won!")
}
function goto_game_over(result, victory) {
@@ -4236,7 +4267,7 @@ function load_game(state) {
}
function save_game() {
- game.active = PLAYER_NAMES[game.current]
+ game.active = PLAYER_NAME[game.current]
return game
}
@@ -4292,7 +4323,7 @@ exports.view = function (state, player_name) {
view.prompt = game.victory
} else if (game.current !== player) {
let inactive = states[game.state].inactive || game.state
- view.prompt = `Waiting for ${PLAYER_NAMES[game.current]}: ${inactive}.`
+ view.prompt = `Waiting for ${PLAYER_NAME[game.current]}: ${inactive}.`
} else {
view.actions = {}
states[game.state].prompt()