summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--info/playtest.html13
-rw-r--r--play.js5
-rw-r--r--rules.js139
3 files changed, 107 insertions, 50 deletions
diff --git a/info/playtest.html b/info/playtest.html
index d52e278..1a49f7f 100644
--- a/info/playtest.html
+++ b/info/playtest.html
@@ -83,7 +83,7 @@ Card - Foederati
Change card text to:
<blockquote>
-Select an army you command and remove one <u>active</u> non-leader barbarian counter
+Select an army you command and remove one non-leader barbarian counter
not in a player's army from the selected army's region. If the selected
army contains fewer barbarians than legions, the barbarian joins your army.
Otherwise, return the barbarian to its home region on its inactive side.
@@ -91,7 +91,6 @@ Otherwise, return the barbarian to its home region on its inactive side.
<ul>
<li>Limit to current region only.
-<li>Limit to active barbarians only.
</ul>
<h3>
@@ -102,11 +101,11 @@ Card - Demagogue
Change card text to:
<blockquote>
-Place 1, 2, or 3 Mob counters in any province.
-If you take a Place Governor action in that province this turn
-you gain one extra vote for each Mob counter there.
-If you take control of that province this turn, do not remove
-Mob counters.
+Choose a province you govern.
+You may place a Mob counter in each adjacent province
+that you do not govern.
+Gain one legacy per Mob counter placed this way.
+Gallia and Britannia are considered adjacent for this event.
</blockquote>
<h3>
diff --git a/play.js b/play.js
index 8d1e9e3..ed3ab14 100644
--- a/play.js
+++ b/play.js
@@ -1574,7 +1574,10 @@ function on_update() {
ui.active_event.appendChild(ui.event_cards[view.event])
ui.played_panel.className = "panel p_" + PLAYER_CLASS[view.current]
- ui.played_header.textContent = PLAYER_NAME[view.current] + " Played"
+ if (typeof view.current === "number")
+ ui.played_header.textContent = PLAYER_NAME[view.current] + " Played"
+ else
+ ui.played_header.textContent = "Played"
ui.played.className = "panel_body p_" + PLAYER_CLASS[view.current]
ui.played.replaceChildren()
if (view.played) {
diff --git a/rules.js b/rules.js
index 25e8d56..cf13010 100644
--- a/rules.js
+++ b/rules.js
@@ -1321,36 +1321,46 @@ states.setup_province = {
}
function goto_setup_hand() {
- // Go backwards for simultaneous selection of cards.
- game.current = last_player()
+ // Simultaneous selection of cards.
+ game.current = []
+ for (let p = 0; p < get_player_count(); ++p)
+ game.current.push(p)
game.state = "setup_hand"
}
states.setup_hand = {
inactive: "Setup",
- prompt() {
- let hand = current_hand()
+ prompt(player) {
+ let hand = game.hand[player]
+ if (hand.length > 0)
+ view.actions.undo = 1
+ else
+ view.actions.undo = 0
if (hand.length < 5) {
prompt("Setup: Draw cards.")
- for (let c of current_draw())
+ for (let c of game.draw[player])
gen_action_card(c)
} else {
prompt("Setup: Done.")
view.actions.done = 1
}
},
- card(c) {
- push_undo()
- set_delete(current_draw(), c)
- set_add(current_hand(), c)
+ card(c, player) {
+ //push_undo()
+ set_delete(game.draw[player], c)
+ game.hand[player].push(c)
},
- done() {
- clear_undo()
-
- if (game.current === first_player())
+ undo(_, player) {
+ let c = game.hand[player].pop()
+ set_add(game.draw[player], c)
+ },
+ done(_, player) {
+ game.hand[player].sort((a,b)=>a-b)
+ set_delete(game.current, player)
+ if (game.current.length === 0) {
+ game.current = first_player()
goto_start_turn()
- else
- game.current = prev_player()
+ }
},
}
@@ -1527,35 +1537,66 @@ states.ira_deorum = {
// TODO: except emperor and ludi saecularis remains
function goto_pax_deorum() {
- game.count = game.current
- game.current = prev_player()
- resume_pax_deorum()
+ let player_count = get_player_count()
+ game.pax_deorum = {
+ current: game.current,
+ undo: new Array(player_count).fill(-1)
+ }
+ let concurrent = []
+ for (game.current = 0; game.current < player_count; ++game.current)
+ init_pax_deorum(concurrent)
+ if (concurrent.length > 0) {
+ game.state = "pax_deorum"
+ game.current = concurrent
+ } else {
+ end_pax_deorum()
+ }
}
-function resume_pax_deorum() {
+function init_pax_deorum(concurrent) {
if (game.draw[game.current].length === 0 && game.discard[game.current].length > 0) {
log(PLAYER_NAME[game.current] + " put discard in available.")
flip_discard_to_available()
}
if (game.draw[game.current].length > 0)
- game.state = "pax_deorum"
- else
- // TODO: skip state?
- game.state = "pax_deorum_done"
+ concurrent.push(game.current)
+}
+
+function end_pax_deorum() {
+ game.current = game.pax_deorum.current
+ delete game.pax_deorum
+ goto_take_actions()
}
states.pax_deorum = {
inactive: "Pax Deorum",
- prompt() {
- prompt("Pax Deorum: Draw one card.")
- for (let c of game.draw[game.current])
- gen_action_card(c)
+ prompt(player) {
+ if (game.pax_deorum.undo[player] < 0) {
+ prompt("Pax Deorum: Draw one card.")
+ for (let c of game.draw[player])
+ gen_action_card(c)
+ view.actions.undo = 0
+ } else {
+ prompt("Pax Deorum: Done.")
+ view.actions.done = 1
+ view.actions.undo = 1
+ }
},
- card(c) {
- push_undo()
- set_add(game.hand[game.current], c)
- set_delete(game.draw[game.current], c)
- game.state = "pax_deorum_done"
+ card(c, player) {
+ game.pax_deorum.undo[player] = c
+ set_add(game.hand[player], c)
+ set_delete(game.draw[player], c)
+ },
+ undo(_, player) {
+ let c = game.pax_deorum.undo[player]
+ game.pax_deorum.undo[player] = -1
+ set_delete(game.hand[player], c)
+ set_add(game.draw[player], c)
+ },
+ done(_, player) {
+ set_delete(game.current, player)
+ if (game.current.length === 0)
+ end_pax_deorum()
},
}
@@ -6142,15 +6183,24 @@ function load_game(state) {
}
function save_game() {
- game.active = PLAYER_NAME[game.current]
+ if (Array.isArray(game.current))
+ game.active = game.current.map(x => PLAYER_NAME[x])
+ else
+ game.active = PLAYER_NAME[game.current]
return game
}
-exports.action = function (state, player, action, arg) {
+function is_active_player(player) {
+ if (Array.isArray(game.current))
+ return set_has(game.current, player)
+ return game.current === player
+}
+
+exports.action = function (state, player_name, action, arg) {
load_game(state)
let S = states[game.state]
if (action in S) {
- S[action](arg)
+ S[action](arg, PLAYER_INDEX[player_name])
} else {
if (action === "undo" && game.undo && game.undo.length > 0)
pop_undo()
@@ -6202,16 +6252,21 @@ exports.view = function (state, player_name) {
if (game.state === "game_over") {
view.prompt = game.victory
- } else if (game.current !== player) {
+ } else if (!is_active_player(player)) {
let inactive = states[game.state].inactive || game.state
- view.prompt = `Waiting for ${PLAYER_NAME[game.current]}: ${inactive}.`
+ if (Array.isArray(game.active))
+ view.prompt = `Waiting for ${game.active.join(" and ")}: ${inactive}.`
+ else
+ view.prompt = `Waiting for ${game.active}: ${inactive}.`
} else {
view.actions = {}
- states[game.state].prompt()
- if (game.undo && game.undo.length > 0)
- view.actions.undo = 1
- else
- view.actions.undo = 0
+ states[game.state].prompt(player)
+ if (view.actions.undo === undefined) {
+ if (game.undo && game.undo.length > 0)
+ view.actions.undo = 1
+ else
+ view.actions.undo = 0
+ }
}
if (player >= 0 && player < player_count) {