From e137caa6f4cef04e18c8ecb2f41df49682f87678 Mon Sep 17 00:00:00 2001
From: Tor Andersson <tor@ccxvii.net>
Date: Thu, 6 Jul 2023 22:37:40 +0200
Subject: Misc.

---
 play.css | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++-----
 play.js  |  5 +++++
 rules.js | 51 +++++++++++++++++++++++++++------------------------
 3 files changed, 83 insertions(+), 29 deletions(-)

diff --git a/play.css b/play.css
index 0dc2ad0..eb5d563 100644
--- a/play.css
+++ b/play.css
@@ -9,7 +9,7 @@ header.your_turn { background-color: orange; }
 #turn_info { background-color: gainsboro; }
 .role_vp { float: right; }
 
-body.Observer #hand_panel, body.Observer #draw_panel, body.Observer #discard_panel, body.Observer #market_panel {
+body.Observer #hand_panel, body.Observer #draw_panel, body.Observer #discard_panel {
 	display: none;
 }
 
@@ -634,11 +634,10 @@ body.shift .zenobia { background-image: url(images/rival_back.png) }
 	min-width: 1368px;
 	max-width: 1636px;
 	margin: 12px auto 36px auto;
-	background-color: #555;
 }
 
 .panel_header {
-	background-color: #444;
+	background-color: hsl(0,0%,27%);
 	color: white;
 	user-select: none;
 	font-weight: bold;
@@ -647,6 +646,7 @@ body.shift .zenobia { background-image: url(images/rival_back.png) }
 }
 
 .panel_body {
+	background-color: hsl(0,0%,35%);
 	display: flex;
 	justify-content: start;
 	flex-wrap: wrap;
@@ -655,8 +655,54 @@ body.shift .zenobia { background-image: url(images/rival_back.png) }
 	min-height: 350px;
 }
 
-#market {
-	background-image: repeating-linear-gradient(135deg, #555555, #555555 60px, #505050 60px, #505050 120px);
+#market, #played {
+	background-image: repeating-linear-gradient(135deg,
+		hsl(0,0%,33%),
+		hsl(0,0%,33%) 60px,
+		hsl(0,0%,30%) 60px,
+		hsl(0,0%,30%) 120px
+	)
+}
+
+.panel_header.p_red { background-color: hsl(354,20%,27%) }
+.panel_header.p_blue { background-color: hsl(207,20%,27%) }
+.panel_header.p_yellow { background-color: hsl(47,25%,27%) }
+.panel_header.p_green { background-color: hsl(99,15%,27%) }
+
+#played.p_red {
+	background-image: repeating-linear-gradient(135deg,
+		hsl(354,20%,33%),
+		hsl(354,20%,33%) 60px,
+		hsl(354,20%,31%) 60px,
+		hsl(354,20%,31%) 120px
+	)
+}
+
+#played.p_blue {
+	background-image: repeating-linear-gradient(135deg,
+		hsl(207,20%,33%),
+		hsl(207,20%,33%) 60px,
+		hsl(207,20%,31%) 60px,
+		hsl(207,20%,31%) 120px
+	)
+}
+
+#played.p_yellow {
+	background-image: repeating-linear-gradient(135deg,
+		hsl(47,25%,33%),
+		hsl(47,25%,33%) 60px,
+		hsl(47,25%,31%) 60px,
+		hsl(47,25%,31%) 120px
+	)
+}
+
+#played.p_green {
+	background-image: repeating-linear-gradient(135deg,
+		hsl(99,15%,33%),
+		hsl(99,15%,33%) 60px,
+		hsl(99,15%,31%) 60px,
+		hsl(99,15%,31%) 120px
+	)
 }
 
 /* CRISIS TABLE HIGHLIGHT */
diff --git a/play.js b/play.js
index 7814414..58e083b 100644
--- a/play.js
+++ b/play.js
@@ -284,6 +284,7 @@ function set_has(set, item) {
 }
 
 const PLAYER_CLASS = [ "red", "blue", "yellow", "green" ]
