From cd99d4425d853a2ee279c935d38082fc14642b8a Mon Sep 17 00:00:00 2001
From: Tor Andersson <tor@ccxvii.net>
Date: Sat, 23 Nov 2024 23:08:18 +0100
Subject: ping/pong respond in chat

---
 play.html |  2 ++
 play.js   |  2 ++
 rules.js  | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
 3 files changed, 68 insertions(+), 8 deletions(-)

diff --git a/play.html b/play.html
index 683ff54..95dae1a 100644
--- a/play.html
+++ b/play.html
@@ -42,6 +42,8 @@
 				<li id="cancel_subsidy_menu" onclick="cancel_subsidy()">Cancel subsidy
 				<li class="separator">
 				<li id="propose_deal_menu" onclick="propose_deal()">Propose deal
+				<li class="separator">
+				<li id="ping_menu" onclick="send_action('ping')">Ping player
 			</menu>
 		</details>
 	</div>
diff --git a/play.js b/play.js
index 1306225..e2238ba 100644
--- a/play.js
+++ b/play.js
@@ -1573,6 +1573,7 @@ function on_update() {
 		"propose_subsidy",
 		"cancel_subsidy",
 		"propose_deal",
+		"ping",
 	])
 
 	update_deal_list(view.deals, window.active_deal_list, "Active Deals")
@@ -1639,6 +1640,7 @@ function on_update() {
 	action_button("stop", "Stop")
 	action_button("pass", "Pass")
 	action_button("next", "Next")
+	action_button("resume", "Resume")
 
 	confirm_action_button("dispute", "Dispute",
 		"Dispute order of movement on Flanders map and restart Austrian and Pragmatic Army movement phase?")
diff --git a/rules.js b/rules.js
index 7354cfd..525d188 100644
--- a/rules.js
+++ b/rules.js
@@ -1219,6 +1219,11 @@ function player_from_power(pow) {
 	}
 }
 
+function set_active_to_power_keep_undo(new_power) {
+	game.power = new_power
+	game.active = player_from_power(new_power)
+}
+
 function set_active_to_power(new_power) {
 	let old_active = player_from_power(game.power)
 	let new_active = player_from_power(new_power)
@@ -6345,10 +6350,10 @@ function end_cancel_subsidy(okay) {
 
 /* NEGOTIATION - DEALS */
 
-function goto_propose_deal(deal) {
-	game.proposal = { save_power: game.power, save_state: game.state, deal }
+function goto_propose_deal(save_power, deal) {
+	game.proposal = { save_power, save_state: game.state, deal }
 	let from = game.proposal.deal[DI_A_POWER]
-	set_active_to_power(from)
+	set_active_to_power_keep_undo(from)
 	game.state = "accept_deal_from"
 }
 
@@ -6370,10 +6375,11 @@ states.accept_deal_from = {
 		view.proposed_deal = game.proposal.deal
 		view.actions.accept = 1
 		view.actions.refuse = 1
+		view.actions.undo = 0
 	},
 	accept() {
 		let to = game.proposal.deal[DI_B_POWER]
-		set_active_to_power(to)
+		set_active_to_power_keep_undo(to)
 		game.state = "accept_deal_to"
 	},
 	refuse() {
@@ -6390,6 +6396,7 @@ states.accept_deal_to = {
 		view.proposed_deal = game.proposal.deal
 		view.actions.accept = 1
 		view.actions.refuse = 1
+		view.actions.undo = 0
 	},
 	accept() {
 		end_accept_deal(true)
@@ -6408,11 +6415,59 @@ function end_accept_deal(okay) {
 	}
 	log_br()
 
-	set_active_to_power(game.proposal.save_power)
+	set_active_to_power_keep_undo(game.proposal.save_power)
 	game.state = game.proposal.save_state
 	delete game.proposal
 }
 
+function goto_ping() {
+	game.proposal = { save_power: game.power, save_state: game.state }
+	game.state = "ping"
+}
+
+states.ping = {
+	inactive: "ping",
+	prompt() {
+		prompt("Ping which power to respond to chat?")
+		for (let pow of all_powers)
+			if (pow !== game.power)
+				gen_action_power(pow)
+		view.actions.undo = 1
+	},
+	power(pow) {
+		set_active_to_power_keep_undo(pow)
+		game.state = "pong"
+	},
+	undo() {
+		states.pong.resume()
+	},
+}
+
+states.pong = {
+	inactive: "respond",
+	prompt() {
+		prompt(power_name[game.proposal.save_power] + " has requested your response in chat.")
+		view.actions.propose_deal = 1
+		view.actions.ping = 1
+		view.actions.resume = 1
+		view.actions.undo = 0
+	},
+	ping() {
+		game.state = "ping"
+	},
+	resume() {
+		set_active_to_power_keep_undo(game.proposal.save_power)
+		game.state = game.proposal.save_state
+		delete game.proposal
+	},
+	propose_deal(arg) {
+		let save_power = game.proposal.save_power
+		game.state = game.proposal.save_state
+		delete game.proposal
+		goto_propose_deal(save_power, arg)
+	},
+}
+
 /* SETUP */
 
 const POWER_FROM_SETUP_STAGE = [
@@ -6927,8 +6982,8 @@ exports.view = function (state, player) {
 				view.actions.propose_subsidy = 1
 			if (!is_two_player() && !is_intro())
 				view.actions.propose_deal = 1
+			view.actions.ping = 1
 		}
-
 	}
 
 	return view
@@ -6949,8 +7004,9 @@ exports.action = function (state, _player, action, arg) {
 			push_undo()
 			goto_cancel_subsidy()
 		} else if (action === "propose_deal") {
-			push_undo()
-			goto_propose_deal(arg)
+			goto_propose_deal(game.power, arg)
+		} else if (action === "ping") {
+			goto_ping()
 		} else
 			throw new Error("Invalid action: " + action)
 	}
-- 
cgit v1.2.3