diff options
Diffstat (limited to 'rules.ts')
-rw-r--r-- | rules.ts | 724 |
1 files changed, 300 insertions, 424 deletions
@@ -4,30 +4,17 @@ // TODO: log end victory conditions at scenario start // Check all push/clear_undo // TODO: check all who = NOBODY etc resets -// TODO: call end_influence_check earlier when possible? -// TODO: use game.command instead of game.who for levy -- can we avoid saving who and count in push_state? -// TODO: can we simplify push_state to not push count and who? // TODO: verify all push_state uses // TODO check all game.count uses // TODO check all game.who uses /* TODO - NAVAL BLOCKADE - Tax and Tax Collectors - TODO - rewrite influence checks to be sane... - check and balance all init_influence_check / do_influence_check / end_influence_check - - revisit remaining game.flags - jack cade - - Battle resolution order (engagement / step nesting) + // use game.command instead of game.who for muster + // then we can drop push_state who/count stashing - Y30 REGROUP - before strike, after hits, before end - Y36 VANGUARD - before round 1 engagement + NAVAL BLOCKADE - Tax and Tax Collectors Y15 LONDON FOR YORK (protective effects + ui) extra favour marker in magic locale @@ -134,7 +121,6 @@ interface Game { burgundians: 0 | 1, first_action: 0 | 1, first_march_highway: 0 | 1, - jack_cade: 0 | 1 | 2, march_to_port: 0 | 1, sail_to_port: 0 | 1, supply_depot: 0 | 1, @@ -144,6 +130,7 @@ interface Game { levy_flags?: { gloucester_as_heir: number, + jack_cade: number, loyalty_and_trust: number, my_crown_is_in_my_heart: number, parliament_votes: number, @@ -170,8 +157,6 @@ interface Game { parley?: MyMap<Locale,number>, spoils?: number[], - check?: { cost: number, modifier: number, source: string }[], - /* temporary properties for various events */ event_scots?: Lord[], event_propaganda?: Locale[], @@ -216,6 +201,8 @@ interface State { undo?(_:any, current: Side): void, plan?(lord: Lord, current: Side): void, end_plan?(_:any, current: Side): void, + check?(bonus:number): void, + check_success?(): void, card?(card: Card): void, locale?(locale: Locale): void, @@ -251,7 +238,6 @@ interface State { agitators?(): void, approach?(): void, capability?(): void, - check?(): void, disband?(): void, discard?(): void, done?(): void, @@ -286,8 +272,6 @@ interface State { remove_favour?(): void, roll?(): void, sail?(): void, - spend1?(): void, - spend3?(): void, stronghold?(): void, supply?(): void, take_cart?(): void, @@ -1577,6 +1561,14 @@ function rout_vassal(_lord: Lord, vassal: Vassal) { set_add(game.battle.routed_vassals, vassal) } +function vassal_influence(vassal) { + // Influence Rating (positive for active side) + let rating = data.vassals[vassal].influence + if (game.active === LANCASTER) + return -rating + return rating +} + // === STATE: LOCALE === function is_favour_friendly(loc: Locale) { @@ -1842,7 +1834,9 @@ function increase_lancaster_influence(amt: number) { game.influence += amt } -// Bonus score but still maxed at 5 +/* + +// Bonus score but still maxed at 5 --- TODO this wasn't used, find out where it's needed function influence_capabilities(lord: Lord, score: number) { let here = get_lord_locale(lord) if (game.active === YORK && is_event_in_play(EVENT_YORK_YORKIST_PARADE)) @@ -1868,141 +1862,122 @@ function influence_capabilities(lord: Lord, score: number) { return score } -// Cards that allows automatic success -function automatic_success(lord: Lord, score) { - - if (lord_has_capability(lord, AOW_LANCASTER_TWO_ROSES)) - score = 6 - if (game.active === LANCASTER - && is_event_in_play(EVENT_LANCASTER_THE_EARL_OF_RICHMOND) - && game.state === "levy_muster_vassal") - score = 6 - if (game.active === LANCASTER - && game.levy_flags.parliament_votes === 1 - && game.state === "parley") - score = 6 - if (game.active === YORK - && game.flags.jack_cade > 0 - && game.state === "parley") - score = 6 - if (game.active === YORK - && is_levy_phase() - && game.levy_flags.succession === 1 - && game.state === "parley") - score = 6 - if (is_campaign_phase() - && game.command === LORD_DEVON - && get_lord_locale(LORD_DEVON) === LOC_EXETER - && is_event_in_play(EVENT_YORK_DORSET) - && game.state === "parley") - score = 6 - - return score -} +*/ -// Initiate influence check with cards influencing the cost overriding all others -// (even automatic at no cost) -function init_influence_check(lord: Lord) { - game.check = [] - game.check.push({ cost: 1, modifier: 0, source: "base" }) - game.check.push({ cost: 0, modifier: data.lords[lord].influence, source: "lord" }) - if (game.active === LANCASTER - && is_event_in_play(EVENT_YORK_AN_HONEST_TALE_SPEEDS_BEST) - && game.state === "parley"){ - game.check.push({ cost: 1, modifier: 0, source:"An Honest tale speeds best"}) - } - if (game.active === LANCASTER - && is_event_in_play(EVENT_LANCASTER_PARLIAMENT_VOTES) - && game.levy_flags.parliament_votes === 1 - && game.state === "parley") { - game.check.push({ cost: -1, modifier: 0, source:"Parliament Votes"}) - } - if (game.active === YORK - && is_event_in_play(EVENT_YORK_SUCCESSION) - && game.levy_flags.succession === 1 - && game.state === "parley") { - game.check.push({ cost: -1, modifier: 0, source:"Succession"}) +function is_automatic_levy_vassal_success(lord: Lord) { + if (game.active === LANCASTER) { + if (is_event_in_play(EVENT_LANCASTER_THE_EARL_OF_RICHMOND)) + return true + if (lord_has_capability(lord, AOW_LANCASTER_TWO_ROSES)) + return true } + return false } -function end_influence_check() { - delete game.check -} - -function count_influence_score() { - let score = game.check.reduce((p, c) => p + c.modifier, 0) - - let lord = NOBODY - if (is_levy_phase()) - lord = game.who - if (is_campaign_phase()) - lord = game.command - - if (score > 5) - score = 5 - if (score < 1) - score = 1 - - score = automatic_success(lord, score) - - return score +function is_automatic_parley_success(lord: Lord) { + if (game.active === LANCASTER) { + if (is_levy_phase()) { + if (game.levy_flags.parliament_votes > 0) + return true + } + } else { + if (is_levy_phase()) { + if (game.levy_flags.succession > 0) + return true + if (game.levy_flags.jack_cade > 0) + return true + } else { + if (lord === LORD_DEVON && get_lord_locale(LORD_DEVON) === LOC_EXETER && is_event_in_play(EVENT_YORK_DORSET)) + return true + } + } + return false } -function count_influence_cost() { - if (game.state === "parley") { - if (is_campaign_phase()) { - if (game.command === LORD_DEVON && get_lord_locale(LORD_DEVON) === LOC_EXETER && is_event_in_play(EVENT_YORK_DORSET)) - return 0 +function get_parley_influence_cost() { + let cost = map_get(game.parley, game.where, 0) + if (game.active === LANCASTER) { + if (is_event_in_play(EVENT_YORK_AN_HONEST_TALE_SPEEDS_BEST)) + cost += 1 + if (is_levy_phase()) { + if (game.levy_flags.parliament_votes > 0) + cost -= 1 } + } else { if (is_levy_phase()) { - if (game.flags.jack_cade > 0) - return 0 + if (game.levy_flags.succession > 0) + cost -= 1 + if (game.levy_flags.jack_cade > 0) + cost = 0 } } - return game.check.reduce((p, c) => p + c.cost, 0) + return cost } -function do_influence_check() { - reduce_influence(count_influence_cost()) - let rating = count_influence_score() - let roll = roll_die() - let success - - if (roll === 1 || rating === 6) - success = true - else if (roll === 6) - success = false - else - success = roll <= rating +function calc_influence_check_cost(bonus, add_cost) { + let cost = 1 + // TODO: "free" influence check specials + if (bonus === 1) + cost += 1 + if (bonus === 2) + cost += 3 + cost += add_cost + return cost +} - // TODO: print log message here instead of returning object - return { success: success, rating: rating, roll: roll } +function calc_influence_check_rating(lord, bonus, add_rating) { + let rating = data.lords[lord].influence + rating += bonus + rating += add_rating + if (rating < 1) + rating = 1 + if (rating > 5) + rating = 5 + return rating } -function add_influence_check_modifier_1() { - game.check.push({ cost: 1, modifier: 1, source: "add" }) +function prompt_influence_check(lord: Lord, add_cost: number = 0, add_rating: number = 0) { + let cost = calc_influence_check_cost(0, add_cost) + let rating = calc_influence_check_rating(lord, 0, add_rating) + + view.prompt += ` Influence Check 1-${rating} for ${cost} IP.` + + /* max rating is 5, no need to pay to increase more! */ + if (rating <= 3) + view.actions.check = [ 0, 1, 2 ] + else if (rating <= 4) + view.actions.check = [ 0, 1 ] + else + view.actions.check = [ 0 ] } -function add_influence_check_modifier_2() { - game.check.push({ cost: 3, modifier: 2, source: "add" }) +function prompt_influence_check_success(add_cost: number = 0) { + let cost = calc_influence_check_cost(0, add_cost) + view.prompt += ` Influence Check for ${cost} IP.` + view.actions.check_success = 1 } -function add_influence_check_distance(distance) { - let idx = game.check.findIndex(i => i.source === "distance") +function roll_influence_check_success(add_cost: number = 0) { + let cost = calc_influence_check_cost(0, add_cost) + reduce_influence(cost) + log(`Influence Check Automatic`) + return true +} - if (idx >= 0) - game.check.splice(idx, 1) +function roll_influence_check(lord: Lord, bonus: number, add_cost: number = 0, add_rating: number = 0) { + let cost = calc_influence_check_cost(bonus, add_cost) + let rating = calc_influence_check_rating(lord, bonus, add_rating) - game.check.push({ cost: distance, modifier: 0, source: "distance" }) -} + reduce_influence(cost) -function prompt_influence_check() { - if (!game.check.some(c => c.source === "add")) { - view.actions.spend1 = 1 - view.actions.spend3 = 1 + let die = roll_die() + if (die <= rating) { + log(`Influence Check 1-${rating}: ${HIT[die]}`) + return true + } else { + log(`Influence Check 1-${rating}: ${MISS[die]}`) + return false } - view.actions.check = 1 - view.prompt += `Cost: ${count_influence_cost()} - Range (${range(count_influence_score())})` } // === 2.0 SETUP === @@ -2698,16 +2673,12 @@ function goto_ready_vassals() { // === 3.4 MUSTER === -function reset_flags_for_muster() { - // to avoid some flags affecting campaign - game.flags.jack_cade = 0 - game.levy_flags.parliament_votes = 0 -} - function goto_levy_muster() { + clear_lords_moved() game.levy_flags = { gloucester_as_heir: 0, + jack_cade: 0, loyalty_and_trust: 0, my_crown_is_in_my_heart: 0, parliament_votes: 0, @@ -2715,18 +2686,13 @@ function goto_levy_muster() { thomas_stanley: 0, } - for (let lord of all_friendly_lords()) { - clear_lords_moved() - // additionnal free specific actions - if (lord_has_capability(lord, AOW_LANCASTER_THOMAS_STANLEY)) - game.levy_flags.thomas_stanley = 1 - if (is_event_in_play(EVENT_LANCASTER_MY_CROWN_IS_IN_MY_HEART)) - game.levy_flags.my_crown_is_in_my_heart = 2 - if (is_event_in_play(EVENT_YORK_GLOUCESTER_AS_HEIR)) - game.levy_flags.gloucester_as_heir = 3 - if (is_event_in_play(EVENT_YORK_LOYALTY_AND_TRUST)) - game.levy_flags.loyalty_and_trust = 1 - } + if (is_event_in_play(EVENT_LANCASTER_MY_CROWN_IS_IN_MY_HEART)) + game.levy_flags.my_crown_is_in_my_heart = 2 + if (is_event_in_play(EVENT_YORK_GLOUCESTER_AS_HEIR)) + game.levy_flags.gloucester_as_heir = 3 + if (is_event_in_play(EVENT_YORK_LOYALTY_AND_TRUST)) + game.levy_flags.loyalty_and_trust = 1 + if (game.active === YORK) log_h2("York Muster") else @@ -2806,9 +2772,8 @@ states.levy_muster = { log(`Mustered with L${lord}.`) push_state("levy_muster_lord") game.who = lord - game.count = data.lords[lord].lordship - reset_flags_for_muster() - lordship_effects(lord) + game.actions = data.lords[lord].lordship + apply_lordship_effects(lord) }, end_muster() { end_levy_muster() @@ -2819,10 +2784,10 @@ states.levy_muster = { function resume_levy_muster_lord() { game.state = "levy_muster_lord" - --game.count + --game.actions // muster over only if the lord has not spend their free levy actions - if (game.count === 0 && game.flags.jack_cade === 0 && game.levy_flags.thomas_stanley === 0 && can_add_troops(game.who, get_lord_locale(game.who))) { + if (game.actions === 0 && game.levy_flags.jack_cade === 0 && game.levy_flags.thomas_stanley === 0 && can_add_troops(game.who, get_lord_locale(game.who))) { set_lord_moved(game.who, 1) pop_state() } @@ -2831,15 +2796,15 @@ function resume_levy_muster_lord() { states.levy_muster_lord = { inactive: "Muster", prompt() { - if (game.count === 1) - view.prompt = `Levy: ${lord_name[game.who]} has ${game.count} action.` + if (game.actions === 1) + view.prompt = `Levy: ${lord_name[game.who]} has ${game.actions} action.` else - view.prompt = `Levy: ${lord_name[game.who]} has ${game.count} actions.` + view.prompt = `Levy: ${lord_name[game.who]} has ${game.actions} actions.` let here = get_lord_locale(game.who) if (is_friendly_locale(here)) { - if (game.count > 0) { + if (game.actions > 0) { // Roll to muster Ready Lord at Seat for (let lord of all_friendly_lords()) { if (is_lord_ready(lord) && has_locale_to_muster(lord)) @@ -2881,26 +2846,26 @@ states.levy_muster_lord = { view.actions.commission_of_array = 1 } - if (game.count === 0 && lord_has_capability(game.who, AOW_LANCASTER_THOMAS_STANLEY) && can_add_troops(game.who, here)) { + if (game.actions === 0 && lord_has_capability(game.who, AOW_LANCASTER_THOMAS_STANLEY) && can_add_troops(game.who, here)) { view.actions.levy_troops = 1 } // Rising wages event if (is_event_in_play(EVENT_LANCASTER_RISING_WAGES) && !can_pay_from_shared(game.who)) { view.actions.levy_troops = 0 } - if (game.count === 0 && game.levy_flags.my_crown_is_in_my_heart > 0 && game.who === LORD_HENRY_VI) { + if (game.actions === 0 && game.levy_flags.my_crown_is_in_my_heart > 0 && game.who === LORD_HENRY_VI) { view.actions.parley = 1 } - if (game.count === 0 && game.levy_flags.gloucester_as_heir > 0 && (game.who === LORD_GLOUCESTER_2 || game.who === LORD_GLOUCESTER_1)) { + if (game.actions === 0 && game.levy_flags.gloucester_as_heir > 0 && (game.who === LORD_GLOUCESTER_2 || game.who === LORD_GLOUCESTER_1)) { view.actions.parley = 1 } - if (game.count === 0 && game.flags.jack_cade > 0) { + if (game.actions === 0 && game.levy_flags.jack_cade > 0) { view.actions.parley = 1 } } else { // Can only Parley if locale is not friendly. - if (game.count > 0) { + if (game.actions > 0) { if (can_action_parley_levy()) view.actions.parley = 1 } @@ -2987,12 +2952,12 @@ states.levy_muster_lord = { parley() { push_undo() push_the_kings_name() - goto_parley() + goto_parley_levy() }, loyalty_and_trust() { push_undo() - game.count += 3 + game.actions += 3 game.levy_flags.loyalty_and_trust = 0 }, @@ -3069,7 +3034,7 @@ function do_levy_troops() { break } if (game.levy_flags.thomas_stanley === 1) { - ++game.count + ++game.actions game.levy_flags.thomas_stanley = 0 } @@ -3081,29 +3046,20 @@ function do_levy_troops() { function goto_levy_muster_lord_attempt(lord: Lord) { game.other = lord push_state("levy_muster_lord_attempt") - init_influence_check(game.who) } states.levy_muster_lord_attempt = { inactive: "Levy Lord", prompt() { view.prompt = `Levy Lord ${lord_name[game.other]}. ` - prompt_influence_check() + prompt_influence_check(game.who) }, - spend1: add_influence_check_modifier_1, - spend3: add_influence_check_modifier_2, - check() { - let results = do_influence_check() - end_influence_check() - - log(`Attempt to levy L${game.other} ${results.success ? "Successful" : "Failed"}: (${range(results.rating)}) ${results.success ? HIT[results.roll] : MISS[results.roll]}`) - - if (results.success) { + check(bonus) { + if (roll_influence_check(game.who, bonus)) { pop_state() push_state("muster_lord_at_seat") game.who = game.other - } - else { + } else { pop_state() resume_levy_muster_lord() } @@ -3177,37 +3133,19 @@ function goto_levy_muster_vassal() { influence_cost += 2 push_state("levy_muster_vassal") - init_influence_check(game.who) - game.check.push({ - cost: influence_cost, - modifier: data.vassals[game.vassal].influence * (game.active === LANCASTER ? -1 : 1), - source: "vassal", - }) } states.levy_muster_vassal = { inactive: "Levy Vassal", prompt() { view.prompt = `Levy Vassal ${data.vassals[game.vassal].name}. ` - prompt_influence_check() + if (is_automatic_levy_vassal_success(game.who)) + prompt_influence_check_success() + else + prompt_influence_check(game.who, 0, vassal_influence(game.vassal)) }, - spend1: add_influence_check_modifier_1, - spend3: add_influence_check_modifier_2, - check() { - let results = do_influence_check() - end_influence_check() - - if (lord_has_capability(game.who, AOW_LANCASTER_TWO_ROSES)) { - log(`Automatic Success. C${AOW_LANCASTER_TWO_ROSES}.`) - } - else if (game.active === LANCASTER && is_event_in_play(EVENT_LANCASTER_THE_EARL_OF_RICHMOND)) { - log(`Automatic Success. C${EVENT_LANCASTER_THE_EARL_OF_RICHMOND}.`) - } - else { - log(`Attempt to levy V${game.vassal} ${results.success ? "Successful" : "Failed"}: (${range(results.rating)}) ${results.success ? HIT[results.roll] : MISS[results.roll]}`) - } - - if (results.success) { + check(bonus) { + if (roll_influence_check(game.who, bonus, 0, vassal_influence(game.vassal))) { muster_vassal(game.vassal, game.who) pop_state() goto_the_kings_name("Levy Vassal") @@ -3216,6 +3154,12 @@ states.levy_muster_vassal = { resume_levy_muster_lord() } }, + check_success() { + roll_influence_check_success() + muster_vassal(game.vassal, game.who) + pop_state() + goto_the_kings_name("Levy Vassal") + } } // === 3.4.4 LEVY TROOPS === @@ -3662,7 +3606,7 @@ states.command = { parley() { push_undo() - goto_parley() + goto_parley_campaign() }, } @@ -4263,7 +4207,6 @@ function goto_tax() { push_undo() game.state = "tax" game.where = NOWHERE - init_influence_check(game.command) } function end_tax() { @@ -4317,7 +4260,7 @@ states.tax = { gen_action_locale(loc) } else { view.prompt = `Tax: Attempt to Tax ${data.locales[game.where].name}. ` - prompt_influence_check() + prompt_influence_check(game.command) } }, locale(loc) { @@ -4328,12 +4271,8 @@ states.tax = { end_tax() } }, - spend1: add_influence_check_modifier_1, - spend3: add_influence_check_modifier_2, - check() { - let results = do_influence_check() - end_influence_check() - if (results.success) + check(bonus) { + if (roll_influence_check(game.command, bonus)) do_tax(game.command, game.where, 1) else log(`Tax %${game.where} failed.`) @@ -4426,10 +4365,9 @@ function can_action_parley_command() { return false } -function search_parley_campaign() { +function search_parley_campaign(here: Locale, lord: Lord) { let result = [] - let here = get_lord_locale(game.command) if (can_parley_at(here)) map_set(result, here, 0) @@ -4439,7 +4377,7 @@ function search_parley_campaign() { map_set(result, next, 1) if (is_exile(here) && count_shared_ships(here, false) > 0) - for (let next of find_ports(here, game.command)) + for (let next of find_ports(here, lord)) if (can_parley_at(next)) map_set(result, next, 1) } @@ -4448,10 +4386,10 @@ function search_parley_campaign() { } function can_action_parley_levy(): boolean { - if (game.count <= 0 + if (game.actions <= 0 && (game.who !== LORD_HENRY_VI || game.levy_flags.my_crown_is_in_my_heart === 0) && ((game.who !== LORD_GLOUCESTER_1 && game.who !== LORD_GLOUCESTER_2) || game.levy_flags.gloucester_as_heir === 0) - && (!game.flags.jack_cade)) + && (!game.levy_flags.jack_cade)) return true let here = get_lord_locale(game.who) if (can_parley_at(here)) @@ -4459,53 +4397,61 @@ function can_action_parley_levy(): boolean { return search_parley_levy(false, here, game.who) } -function goto_parley() { +function goto_parley_levy() { + let lord = game.who + let here = get_lord_locale(lord) + push_state("parley") - if (is_levy_phase()) { - init_influence_check(game.who) - game.parley = search_parley_levy([], get_lord_locale(game.who), game.who) - } else { - init_influence_check(game.command) - game.parley = search_parley_campaign() - - // Campaign phase, and current location is no cost (except some events), and always successful. - if (game.parley.length === 2 && get_lord_locale(game.command) === game.parley[0]) { - log(`Parley at ${data.locales[get_lord_locale(game.command)]}`) - shift_favour_toward(game.parley[0] as Locale) - if (is_lancaster_lord(game.command) && is_event_in_play(EVENT_YORK_AN_HONEST_TALE_SPEEDS_BEST)) { - reduce_lancaster_influence(1) - } - end_parley(true) - return - } - } + game.parley = search_parley_levy([], here, lord) - if (game.parley.length === 2) { - game.where = game.parley[0] as Locale - add_influence_check_distance(game.parley[1]) - } else { + if (game.parley.length === 2 && game.parley[0] === here) + game.where = here + else game.where = NOWHERE +} + +function goto_parley_campaign() { + let lord = game.command + let here = get_lord_locale(lord) + + push_state("parley") + + // Campaign phase, and current location is no cost (except some events), and always successful. + if (can_parley_at(here)) { + log(`Parley at ${data.locales[here]}`) + shift_favour_toward(here) + if (is_lancaster_lord(game.command) && is_event_in_play(EVENT_YORK_AN_HONEST_TALE_SPEEDS_BEST)) { + reduce_lancaster_influence(1) + } + end_parley(true) + return } + + game.parley = search_parley_campaign(here, lord) + game.where = NOWHERE } function end_parley(success: boolean) { pop_state() game.where = NOWHERE delete game.parley - if (game.levy_flags.my_crown_is_in_my_heart > 0 && game.who === LORD_HENRY_VI) { - --game.levy_flags.my_crown_is_in_my_heart - ++game.count - } - if (game.levy_flags.gloucester_as_heir > 0 && (game.who === LORD_GLOUCESTER_1 || game.who === LORD_GLOUCESTER_2)) { - --game.levy_flags.gloucester_as_heir - ++game.count - } - if (game.flags.jack_cade > 0) { - --game.flags.jack_cade - ++game.count + + // Free Levy Lordship action + if (is_levy_phase()) { + if (game.levy_flags.my_crown_is_in_my_heart > 0 && game.who === LORD_HENRY_VI) { + --game.levy_flags.my_crown_is_in_my_heart + ++game.actions + } + if (game.levy_flags.gloucester_as_heir > 0 && (game.who === LORD_GLOUCESTER_1 || game.who === LORD_GLOUCESTER_2)) { + --game.levy_flags.gloucester_as_heir + ++game.actions + } + if (game.levy_flags.jack_cade > 0) { + --game.levy_flags.jack_cade + ++game.actions + } } - end_influence_check() if (is_campaign_phase()) { if (game.active === YORK && is_event_in_play(EVENT_LANCASTER_NEW_ACT_OF_PARLIAMENT)) @@ -4529,14 +4475,17 @@ states.parley = { for (let i = 0; i < game.parley.length; i += 2) gen_action_locale(game.parley[i] as Locale) } else { - view.prompt = "Parley: " - prompt_influence_check() + let lord = is_levy_phase() ? game.who : game.command + view.prompt = "Parley at " + data.locales[game.where].name + "." + if (is_automatic_parley_success(lord)) + prompt_influence_check_success(get_parley_influence_cost()) + else + prompt_influence_check(lord, get_parley_influence_cost()) } }, locale(loc) { push_undo() game.where = loc - add_influence_check_distance(map_get(game.parley, loc, 0)) let here = get_lord_locale(is_levy_phase() ? game.who : game.command) if (!is_adjacent(here, loc)) { // TODO: check interaction of Naval Blockade with Great Ships when parleying across multiple seas @@ -4544,41 +4493,20 @@ states.parley = { game.state = "blockade_parley" } }, - spend1: add_influence_check_modifier_1, - spend3: add_influence_check_modifier_2, - check() { - let results = do_influence_check() - - if (game.levy_flags.parliament_votes === 1) { - log(`Parley at ${data.locales[game.where].name}. Automatic Success.`) - logevent(EVENT_LANCASTER_PARLIAMENT_VOTES) - game.levy_flags.parliament_votes = 0 - } - else if (game.flags.jack_cade > 0) { - log(`Parley at ${data.locales[game.where].name}. Automatic Success.`) - logevent(EVENT_YORK_JACK_CADE) - } - else if (game.levy_flags.succession === 1) { - log(`Parley at ${data.locales[game.where].name}. Automatic Success.`) - logevent(EVENT_YORK_SUCCESSION) - game.levy_flags.succession = 0 - } - else if (is_campaign_phase() - && game.command === LORD_DEVON - && get_lord_locale(LORD_DEVON) === LOC_EXETER - && is_event_in_play(EVENT_YORK_DORSET) - ) { - log(`Parley at ${data.locales[game.where].name}. Automatic Success. C${EVENT_YORK_DORSET}.`) - } - else - log(`Attempt to Parley at %${game.where} ${results.success ? "Successful" : "Failed"}: (${range(results.rating)}) ${results.success ? HIT[results.roll] : MISS[results.roll]}`) - if (results.success) { + check(bonus) { + let lord = is_levy_phase() ? game.who : game.command + if (roll_influence_check(lord, bonus, get_parley_influence_cost())) { shift_favour_toward(game.where) end_parley(true) } else { end_parley(false) } }, + check_success() { + roll_influence_check_success(get_parley_influence_cost()) + shift_favour_toward(game.where) + end_parley(true) + }, } states.blockade_parley = { @@ -6006,7 +5934,6 @@ states.suspicion_2 = { push_undo() game.other = lord game.state = "suspicion_3" - init_influence_check(game.who) }, } @@ -6014,15 +5941,12 @@ states.suspicion_3 = { inactive: "Suspicion", prompt() { view.prompt = `Suspicion` - prompt_influence_check() + prompt_influence_check(game.who) }, - spend1: add_influence_check_modifier_1, - spend3: add_influence_check_modifier_2, - check() { + check(bonus) { let other = game.other - let results = do_influence_check() - logi(`Attempt to disband ${data.lords[other].name} ${results.success ? "Successful" : "Failed"}: (${range(results.rating)}) ${results.success ? HIT[results.roll] : MISS[results.roll]}`) - if (results.success) { + + if (roll_influence_check(game.who, bonus)) { log(`${data.lords[other].name} disbanded`) remove_lord_from_battle(other) disband_lord(other) @@ -6032,7 +5956,6 @@ states.suspicion_3 = { game.who = NOBODY game.other = NOBODY - end_influence_check() resume_battle_events() }, } @@ -6094,12 +6017,6 @@ states.for_trust_not_him_vassal = { } function goto_influence_check_for_trust_not_him() { - init_influence_check(game.who) - game.check.push({ - cost: 0, - modifier: data.vassals[game.vassal].influence * (game.active === LANCASTER ? -1 : 1), - source: "vassal", - }) game.state = "for_trust_not_him_bribe" } @@ -6107,26 +6024,21 @@ states.for_trust_not_him_bribe = { inactive: `Influence check`, prompt() { view.prompt = `Influence check : Success bribes ${data.vassals[game.vassal].name} ` - prompt_influence_check() + if (is_automatic_levy_vassal_success(game.who)) + prompt_influence_check_success() + else + prompt_influence_check(game.who, 0, vassal_influence(game.vassal)) }, - spend1: add_influence_check_modifier_1, - spend3: add_influence_check_modifier_2, - check() { - let results = do_influence_check() - if (game.who === LORD_HENRY_TUDOR && lord_has_capability(LORD_HENRY_TUDOR, AOW_LANCASTER_TWO_ROSES)) { - logi(`Automatic success C${AOW_LANCASTER_TWO_ROSES}`) - } - else { - logi(`Attempt to bribe ${data.vassals[game.vassal].name} ${results.success ? "Successful" : "Failed"}: (${range(results.rating)}) ${results.success ? HIT[results.roll] : MISS[results.roll]}`) - } - if (results.success) { + check(bonus) { + if (roll_influence_check(game.who, bonus)) { muster_vassal(game.vassal, game.who) - end_influence_check() - end_for_trust_not_him() - } else { - end_influence_check() - end_for_trust_not_him() } + end_for_trust_not_him() + }, + check_success() { + roll_influence_check_success() + muster_vassal(game.vassal, game.who) + end_for_trust_not_him() }, } @@ -6239,7 +6151,6 @@ states.culverins_and_falconets = { logi(`${data.lords[lord].name} Artillery does ${die1} hits`) } - if (is_attacker()) game.battle.attacker_artillery = (die1 + die2) else @@ -6307,7 +6218,7 @@ function is_vanguard_in_battle() { states.vanguard = { prompt() { - view.prompt = "Vanguard: This Lord may choose his Engagement to be the only one." + view.prompt = "Vanguard: Norfolk may choose his Engagement to be the only one." view.actions.vanguard = 1 view.actions.done = 1 }, @@ -6716,6 +6627,9 @@ function goto_total_hits() { game.battle.ahits = ahits game.battle.dhits = dhits + log_hits(ahits, "ATK TOTAL") + log_hits(dhits, "DEF TOTAL") + game.battle.target = null game.battle.final_charge = 0 @@ -8528,7 +8442,6 @@ exports.setup = function (seed, scenario, options) { burgundians: 0, first_action: 0, first_march_highway: 0, - jack_cade: 0, london_for_york: 0, march_to_port: 0, sail_to_port: 0, @@ -9476,9 +9389,11 @@ function get_main_lancaster_heir() { */ -// === CAPABILITY: MUSTER EFFECTS === +// === CAPABILITY MUSTER EFFECTS === // When a lord levies a capability, its muster vassal applies instantly. +// When a lord levies a capability, its +Lordship effects apply instantly. + function capability_muster_effects(lord: Lord, c: Card) { if (c === AOW_LANCASTER_MONTAGU) muster_vassal(VASSAL_MONTAGU, lord) @@ -9503,10 +9418,10 @@ function capability_muster_effects(lord: Lord, c: Card) { } if (c === AOW_YORK_FAIR_ARBITER && is_friendly_locale(get_lord_locale(LORD_SALISBURY))) { - game.count += 1 + game.actions += 1 } if (c === AOW_YORK_FALLEN_BROTHER && !is_lord_in_play(LORD_CLARENCE)) { - game.count += 1 + game.actions += 1 } if (AOW_YORK_BURGUNDIANS.includes(c)) { @@ -9521,27 +9436,32 @@ function capability_muster_effects(lord: Lord, c: Card) { } } -// === CAPABILITY: LORDSHIP EFFECTS === +// === LORDSHIP AND THIS LEVY EFFECTS === + +function apply_lordship_effects(lord: Lord) { -// When a lord levies a capability, its +Lordship effects apply instantly. -function lordship_effects(lord: Lord) { if (is_friendly_locale(get_lord_locale(lord)) && lord_has_capability(lord, AOW_YORK_FAIR_ARBITER)) - game.count += 1 + game.actions += 1 if (lord_has_capability(lord, AOW_YORK_FALLEN_BROTHER) && !is_lord_in_play(LORD_CLARENCE)) - game.count += 1 + game.actions += 1 if (is_event_in_play(EVENT_YORK_EDWARD_V) && (lord === LORD_GLOUCESTER_1 || lord === LORD_GLOUCESTER_2)) - game.count += 3 + game.actions += 3 + + game.levy_flags.thomas_stanley = 0 + if (lord_has_capability(lord, AOW_LANCASTER_THOMAS_STANLEY)) + game.levy_flags.thomas_stanley = 1 - if (is_lancaster_lord(lord) && is_event_in_play(EVENT_LANCASTER_PARLIAMENT_VOTES)) { + game.levy_flags.parliament_votes = 0 + if (is_event_in_play(EVENT_LANCASTER_PARLIAMENT_VOTES)) game.levy_flags.parliament_votes = 1 - } - if (is_york_lord(lord) && is_event_in_play(EVENT_YORK_SUCCESSION)) { + + game.levy_flags.succession = 0 + if (is_event_in_play(EVENT_YORK_SUCCESSION)) game.levy_flags.succession = 1 - } - if (is_york_lord(lord) && is_jack_cade_eligible(lord)) { - game.flags.jack_cade = 2 - } + game.levy_flags.jack_cade = 0 + if (is_jack_cade_eligible(lord)) + game.levy_flags.jack_cade = 2 } // === CAPABILITY: SOLDIERS OF FORTUNE === @@ -9603,7 +9523,7 @@ states.soldiers_of_fortune = { break } if (game.levy_flags.thomas_stanley === 1) { - ++game.count + ++game.actions game.levy_flags.thomas_stanley = 0 } if (number === 5) @@ -9677,7 +9597,7 @@ states.commission_of_array = { break } if (game.levy_flags.thomas_stanley === 1) { - ++game.count + ++game.actions game.levy_flags.thomas_stanley = 0 } end_commission_of_array() @@ -9754,30 +9674,21 @@ function can_action_merchants() { function goto_merchants() { game.count = count_deplete(get_lord_locale(game.command)) game.state = "merchants" - init_influence_check(game.command) } states.merchants = { inactive: "Merchants", prompt() { view.prompt = "Merchants: Succeed an influence check to remove Depleted markers" - prompt_influence_check() - }, - spend1: add_influence_check_modifier_1, - spend3: add_influence_check_modifier_2, - check() { - let results = do_influence_check() - log(`Attempt to C${AOW_LANCASTER_MERCHANTS} with %${game.command} ${results.success ? "Successful" : "Failed"}: (${range(results.rating)}) ${results.success ? HIT[results.roll] : MISS[results.roll]}`) - if (results.success) { - merchants_success() - } else { + prompt_influence_check(game.command) + }, + check(bonus) { + if (roll_influence_check(game.command, bonus)) + game.state = "merchants_success" + else end_merchants_attempt() - } } } -function merchants_success() { - game.state = "merchants_success" -} states.merchants_success = { inactive: "Merchants Success", @@ -9806,7 +9717,6 @@ function end_merchants_attempt() { spend_action(1) game.count = 0 push_undo() - end_influence_check() resume_command() } @@ -9972,31 +9882,23 @@ states.heralds = { function goto_heralds_attempt(lord: Lord) { game.other = lord game.state = "heralds_attempt" - init_influence_check(game.command) } states.heralds_attempt = { inactive: "Heralds Attempt", prompt() { view.prompt = `Attempt to shift ${lord_name[game.other]} to next Turn Box. ` - prompt_influence_check() + prompt_influence_check(game.command) }, - spend1: add_influence_check_modifier_1, - spend3: add_influence_check_modifier_2, - check() { - let results = do_influence_check() - log(`Attempt to shift L${game.other} ${results.success ? "Successful" : "Failed"}: (${range(results.rating)}) ${results.success ? HIT[results.roll] : MISS[results.roll]}`) - - if (results.success) { + check(bonus) { + if (roll_influence_check(game.command, bonus)) { set_lord_calendar(game.other, current_turn() + 1) } - end_heralds_attempt() }, } function end_heralds_attempt() { - end_influence_check() spend_all_actions() resume_command() } @@ -10559,9 +10461,9 @@ function goto_lancaster_event_luniverselle_aragne() { } states.aragne_1 = { - inactive: "L'universelle Aragne", + inactive: "L'Universelle Aragne", prompt() { - view.prompt = "Select up to 2 Vassals" + view.prompt = "L'Universelle Aragne: Select up to 2 Vassals" if (game.event_aragne.length < 2) { for (let v of all_vassals) { if (!set_has(game.event_aragne, v) && is_vassal_mustered_with_york_lord(v)) { @@ -10588,9 +10490,9 @@ function goto_yorkist_aragne() { } states.aragne_2 = { - inactive: "Influence checks", + inactive: "L'Universelle Aragne", prompt() { - view.prompt = `For Each vassal, influence check : failure disbands it` + view.prompt = `L'Universelle Aragne: Influence check for each selected Vassal.` let done = true for (let v of game.event_aragne) { gen_action_vassal(v) @@ -10599,15 +10501,9 @@ states.aragne_2 = { if (done) view.actions.done = 1 }, - vassal(other) { + vassal(v) { push_undo() - game.vassal = other - init_influence_check(get_vassal_lord(other)) - game.check.push({ - cost: 0, - modifier: data.vassals[other].influence * (game.active === LANCASTER ? -1 : 1), - source: "vassal", - }) + game.vassal = v game.state = "aragne_3" }, done() { @@ -10616,23 +10512,17 @@ states.aragne_2 = { } states.aragne_3 = { - inactive: `Influence check`, + inactive: "L'Universelle Aragne", prompt() { - view.prompt = `Influence check : Failure disbands ${data.vassals[game.vassal].name}` - prompt_influence_check() + view.prompt = `L'Universelle Aragne: ${data.vassals[game.vassal].name}.` + let lord = get_vassal_lord(game.vassal) + prompt_influence_check(lord, 0, vassal_influence(game.vassal)) }, - spend1: add_influence_check_modifier_1, - spend3: add_influence_check_modifier_2, - check() { - let results = do_influence_check() - logi(`Attempt to save ${data.vassals[game.vassal].name} ${results.success ? "Successful" : "Failed"}: (${range(results.rating)}) ${results.success ? HIT[results.roll] : MISS[results.roll]}`) - - if (!results.success) { + check(bonus) { + let lord = get_vassal_lord(game.vassal) + if (roll_influence_check(lord, bonus, 0, vassal_influence(game.vassal))) { disband_vassal(game.vassal) } - - end_influence_check() - set_delete(game.event_aragne, game.vassal) game.vassal = NOVASSAL game.state = "aragne_2" @@ -10822,7 +10712,6 @@ states.tax_collectors = { game.where = NOWHERE game.who = lord game.state = "tax_collectors_lord" - init_influence_check(lord) }, done() { end_tax_collectors() @@ -10838,7 +10727,7 @@ states.tax_collectors_lord = { gen_action_locale(loc) } else { view.prompt = `Tax Collectors: Attempt to Tax ${data.locales[game.where].name}. ` - prompt_influence_check() + prompt_influence_check(game.who) } }, locale(loc) { @@ -10849,18 +10738,11 @@ states.tax_collectors_lord = { end_tax_collectors_lord() } }, - spend1: add_influence_check_modifier_1, - spend3: add_influence_check_modifier_2, - check() { - let results = do_influence_check() - logi(`Tax: ${results.success ? "Successful" : "Failed"}: (${range(results.rating)}) ${results.success ? HIT[results.roll] : MISS[results.roll]}`) - end_influence_check() - - if (results.success) + check(bonus) { + if (roll_influence_check(game.who, bonus)) do_tax(game.where, game.who, 2) else log(`Tax %${game.where} failed.`) - end_tax_collectors_lord() }, } @@ -11003,7 +10885,6 @@ function goto_dubious_clarence() { if (can_play) { game.state = "dubious_clarence" game.who = LORD_EDWARD_IV - init_influence_check(LORD_EDWARD_IV) } else { logi(`No Effect`) end_immediate_event() @@ -11014,20 +10895,13 @@ states.dubious_clarence = { inactive: "Dubious Clarence", prompt() { view.prompt = `You may Influence check with Edward to disband Clarence ` - prompt_influence_check() + prompt_influence_check(game.who) }, - spend1: add_influence_check_modifier_1, - spend3: add_influence_check_modifier_2, - check() { - let results = do_influence_check() - log(`Attempt to disband Clarence ${results.success ? "Successful" : "Failed"}: (${range(results.rating)}) ${results.success ? HIT[results.roll] : MISS[results.roll]}`) - - if (results.success) { + check(bonus) { + if (roll_influence_check(game.who, bonus)) { disband_lord(LORD_CLARENCE, false) - end_immediate_event() - } else { - end_immediate_event() } + end_immediate_event() }, } @@ -11262,14 +11136,16 @@ function is_york_dominating_wales() { } function is_jack_cade_eligible(lord: Lord) { - if (!is_event_in_play(EVENT_YORK_JACK_CADE)) - return false - if (is_lord_in_or_adjacent_to_south(lord) && is_york_dominating_south()) - return true - if (is_lord_in_or_adjacent_to_north(lord) && is_york_dominating_north()) - return true - if (is_lord_in_or_adjacent_to_wales(lord) && is_york_dominating_wales()) - return true + if (is_york_lord(lord)) { + if (!is_event_in_play(EVENT_YORK_JACK_CADE)) + return false + if (is_lord_in_or_adjacent_to_south(lord) && is_york_dominating_south()) + return true + if (is_lord_in_or_adjacent_to_north(lord) && is_york_dominating_north()) + return true + if (is_lord_in_or_adjacent_to_wales(lord) && is_york_dominating_wales()) + return true + } return false } |