+const PLAYER_NAME = [ "Red", "Blue", "Yellow", "Green" ]
 const BARBARIAN_CLASS = [ "alamanni", "franks", "goths", "sassanids", "nomads" ]
 
 const BOXES = {
@@ -665,6 +666,7 @@ let ui = {
 	active_event: document.getElementById("active_event"),
 	combat_mask: document.getElementById("combat_mask"),
 	discard: document.getElementById("discard"),
+	played_header: document.getElementById("played_header"),
 	played: document.getElementById("played"),
 	market: document.getElementById("market"),
 	pieces: document.getElementById("pieces"),
@@ -1445,6 +1447,9 @@ function on_update() {
 	ui.active_event.replaceChildren()
 		ui.active_event.appendChild(ui.event_cards[view.event])
 
+	ui.played_header.className = "panel_header p_" + PLAYER_CLASS[view.current]
+	ui.played_header.textContent = PLAYER_NAME[view.current] + " Played"
+	ui.played.className = "panel_body p_" + PLAYER_CLASS[view.current]
 	ui.played.replaceChildren()
 	if (view.played) {
 		for (let c of view.played) {
diff --git a/rules.js b/rules.js
index 928a041..ee82eeb 100644
--- a/rules.js
+++ b/rules.js
@@ -1,21 +1,10 @@
 "use strict"
 
-/*
-TODO
-
-[ ] killed leader stash for buy/trash phase
-
-TODO: can_select_general - check actual possible actions
-TODO: can_select_governor - check actual possible actions
-TODO: can_select_militia - check actual possible actions
-
-*/
-
 var game
 var view
 const states = {}
 
-const AUTO_PLAY_EVENTS = false
+const AUTO_PLAY_EVENTS = true
 
 const P1 = "Red"
 const P2 = "Blue"
@@ -834,6 +823,9 @@ function can_militia_initiate_battle(where) {
 		return true
 	if (some_barbarian((id, loc) => loc === where))
 		return true
+	for (let id = 0; id < 3; ++id)
+		if (get_rival_emperor_location(id) === where)
+			return true
 	return false
 }
 
@@ -844,6 +836,9 @@ function can_general_initiate_battle(where) {
 		return true
 	if (some_barbarian((id, loc) => loc === where))
 		return true
+	for (let id = 0; id < 3; ++id)
+		if (get_rival_emperor_location(id) === where)
+			return true
 	return false
 }
 
@@ -2069,6 +2064,7 @@ states.take_actions = {
 		log("Recruit Governor " + (game.selected_governor % 6) + ".")
 		spend_senate(game.selected_governor % 6)
 		set_governor_location(game.selected_governor, AVAILABLE)
+		resume_take_actions()
 	},
 
 	recruit_general() {
@@ -2375,7 +2371,7 @@ function calc_extra_votes(where) {
 states.place_governor = {
 	inactive: "Place Governor",
 	prompt() {
-		let need = calc_needed_votes(game.where, false) - calc_extra_votes(game.where)
+		let need = Math.max(0, calc_needed_votes(game.where, false) - calc_extra_votes(game.where))
 		let dice = game.count
 		if (game.where === ITALIA)
 			dice += count_own_basilicas()
@@ -2412,7 +2408,7 @@ states.place_governor = {
 states.praetorian_guard = {
 	inactive: "Praetorian Guard",
 	prompt() {
-		let need = calc_needed_votes(game.where, true) - calc_extra_votes(game.where)
+		let need = Math.max(0, calc_needed_votes(game.where, true) - calc_extra_votes(game.where))
 		let dice = game.count
 		if (game.where === ITALIA)
 			dice += count_own_basilicas()
@@ -2676,7 +2672,7 @@ function has_mobs_in_own_provinces() {
 states.becoming_emperor = {
 	inactive: "Becoming Emperor",
 	prompt() {
-		prompt("Becoming Emperor: Place your Emperor token.")
+		prompt("Becoming Emperor: Place your Emperor.")
 		for (let i = 0; i < 6; ++i) {
 			let id = game.current * 6 + i
 			if (is_region(get_governor_location(id)))
@@ -3074,7 +3070,6 @@ function can_play_foederati() {
 }
 
 function play_foederati() {
-	// TODO: auto-select general on map?
 	game.state = "foederati"
 }
 
@@ -3120,10 +3115,16 @@ states.foederati_general = {
 		let tribe = get_barbarian_tribe(id)
 		let from = get_barbarian_location(id)
 		if (count_legions_in_army(game.count) > count_barbarians_in_army(game.count)) {
-			log("Foederati " + BARBARIAN_NAME[tribe] + " from %" + from + " to %" + game.where + ".")
+			if (is_barbarian_inactive(id))
+				log("Foederati inactive " + BARBARIAN_NAME[tribe] + " from %" + from + " to %" + game.where + ".")
+			else
+				log("Foederati " + BARBARIAN_NAME[tribe] + " from %" + from + " to %" + game.where + ".")
 			set_barbarian_location(id, ARMY + game.count)
 		} else {
-			log("Foederati " + BARBARIAN_NAME[tribe] + " in %" + from + ".")
+			if (is_barbarian_inactive(id))
+				log("Foederati inactive " + BARBARIAN_NAME[tribe] + " in %" + from + ".")
+			else
+				log("Foederati " + BARBARIAN_NAME[tribe] + " in %" + from + ".")
 			eliminate_barbarian(id)
 		}
 		resume_take_actions()
@@ -3267,7 +3268,7 @@ function auto_play_princeps_senatus() {
 }
 
 function can_play_princeps_senatus() {
-	return !used_card_event(CARD_S2X)
+	return !used_card_event(CARD_S2X) && game.sip > 0
 }
 
 function play_princeps_senatus() {
@@ -3299,7 +3300,6 @@ function can_play_force_march() {
 }
 
 function play_force_march() {
-	// TODO: auto-select general on map?
 	game.state = "force_march_who"
 }
 
@@ -4372,10 +4372,11 @@ function goto_combat_victory_attacker() {
 
 		// Surviving Barbarians go home (to active)
 		let tribe = game.combat.target
-		console.log("BARB", tribe, game.combat)
-		for (let id = first_barbarian[tribe]; id <= last_barbarian[tribe]; ++id)
-			if (get_barbarian_location(id) === game.where)
-				set_barbarian_location(id, BARBARIAN_HOMELAND[tribe])
+		if (is_province(game.where)) {
+			for (let id = first_barbarian[tribe]; id <= last_barbarian[tribe]; ++id)
+				if (get_barbarian_location(id) === game.where)
+					set_barbarian_location(id, BARBARIAN_HOMELAND[tribe])
+		}
 	} else {
 		if (game.emperor === ARMY + game.combat.attacker)
 			award_combat_legacy(game.current, "Military Emperor Victory", 4)
@@ -5079,6 +5080,8 @@ function vp_tie(p) {
 function goto_game_end() {
 	log_h1("Game End")
 
+	game.played.length = 0
+
 	game.crisis[0] = -1
 	game.crisis[1] = 0
 	game.crisis[2] = 0
-- 
cgit v1.2.3