From 5b91837ae8c298ca0110854c48a1bf2fb6bea69a Mon Sep 17 00:00:00 2001 From: Tor Andersson Date: Thu, 22 Jun 2023 12:29:34 +0200 Subject: Gain Legacy. --- rules.js | 244 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file 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: [], -- cgit v1.2.3