diff options
-rw-r--r-- | play.js | 18 | ||||
-rw-r--r-- | rules.js | 115 |
2 files changed, 122 insertions, 11 deletions
@@ -1844,13 +1844,17 @@ function update_subsidy_list(subs, elt, title) { } } -function update_deal_item(deal) { +function update_deal_item(deal, ix) { let [ a_power, b_power, a_turn, b_turn, a_phase, b_phase, a_promise, b_promise ] = deal let str = "<tr class='a'>" str += "<td width=24>" + power_image[a_power] str += "<td>" + html_escape(a_promise) str += "<td width=80><i>" + phase_list(a_phase) + "</i>" str += "<td width=60>" + turn_name[a_turn] + if (is_action("cancel_deal")) + str += `<td width=15 class="action" style="color:brown" onclick="cancel_deal(${ix})">\u274c</a>` + else + str += "<td width=15>" str += "<tr class='b'>" str += "<td>" + power_image[b_power] str += "<td>" + html_escape(b_promise) @@ -1859,11 +1863,19 @@ function update_deal_item(deal) { return str } +function cancel_deal(ix) { + let deal = view.deals[ix] + if (window.confirm( + `ANNUL deal between between ${power_name[deal[DI_A_POWER]]} and ${power_name[deal[DI_B_POWER]]}?` + )) + send_message("action", [ "cancel_deal", ix, game_cookie ]) +} + function update_deal_list(deals, elt, title) { if (deals && deals.length > 0) { //let str = "<table><tr><th><th>" + title + "<th>phase<th>until" - let str = "<table><tr><th colspan=4>" + title - str += deals.map(update_deal_item).join("<tr class='sep'><td colspan=4>") + let str = "<table><tr><th colspan=5>" + title + str += deals.map(update_deal_item).join("<tr class='sep'><td colspan=5>") str += "</table>" elt.innerHTML = str elt.style.display = "block" @@ -6534,7 +6534,7 @@ function end_cancel_subsidy() { delete game.proposal } -/* NEGOTIATION - DEALS */ +/* NEGOTIATION - CREATE DEAL */ function goto_propose_deal(save_power, deal) { game.proposal = { save_power, save_state: game.state, deal } @@ -6630,6 +6630,105 @@ function end_accept_deal() { delete game.proposal } +/* NEGOTIATION - CANCEL DEAL */ + +function cancel_deal() { + array_remove(game.deals, game.proposal.index) +} + +function goto_cancel_deal(save_power, deal_idx) { + let deal = game.deals[deal_idx] + game.proposal = { save_power, save_state: game.state, from: deal[DI_A_POWER], to: deal[DI_B_POWER], index: deal_idx } + set_active_to_power_keep_undo(game.proposal.from) + game.state = "cancel_deal_approve_from" +} + +states.cancel_deal_approve_from = { + dont_snap: true, + inactive: "cancel deal", + prompt() { + let from = game.proposal.from + let to = game.proposal.to + prompt(`Cancel deal between ${power_name[from]} and ${power_name[to]}?`) + view.proposed_deal = game.deals[game.proposal.index] + view.actions.accept = 1 + view.actions.reject = 1 + }, + accept() { + set_active_to_power_keep_undo(game.proposal.to) + game.state = "cancel_deal_approve_to" + }, + reject() { + goto_reject_cancel_deal() + }, +} + +states.cancel_deal_approve_to = { + dont_snap: true, + inactive: "cancel deal", + prompt() { + let from = game.proposal.from + let to = game.proposal.to + prompt(`Cancel deal between ${power_name[from]} and ${power_name[to]}?`) + view.proposed_deal = game.deals[game.proposal.index] + view.actions.accept = 1 + view.actions.reject = 1 + }, + accept() { + cancel_deal() + goto_notify_cancel_deal() + }, + reject() { + goto_reject_cancel_deal() + }, +} + +function goto_reject_cancel_deal() { + game.proposal.reject = 1 + goto_notify_cancel_deal() +} + +function goto_notify_cancel_deal() { + let from = game.proposal.from + let to = game.proposal.to + if (game.power === to) + set_active_to_power_keep_undo(from) + else + set_active_to_power_keep_undo(game.proposal.save_power) + game.state = "notify_cancel_deal" +} + +function next_notify_cancel_deal() { + if (game.power !== game.proposal.save_power) + set_active_to_power_keep_undo(game.proposal.save_power) + else + end_cancel_deal() +} + +states.notify_cancel_deal = { + dont_snap: true, + inactive: "resume play", + prompt() { + let from = game.proposal.from + let to = game.proposal.to + if (game.proposal.reject) + prompt(`Deal between ${power_name[from]} and ${power_name[to]} was NOT canceled.`) + else + prompt(`Deal between ${power_name[from]} and ${power_name[to]} canceled.`) + view.actions.resume = 1 + view.actions.undo = 0 + }, + resume() { + next_notify_cancel_deal() + }, +} + +function end_cancel_deal() { + set_active_to_power_keep_undo(game.proposal.save_power) + game.state = game.proposal.save_state + delete game.proposal +} + /* NEGOTIATION - PING PLAYER */ function goto_ping() { @@ -7444,12 +7543,14 @@ exports.view = function (state, player) { // negotiation actions for active player if (!globalThis.RTT_FUZZER) if (game.proposal === undefined && !is_intro() && view.turn > 0) { + view.actions.propose_subsidy = 1 if (may_cancel_subsidy()) view.actions.cancel_subsidy = 1 - if (!is_intro()) - view.actions.propose_subsidy = 1 - if (!is_two_player() && !is_intro()) + if (!is_two_player()) { view.actions.propose_deal = 1 + if (game.deals.length > 0) + view.actions.cancel_deal = 1 + } view.actions.ping = 1 } } @@ -7471,6 +7572,8 @@ exports.action = function (state, _player, action, arg) { goto_cancel_subsidy(game.power) } else if (action === "propose_deal") { goto_propose_deal(game.power, arg) + } else if (action === "cancel_deal") { + goto_cancel_deal(game.power, arg) } else if (action === "ping") { goto_ping() } else @@ -7780,10 +7883,6 @@ function set_intersect(one, two) { // Map as plain sorted array of key/value pairs -function map_clear(set) { - set.length = 0 -} - function map_has(map, key) { let a = 0 let b = (map.length >> 1) - 1 |