summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--rules.js244
1 files changed, 210 insertions, 34 deletions
diff --git a/rules.js b/rules.js
index 410cb39..bdac983 100644
--- a/rules.js
+++ b/rules.js
@@ -33,19 +33,15 @@ game.battle -> game.battle / game.count + game.where
[x] remove at start
[x] remove when replaced
-[ ] castra
+[x] castra
[x] place
[x] remove at start
[x] remove when move/attack
- [ ] move militia to general at end of turn
+ [x] move militia to general at end of turn
[x] remove when retreat
[x] support check
-
-[ ] gain legacy
- [ ] emperor
- [ ] provinces
- [ ] improvements
+[x] gain legacy
[x] end turn
[x] grow mobs
@@ -765,7 +761,7 @@ function is_own_province(where) {
return is_own_governor(get_province_governor(where))
}
-function is_emperor(governor) {
+function is_emperor_governor(governor) {
let emperor = get_province_governor(ITALIA)
if (emperor >= 0 && governor >= 0)
return (emperor / 6 | 0) === (governor / 6 | 0)
@@ -879,6 +875,45 @@ function count_units_in_army(id) {
return n
}
+function is_emperor_player() {
+ return is_own_province(ITALIA)
+}
+
+function is_pretender_player() {
+ for (let where = 1; where < 12; ++where)
+ if (is_seat_of_power(where) || is_breakaway(where))
+ if (is_own_province(where))
+ return true
+ return false
+}
+
+function is_only_pretender_player() {
+ let result = false
+ for (let where = 1; where < 12; ++where)
+ if (is_seat_of_power(where))
+ if (is_own_province(where))
+ result = true
+ else
+ return false
+ return result
+}
+
+function count_pretender_provinces() {
+ let n = 0
+ for (let where = 1; where < 12; ++where)
+ if (is_seat_of_power(where) || is_breakaway(where))
+ ++n
+ return n
+}
+
+function count_own_breakaway_provinces() {
+ let n = 0
+ for (let where = 0; where < 12; ++where)
+ if (is_own_province(where) && (is_seat_of_power(where) || is_breakaway(where)))
+ ++n
+ return n
+}
+
function count_own_provinces() {
let n = 0
for (let where = 0; where < 12; ++where)
@@ -887,6 +922,21 @@ function count_own_provinces() {
return n
}
+function count_own_improvements() {
+ let n = 0
+ for (let where = 0; where < 12; ++where) {
+ if (is_own_province(where)) {
+ if (has_amphitheater(where))
+ ++n
+ if (has_basilica(where))
+ ++n
+ if (has_limes(where))
+ ++n
+ }
+ }
+ return n
+}
+
function count_own_basilicas() {
let n = 0
for (let where = 0; where < 12; ++where)
@@ -1639,7 +1689,7 @@ function remove_governor(where) {
let old_governor = get_province_governor(where)
if (old_governor >= 0) {
set_governor_location(old_governor, AVAILABLE)
- if (where !== ITALIA && is_emperor(old_governor))
+ if (where !== ITALIA && is_emperor_governor(old_governor))
reduce_support(ITALIA)
}
@@ -1657,7 +1707,7 @@ function place_governor(where, new_governor) {
let old_governor = get_province_governor(where)
if (old_governor >= 0) {
set_governor_location(old_governor, AVAILABLE)
- if (where !== ITALIA && is_emperor(old_governor))
+ if (where !== ITALIA && is_emperor_governor(old_governor))
reduce_support(ITALIA)
}
@@ -1667,7 +1717,7 @@ function place_governor(where, new_governor) {
else
game.support[where] = Math.max(1, game.support[where] - 1)
- if (where !== ITALIA && is_emperor(new_governor))
+ if (where !== ITALIA && is_emperor_governor(new_governor))
increase_support(ITALIA)
update_neutral_italia()
@@ -1780,7 +1830,7 @@ function roll_to_place_governor(pg) {
// ACTION: PRAETORIAN GUARD
function has_unused_praetorian_guard() {
- return game.ip[MILITARY] >= 1 && !is_own_province(ITALIA) && !has_placed_governor(ITALIA) && has_praetorian_guard_card()
+ return game.ip[MILITARY] >= 1 && !is_emperor_player() && !has_placed_governor(ITALIA) && has_praetorian_guard_card()
}
function has_praetorian_guard_card() {
@@ -1797,7 +1847,7 @@ function has_praetorian_guard_card() {
function can_play_praetorian_guard() {
if (game.selected_governor >= 0 && get_governor_location(game.selected_governor) === AVAILABLE)
- return game.ip[MILITARY] >= 1 && !is_own_province(ITALIA) && !has_placed_governor(ITALIA)
+ return game.ip[MILITARY] >= 1 && !is_emperor_player() && !has_placed_governor(ITALIA)
return false
}
@@ -2454,30 +2504,31 @@ function goto_combat_victory() {
goto_combat_victory_defender()
}
-function award_legacy(p, n) {
- log(PLAYER_NAMES[p] + " gained " + n + " VP.")
+function award_legacy(p, reason, n) {
+ log(PLAYER_NAMES[p] + " gained " + n + " Legacy for " + reason + ".")
game.legacy[p] += n
}
function goto_combat_victory_defender() {
if (game.battle.type === "general")
- award_legacy(game.battle.target / 6 | 0, 2)
+ award_legacy(game.battle.target / 6 | 0, "Victory", 2)
if (game.battle.type === "militia")
- award_legacy(get_province_governor(game.where) / 6 | 0, 2)
+ award_legacy(get_province_governor(game.where) / 6 | 0, "Victory", 2)
end_battle()
}
function goto_combat_victory_attacker() {
- award_legacy(game.current, 2)
if (game.battle.type === "barbarians") {
- award_legacy(game.current, game.battle.dtaken)
+ award_legacy(game.current, "Victory", 2 + game.battle.dtaken)
// Surviving Barbarians go home (to active)
let tribe = get_barbarian_tribe(game.battle.target)
for (let id = first_barbarian[tribe]; id <= last_barbarian[tribe]; ++id)
if (get_barbarian_location(id) === game.battle)
set_barbarian_location(id, BARBARIAN_HOMELAND[tribe])
+ } else {
+ award_legacy(game.current, "Victory", 2)
}
// Defending Romans must retreat into province
@@ -2569,7 +2620,7 @@ states.support_check = {
}
function goto_support_check_emperor() {
- if (is_own_province(ITALIA) && is_any_rival_emperor_or_pretender()) {
+ if (is_emperor_player() && is_any_rival_emperor_or_pretender()) {
game.state = "support_check_emperor"
return
}
@@ -2627,6 +2678,57 @@ function goto_expand_pretender_empire() {
// === GAIN LEGACY ===
function goto_gain_legacy() {
+ log_h3("Gain Legacy")
+
+ if (is_only_pretender())
+ award_legacy(game.current, "Pretender", count_own_breakaway_provinces())
+
+ if (is_emperor_player())
+ goto_legitimize_claim()
+ else
+ goto_gain_legacy_provinces()
+}
+
+function goto_legitimize_claim() {
+ if (is_pretender_player())
+ game.state = "legitimize_claim"
+ else
+ goto_gain_legacy_emperor()
+}
+
+states.legitimize_claim = {
+ prompt() {
+ prompt("Gain Legacy: Remove Seat of Power and Breakaway markers in your provinces.")
+ for (let where = 1; where < 12; ++where) {
+ if (is_own_province(where) && is_seat_of_power(where) || is_breakaway(where)) {
+ gen_action_region(where)
+ },
+ region(where) {
+ push_undo()
+ remove_seat_of_power(where)
+ remove_breakaway(where)
+ goto_legitimize_claim()
+ },
+}
+
+function goto_gain_legacy_emperor() {
+ award_legacy(game.current, "Emperor", Math.max(0, game.support[ITALIA] - count_pretender_provinces()))
+ if (!is_any_rival_emperor_or_pretender()) {
+ log(PLAYER_NAMES[game.current] + " gained Emperor Turn")
+ game.emperor_turns[game.current] += 1
+ }
+ goto_gain_legacy_provinces()
+}
+
+function goto_gain_legacy_provinces() {
+ award_legacy(game.current, "Provinces", count_own_provinces())
+ award_legacy(game.current, "Improvements", count_own_improvements())
+
+ if (is_emperor_player() && game.legacy[game.current] >= 60) {
+ log("Game will end after this round!")
+ game.end = 1
+ }
+
goto_buy_trash_cards()
}
@@ -2648,11 +2750,12 @@ function goto_buy_trash_cards() {
for (let c of game.played)
set_add(discard, c)
game.played.length = 0
- game.battle = {
- count: 0,
- pp: count_political_points(),
- }
- if (current_hand().length > 0)
+ game.count = 0
+ game.pp = count_political_points()
+
+ if (game.end)
+ goto_end_of_turn()
+ else if (current_hand().length > 0)
game.state = "buy_trash_discard"
else
game.state = "buy_trash"
@@ -2685,9 +2788,9 @@ function find_market_with_card(c) {
states.buy_trash = {
prompt() {
- prompt("Buy/Trash cards: " + game.battle.pp + "PP left.")
+ prompt("Buy/Trash cards: " + game.pp + "PP left.")
let nprov = count_own_provinces()
- if (game.battle.pp >= 3) {
+ if (game.pp >= 3) {
for (let c of current_discard())
gen_action_card(c)
}
@@ -2697,8 +2800,8 @@ states.buy_trash = {
let cost = card_cost(c)
if (cost > nprov)
cost *= 2
- cost += game.battle.count
- if (game.battle.pp >= cost)
+ cost += game.count
+ if (game.pp >= cost)
gen_action_card(c)
}
}
@@ -2709,7 +2812,7 @@ states.buy_trash = {
if (set_has(current_discard(), c)) {
log("Trashed " + card_name(c))
set_delete(current_discard(), c)
- game.battle.pp -= 3
+ game.pp -= 3
} else {
log("Bought " + card_name(c))
set_add(current_discard(), c)
@@ -2717,9 +2820,9 @@ states.buy_trash = {
let cost = card_cost(c)
if (cost > count_own_provinces())
cost *= 2
- cost += game.battle.count
- game.battle.pp -= cost
- game.battle.count += 1
+ cost += game.count
+ game.pp -= cost
+ game.count += 1
}
},
done() {
@@ -2834,7 +2937,79 @@ states.refill_hand = {
function end_refill_hand() {
game.current = next_player()
- goto_start_turn()
+ if (game.current === game.first && game.end)
+ goto_game_end()
+ else
+ goto_start_turn()
+}
+
+// === GAME END ===
+
+function max_emperor_turns(cutoff) {
+ let n = 0
+ for (let x of game.emperor_turns)
+ if (x > n && x < cutoff)
+ n = x
+ return n
+}
+
+function award_emperor_turns(amount, cutoff) {
+ let x = max_emperor_turns(cutoff)
+ if (x > 0) {
+ for (let p = 0; p < game.legacy.length; ++p)
+ if (game.emperor_turns[p] === x)
+ award_legacy(p, "Emperor Turns", amount)
+ }
+ return x
+}
+
+function vp_tie(p) {
+ let vp = game.legacy[p] * 100000
+
+ game.current = p
+ if (is_emperor_player())
+ vp += 10000
+ if (is_pretender_player())
+ vp += 1000
+ vp += count_own_provinces() * 100
+ vp += count_own_legions() * 10
+ vp += random(10)
+
+ return vp
+}
+
+function goto_game_end() {
+ let cutoff = 1000
+
+ log_h2("Game End")
+
+ cutoff = award_emperor_turns(10, cutoff)
+ cutoff = award_emperor_turns(6, cutoff)
+ cutoff = award_emperor_turns(3, cutoff)
+ cutoff = award_emperor_turns(0, cutoff)
+
+ 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!")
+}
+
+function goto_game_over(result, victory) {
+ game.state = "game_over"
+ game.active = "None"
+ game.result = result
+ game.victory = victory
+ log_h1("Game Over")
+ log(game.victory)
+ return true
+}
+
+states.game_over = {
+ get inactive() {
+ return game.victory
+ },
+ prompt() {
+ view.prompt = game.victory
+ },
}
// === SETUP ===
@@ -2893,6 +3068,7 @@ exports.setup = function (seed, scenario, options) {
active_events: [],
ip: [],
+ pp: 0,
selected_governor: -1,
selected_general: -1,
played: [],