summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Andersson <tor@ccxvii.net>2023-07-01 16:36:11 +0200
committerTor Andersson <tor@ccxvii.net>2023-07-07 19:05:52 +0200
commit285606d4c3fec57d501c66b46a48e730e71d0f6a (patch)
tree427a5607d478a9a92864548e079f69a3f312a58d
parent0dc3440161c7062ae09a93f001d5dd1629b35942 (diff)
downloadtime-of-crisis-285606d4c3fec57d501c66b46a48e730e71d0f6a.tar.gz
Expansion cards.
TODO: Frumentarii, Spiculum, Demagogue.
-rw-r--r--info/cards.html42
-rw-r--r--info/readme.html5
-rw-r--r--play.css4
-rw-r--r--play.js2
-rw-r--r--rules.js531
5 files changed, 496 insertions, 88 deletions
diff --git a/info/cards.html b/info/cards.html
index 4fc8758..3c3bd5a 100644
--- a/info/cards.html
+++ b/info/cards.html
@@ -66,6 +66,16 @@ h2 {
.card.influence_s2{background-image:url(../cards.1x/influence_s2.jpg)}
.card.influence_s3{background-image:url(../cards.1x/influence_s3.jpg)}
.card.influence_s4{background-image:url(../cards.1x/influence_s4.jpg)}
+.card.influence_s4b{background-image:url(../cards.1x/influence_s4b.jpg)}
+.card.influence_m2x{background-image:url(../cards.1x/influence_m2x.jpg)}
+.card.influence_m3x{background-image:url(../cards.1x/influence_m3x.jpg)}
+.card.influence_m4x{background-image:url(../cards.1x/influence_m4x.jpg)}
+.card.influence_p2x{background-image:url(../cards.1x/influence_p2x.jpg)}
+.card.influence_p3x{background-image:url(../cards.1x/influence_p3x.jpg)}
+.card.influence_p4x{background-image:url(../cards.1x/influence_p4x.jpg)}
+.card.influence_s2x{background-image:url(../cards.1x/influence_s2x.jpg)}
+.card.influence_s3x{background-image:url(../cards.1x/influence_s3x.jpg)}
+.card.influence_s4x{background-image:url(../cards.1x/influence_s4x.jpg)}
@media (min-resolution:97dpi) {
.card.event_back{background-image:url(../cards.2x/event_back.jpg)}
@@ -101,6 +111,16 @@ h2 {
.card.influence_s2{background-image:url(../cards.2x/influence_s2.jpg)}
.card.influence_s3{background-image:url(../cards.2x/influence_s3.jpg)}
.card.influence_s4{background-image:url(../cards.2x/influence_s4.jpg)}
+.card.influence_s4b{background-image:url(../cards.2x/influence_s4b.jpg)}
+.card.influence_m2x{background-image:url(../cards.2x/influence_m2x.jpg)}
+.card.influence_m3x{background-image:url(../cards.2x/influence_m3x.jpg)}
+.card.influence_m4x{background-image:url(../cards.2x/influence_m4x.jpg)}
+.card.influence_p2x{background-image:url(../cards.2x/influence_p2x.jpg)}
+.card.influence_p3x{background-image:url(../cards.2x/influence_p3x.jpg)}
+.card.influence_p4x{background-image:url(../cards.2x/influence_p4x.jpg)}
+.card.influence_s2x{background-image:url(../cards.2x/influence_s2x.jpg)}
+.card.influence_s3x{background-image:url(../cards.2x/influence_s3x.jpg)}
+.card.influence_s4x{background-image:url(../cards.2x/influence_s4x.jpg)}
}
</style>
@@ -116,17 +136,17 @@ h2 {
<div class="card influence influence_m4"></div>
</div>
<div class="list">
-<div class="card influence influence_p1"></div>
-<div class="card influence influence_p2"></div>
-<div class="card influence influence_p3"></div>
-<div class="card influence influence_p4"></div>
-</div>
-<div class="list">
<div class="card influence influence_s1"></div>
<div class="card influence influence_s2"></div>
<div class="card influence influence_s3"></div>
<div class="card influence influence_s4"></div>
</div>
+<div class="list">
+<div class="card influence influence_p1"></div>
+<div class="card influence influence_p2"></div>
+<div class="card influence influence_p3"></div>
+<div class="card influence influence_p4"></div>
+</div>
<h2>Expansion Influence Cards</h2>
@@ -136,16 +156,16 @@ h2 {
<div class="card influence influence_m4x"></div>
</div>
<div class="list">
-<div class="card influence influence_p2x"></div>
-<div class="card influence influence_p3x"></div>
-<div class="card influence influence_p4x"></div>
-</div>
-<div class="list">
<div class="card influence influence_s2x"></div>
<div class="card influence influence_s3x"></div>
<div class="card influence influence_s4x"></div>
<div class="card influence influence_s4b"></div>
</div>
+<div class="list">
+<div class="card influence influence_p2x"></div>
+<div class="card influence influence_p3x"></div>
+<div class="card influence influence_p4x"></div>
+</div>
<h2>Event Cards</h2>
diff --git a/info/readme.html b/info/readme.html
index d43559d..ef978f0 100644
--- a/info/readme.html
+++ b/info/readme.html
@@ -49,7 +49,10 @@ How do I use the event on a card?
<p>
Once the card is in your "Played" area you can click it again to use the event.
The card will turn dark once its effect has been used.
-"Flanking Maneuver" and "Damnatio Memoriae" can only be played when prompted at the appropriate time.
+<p>
+"Cavalry", "Flanking Maneuver", "Spiculum", and "Triumph" can only be played in combat.
+<p>
+"Ambitus" and "Damnatio Memoriae" can only be played during the Place Governor action.
<hr>
diff --git a/play.css b/play.css
index ac6c457..f8d8536 100644
--- a/play.css
+++ b/play.css
@@ -192,10 +192,6 @@ body svg .sea.action {
display: block;
}
-.support.s0.action {
- background-color: hsla(206, 100%, 35%, 0.4);
-}
-
.dice {
width: 36px;
height: 36px;
diff --git a/play.js b/play.js
index 0e6618c..88db339 100644
--- a/play.js
+++ b/play.js
@@ -826,7 +826,7 @@ function create_support_buttons(region) {
for (let i = 0; i <= 4; ++i) {
let x = Math.floor(-1 + x0 + i * 51.6666)
let y = (-1 + y0)
- let e = create_thing({ className: "support s" + i, my_action: i > 0 ? "support" : "recall", my_id: i > 0 ? (region << 3) + i : region })
+ let e = create_thing({ className: "support s" + i, my_action: "support", my_id: (region << 3) + i })
e.style.top = y + "px"
e.style.left = x + "px"
}
diff --git a/rules.js b/rules.js
index 880dff1..ed56611 100644
--- a/rules.js
+++ b/rules.js
@@ -4,13 +4,16 @@
TODO
[ ] killed leader stash for buy/trash phase
-[ ] killed ardashur+shapur: two support bumps
-[ ] killed gives credits for military + senate
[ ] display of general+castra stacked with militia+castra
+[ ] todo: battle twice with militia (remove mbattled?)
[ ] emperor
[ ] expansion cards
+Frumentarii
+Demagogue
+Spiculum
+
*/
var game
@@ -401,6 +404,16 @@ const PLAY_CARD_EVENT = {
"Damnatio Memoriae": play_damnatio_memoriae,
"Damnatio Memoriae (exp)": play_damnatio_memoriae_exp,
"Pretender": play_pretender,
+
+ "Cavalry": play_cavalry,
+ "Princeps Senatus": play_princeps_senatus,
+ "Ambitus": play_ambitus,
+ "Force March": play_force_march,
+ "Frumentarii": play_frumentarii,
+ "Mobile Vulgus": play_mobile_vulgus,
+ "Spiculum": play_spiculum,
+ "Triumph": play_triumph,
+ "Demagogue": play_demagogue,
}
const CAN_PLAY_CARD_EVENT = {
@@ -414,6 +427,16 @@ const CAN_PLAY_CARD_EVENT = {
"Damnatio Memoriae": null,
"Damnatio Memoriae (exp)": null,
"Pretender": can_play_pretender,
+
+ "Cavalry": null,
+ "Princeps Senatus": can_play_princeps_senatus,
+ "Ambitus": null,
+ "Force March": can_play_force_march,
+ "Frumentarii": can_play_frumentarii,
+ "Mobile Vulgus": can_play_mobile_vulgus,
+ "Spiculum": null,
+ "Triumph": null,
+ "Demagogue": can_play_demagogue,
}
function can_play_card_event(c) {
@@ -561,6 +584,9 @@ function has_general_battled(id) { return game.battled & (1 << id) }
function set_general_battled(id) { game.battled |= (1 << id) }
function clear_general_battled(id) { game.battled &= ~(1 << id) }
+function has_general_force_marched(id) { return game.force_march & (1 << id) }
+function set_general_force_marched(id) { game.force_march |= (1 << id) }
+
function has_militia_battled(province) { return game.mbattled & (1 << province) }
function set_militia_battled(province) { game.mbattled |= (1 << province) }
function clear_militia_battled(province) { game.mbattled &= ~(1 << province) }
@@ -1116,6 +1142,13 @@ function has_card_event(event) {
return false
}
+function used_card_event(event) {
+ for (let c = event[0]; c <= event[1]; ++c)
+ if (set_has(game.used, c))
+ return true
+ return false
+}
+
// === SETUP ===
states.setup_province = {
@@ -1179,6 +1212,7 @@ function goto_start_turn() {
game.killed = 0
game.battled = 0
+ game.force_march = 0
game.mbattled = 0
game.placed = 0
@@ -1993,6 +2027,7 @@ states.take_actions = {
push_undo()
if (game.selected_governor >= 0) {
spend_senate(1)
+ game.ambitus = 0
game.count = 1
game.where = where
game.state = "place_governor"
@@ -2148,6 +2183,16 @@ function place_governor(where, new_governor) {
update_neutral_italia()
}
+function count_units_in_capital(where) {
+ let n = 0
+ let army = get_capital_general(where)
+ if (army >= 0)
+ n += count_units_in_army(army)
+ if (has_militia(where))
+ n += 1
+ return n
+}
+
function calc_needed_votes(where, pg) {
let n = get_support(where) * 2 // base number of votes
let old_governor = get_province_governor(where)
@@ -2166,6 +2211,8 @@ function calc_needed_votes(where, pg) {
if (has_militia(where))
n += 1
}
+ // Ambitus adds guaranteed votes.
+ n -= game.ambitus
return Math.max(1, n)
}
@@ -2173,19 +2220,28 @@ states.place_governor = {
inactive: "Place Governor",
prompt() {
let need = calc_needed_votes(game.where, false)
- let votes = game.count
+ let dice = game.count
if (game.where === ITALIA)
- votes += count_own_basilicas()
+ dice += count_own_basilicas()
view.color = SENATE
view.selected_region = game.where
view.selected_governor = game.selected_governor
- prompt(`Place Governor: ${game.sip} senate. Rolling ${votes} dice. ${need} votes needed.`)
+ prompt(`Place Governor: ${game.sip} senate. Rolling ${dice} dice. ${need} votes needed.`)
+ if (game.ambitus < game.count && has_card_event(CARD_P2X)) {
+ view.prompt += " Ambitus?"
+ gen_card_event(CARD_P2X)
+ }
if (game.sip >= 1)
view.actions.spend_senate = 1
else
view.actions.spend_senate = 0
view.actions.roll = 1
},
+ card(c) {
+ push_undo()
+ set_add(game.used, c)
+ play_card_event(c)
+ },
spend_senate() {
push_undo()
spend_senate(1)
@@ -2201,19 +2257,28 @@ states.praetorian_guard = {
inactive: "Praetorian Guard",
prompt() {
let need = calc_needed_votes(game.where, true)
- let votes = game.count
+ let dice = game.count
if (game.where === ITALIA)
- votes += count_own_basilicas()
+ dice += count_own_basilicas()
view.color = MILITARY
view.selected_region = game.where
view.selected_governor = game.selected_governor
- prompt(`Praetorian Guard: ${game.mip} Military. Rolling ${votes} dice. ${need} votes needed.`)
+ prompt(`Praetorian Guard: ${game.mip} military. Rolling ${dice} dice. ${need} votes needed.`)
+ if (game.ambitus < game.count && has_card_event(CARD_P2X)) {
+ view.prompt += " Ambitus?"
+ gen_card_event(CARD_P2X)
+ }
if (game.mip >= 1)
view.actions.spend_military = 1
else
view.actions.spend_military = 0
view.actions.roll = 1
},
+ card(c) {
+ push_undo()
+ set_add(game.used, c)
+ play_card_event(c)
+ },
spend_military() {
push_undo()
spend_military(1)
@@ -2296,6 +2361,7 @@ function play_praetorian_guard_auto() {
}
}
spend_military(1)
+ game.ambitus = 0
game.count = 1
game.where = ITALIA
game.state = "praetorian_guard"
@@ -2737,6 +2803,7 @@ function can_play_foederati() {
}
function play_foederati() {
+ // TODO: auto-select general on map?
game.state = "foederati"
}
@@ -2917,12 +2984,253 @@ states.pretender_breakaway = {
},
}
+
+// CARD: Princeps Senatus
+
+function can_play_princeps_senatus() {
+ return !used_card_event(CARD_S2X)
+}
+
+function play_princeps_senatus() {
+ log("Princeps Senatus.")
+}
+
+// CARD: Ambitus
+
+function play_ambitus() {
+ log("Ambitus.")
+ game.ambitus += 1
+}
+
+// CARD: Force March
+
+function can_play_force_march() {
+ if (game.mip >= 1) {
+ for (let i = 0; i < 6; ++i) {
+ let id = game.current * 6 + i
+ if (is_region(get_general_location(id)))
+ if (has_general_battled(id) && !has_general_force_marched(id))
+ return true
+ }
+ }
+ return false
+}
+
+function play_force_march() {
+ // TODO: auto-select general on map?
+ game.state = "force_march_who"
+}
+
+states.force_march_who = {
+ prompt() {
+ prompt("Force March: Choose an army you command...")
+ for (let i = 0; i < 6; ++i) {
+ let id = game.current * 6 + i
+ let where = get_general_location(id)
+ if (is_region(where) && has_general_battled(id) && !has_general_force_marched(id))
+ gen_action_general(id)
+ }
+ // TODO: Militia + Force March ?
+ },
+ general(id) {
+ log("Force March.")
+ set_general_force_marched(id)
+ game.selected_governor = -1
+ game.selected_general = id
+ game.selected_militia = -1
+ game.state = "force_march"
+ },
+}
+
+states.force_march = {
+ prompt() {
+ prompt("Force March: Move Army or Initiate Battle.")
+
+ let where = UNAVAILABLE
+ view.color = MILITARY
+ if (game.selected_general > 0) {
+ view.selected_general = game.selected_general
+ where = get_general_location(game.selected_general)
+ } else {
+ view.selected_militia = game.selected_militia
+ where = game.selected_militia
+ }
+
+ // Initiate Battle
+ gen_initiate_battle(where)
+
+ // Move Army
+ if (game.selected_general > 0) {
+ for (let to of ADJACENT[where]) {
+ if (!is_sea(to)) {
+ gen_action_region(to)
+ if (can_enter_capital(to))
+ gen_action_capital(to)
+ }
+ }
+
+ // Free Action: Enter/Leave Capital
+ if (is_province(where)) {
+ if (is_general_inside_capital(game.selected_general)) {
+ view.actions.leave = 1
+ } else if (can_enter_capital(where)) {
+ view.actions.enter = 1
+ gen_action_capital(where)
+ }
+ }
+ }
+ },
+
+ general(id) {
+ push_undo()
+ goto_battle_vs_general(get_general_location(game.selected_general), game.selected_general, id)
+ },
+
+ militia(where) {
+ push_undo()
+ goto_battle_vs_militia(where, game.selected_general)
+ },
+
+ barbarian(id) {
+ push_undo()
+ goto_battle_vs_barbarian(get_selected_region(), game.selected_general, id)
+ },
+
+ rival_emperor(id) {
+ push_undo()
+ goto_battle_vs_rival_emperor(get_selected_region(), game.selected_general, id)
+ },
+
+ region(where) {
+ push_undo()
+ move_army_to(game.selected_general, where)
+ },
+
+ capital(where) {
+ push_undo()
+ if (get_general_location(game.selected_general) !== where)
+ move_army_to(game.selected_general, where)
+ enter_capital()
+ },
+
+ enter() {
+ push_undo()
+ enter_capital()
+ game.state = "take_actions"
+ },
+
+ leave() {
+ push_undo()
+ set_general_outside_capital(game.selected_general)
+ remove_general_castra(game.selected_general)
+ game.state = "take_actions"
+ },
+}
+
+// CARD: Frumentarii
+
+function can_play_frumentarii() {
+ return !used_card_event(CARD_S3X)
+}
+
+function play_frumentarii() {
+ log("Frumentarii.")
+ game.frumentarii |= (1 << game.current)
+}
+
+// CARD: Mobile Vulgus
+
+function can_play_mobile_vulgus() {
+ for (let where = 0; where < 12; ++where) {
+ if (is_enemy_province(where)) {
+ let n = get_support(where) * 2 + count_units_in_capital(where)
+ if (game.pip >= n)
+ return true
+ }
+ }
+ return false
+}
+
+function play_mobile_vulgus() {
+ game.state = "mobile_vulgus_where"
+}
+
+states.mobile_vulgus_where = {
+ prompt() {
+ prompt("Mobile Vulgus: Choose a province...")
+ view.color = POPULACE
+ for (let where = 0; where < 12; ++where) {
+ if (is_enemy_province(where)) {
+ let n = get_support(where) * 2 + count_units_in_capital(where)
+ if (game.pip >= n)
+ gen_action_region(where)
+ }
+ }
+ },
+ region(where) {
+ log("Mobile Vulgus in %" + where + ".")
+ game.where = where
+ game.state = "mobile_vulgus"
+ },
+}
+
+states.mobile_vulgus = {
+ prompt() {
+ prompt("Mobile Vulgus: " + game.pip + " populace. Reduce support in " + REGION_NAME[game.where] + ".")
+ let n = get_support(game.where) * 2 + count_units_in_capital(game.where)
+ if (game.pip >= n)
+ gen_action_support(game.where, get_support(game.where) - 1)
+ view.actions.done = 1
+ },
+ support() {
+ push_undo()
+ log("Reduce support level in %" + game.where + ".")
+ let n = get_support(game.where) * 2 + count_units_in_capital(game.where)
+ spend_populace(n)
+ reduce_support(game.where)
+ if (is_neutral_province(game.where))
+ game.state = "take_actions"
+ },
+ done() {
+ push_undo()
+ game.state = "take_actions"
+ },
+}
+
+// CARD: Triumph
+
+function play_triumph() {
+ log("Triumph.")
+ // TODO
+}
+
+// CARD: Demagogue
+
+function can_play_demagogue() {
+ return !used_card_event(CARD_P4X)
+}
+
+function play_demagogue() {
+ log("Demagogue.")
+ // TODO
+}
+
// === COMBAT ===
function play_flanking_maneuver() {
game.combat.flanking = 1
}
+function play_cavalry() {
+ game.combat.cavalry = 1
+}
+
+function play_spiculum() {
+ game.combat.spiculum = 1
+ game.state = "spiculum"
+ // TODO
+}
+
function goto_battle_vs_general(where, attacker, target) {
goto_battle("general", where, attacker, target)
}
@@ -3004,6 +3312,16 @@ states.initiate_battle = {
gen_card_event(CARD_M3)
}
+ if (!game.combat.cavalry && has_card_event(CARD_M2X)) {
+ view.prompt += " Cavalry?"
+ gen_card_event(CARD_M2X)
+ }
+
+ if (!game.combat.spiculum && has_card_event(CARD_M4X)) {
+ view.prompt += " Spiculum?"
+ gen_card_event(CARD_M4X)
+ }
+
view.actions.roll = 1
},
card(c) {
@@ -3419,6 +3737,8 @@ states.combat_victory = {
prompt("Combat: There is no winner.")
else if (de || game.combat.dtaken > game.combat.ataken)
prompt("Combat: You win the battle!")
+ else if (game.combat.dtaken === game.combat.ataken && game.combat.cavalry)
+ prompt("Combat: You win the battle!")
else
prompt("Combat: Defenders win the battle!")
view.actions.done = 1
@@ -3552,8 +3872,12 @@ function goto_free_increase_support_level() {
}
}
- game.combat = null
- game.state = "take_actions"
+ if (game.combat.target === "barbarians" && has_card_event(CARD_S4X)) {
+ game.state = "triumph"
+ } else {
+ game.combat = null
+ game.state = "take_actions"
+ }
}
states.free_increase_support_level = {
@@ -3581,6 +3905,28 @@ states.free_increase_support_level = {
},
}
+states.triumph = {
+ prompt() {
+ prompt("Combat: You may play Triumph.")
+ gen_card_event(CARD_S4X)
+ view.actions.pass = 1
+ },
+ card(c) {
+ push_undo()
+ set_add(game.used, c)
+
+ award_legacy(game.current, "Triumph", game.combat.dtaken)
+
+ game.combat = null
+ game.state = "take_actions"
+ },
+ pass() {
+ push_undo()
+ game.combat = null
+ game.state = "take_actions"
+ },
+}
+
// === SUPPORT CHECK ===
function goto_support_check() {
@@ -3819,13 +4165,40 @@ function goto_buy_trash_cards() {
log("Played no cards.")
log_br()
+ //log_h3("Buy/Trash Cards")
+
+ game.pp = count_political_points()
+
+ log_h3(game.pp + " Political Points")
+ if (used_card_event(CARD_S2X)) {
+ let n = Math.min(2, game.sip)
+ if (n > 0) {
+ logi("+" + n + " for Princeps Senatus")
+ game.pp += n
+ }
+ }
+
+ game.mip = game.sip = game.pip = 0
+ for (let i = 0; i < 3; ++i) {
+ if (game.killed & (1 << i)) {
+ logi("+2 senate credits")
+ game.sip += 2
+ }
+ }
+ for (let i = 3; i < 6; ++i) {
+ if (game.killed & (1 << i)) {
+ logi("+2 military credits")
+ game.mip += 2
+ }
+ }
+
let discard = current_discard()
for (let c of game.played)
set_add(discard, c)
-
game.played.length = 0
+ game.used.length = 0
+
game.count = 0
- game.pp = count_political_points()
if (game.end)
goto_end_of_turn()
@@ -3862,47 +4235,26 @@ function find_market_with_card(c) {
return null
}
-function has_military_card_bonus() {
- let military_bonus = 0
- if (game.killed & CNIVA_BONUS)
- military_bonus += 2
- if (game.killed & ARDASHIR_BONUS)
- military_bonus += 2
- if (game.killed & SHAPUR_BONUS)
- military_bonus += 2
- return military_bonus
+function spend_military_credit(cost) {
+ let credit = Math.min(cost, game.mip)
+ game.mip -= credit
+ return cost - credit
}
-function has_senate_card_bonus() {
- let senate_bonus = 0
- if (game.killed & (1 << POSTUMUS))
- senate_bonus += 2
- if (game.killed & (1 << PRIEST_KING))
- senate_bonus += 2
- if (game.killed & (1 << ZENOBIA))
- senate_bonus += 2
- return senate_bonus
-}
-
-function spend_military_card_bonus() {
- game.killed &= ~(CNIVA_BONUS | ARDASHIR_BONUS | SHAPUR_BONUS)
-}
-
-function spend_senate_card_bonus() {
- game.killed &= ~((1 << POSTUMUS) | (1 << PRIEST_KING) | (1 << ZENOBIA))
+function spend_senate_credit(cost) {
+ let credit = Math.min(cost, game.sip)
+ game.mip -= credit
+ return cost - credit
}
states.buy_trash = {
inactive: "Buy/Trash Cards",
prompt() {
- let military_bonus = has_military_card_bonus()
- let senate_bonus = has_senate_card_bonus()
-
prompt("Buy/Trash Cards: " + game.pp + " political points.")
- if (military_bonus)
- view.prompt += " First Military card is 2 cheaper."
- if (senate_bonus)
- view.prompt += " First Senate card is 2 cheaper."
+ if (game.mip > 0)
+ view.prompt += " " + game.mip + " military credits."
+ if (game.sip > 0)
+ view.prompt += " " + game.mip + " senate credits."
let nprov = count_own_provinces()
if (game.pp >= 3) {
@@ -3916,10 +4268,10 @@ states.buy_trash = {
if (cost > nprov)
cost *= 2
cost += game.count
- if (military_bonus && card_influence(c) === MILITARY)
- cost -= 2
- if (senate_bonus && card_influence(c) === SENATE)
- cost -= 2
+ if (card_influence(c) === MILITARY)
+ cost = Math.max(0, cost - game.mip)
+ if (card_influence(c) === SENATE)
+ cost = Math.max(0, cost - game.sip)
if (game.pp >= cost)
gen_action_card(c)
}
@@ -3933,9 +4285,6 @@ states.buy_trash = {
set_delete(current_discard(), c)
game.pp -= 3
} else {
- let military_bonus = has_military_card_bonus()
- let senate_bonus = has_senate_card_bonus()
-
log("Buy " + card_name(c) + ".")
set_add(current_discard(), c)
set_delete(find_market_with_card(c), c)
@@ -3945,14 +4294,10 @@ states.buy_trash = {
cost *= 2
cost += game.count
- if (military_bonus && card_influence(c) === MILITARY) {
- spend_military_card_bonus()
- cost -= 2
- }
- if (senate_bonus && card_influence(c) === SENATE) {
- spend_senate_card_bonus()
- cost -= 2
- }
+ if (card_influence(c) === MILITARY)
+ cost = spend_military_credit(cost)
+ if (card_influence(c) === SENATE)
+ cost = spend_senate_credit(cost)
game.pp -= cost
game.count += 1
@@ -4243,6 +4588,10 @@ exports.setup = function (seed, scenario, options) {
killed: 0,
combat: null,
+ ambitus: 0,
+ frumentarii: 0,
+ force_march: 0,
+
provinces: new Array(3 * player_count).fill(1),
governors: new Array(6 * player_count).fill(UNAVAILABLE),
generals: new Array(6 * player_count).fill(UNAVAILABLE),
@@ -4264,17 +4613,57 @@ exports.setup = function (seed, scenario, options) {
game.events = setup_events()
- game.market = [
- setup_market_pile(CARD_M2),
- setup_market_pile(CARD_S2),
- setup_market_pile(CARD_P2),
- setup_market_pile(CARD_M3),
- setup_market_pile(CARD_S3),
- setup_market_pile(CARD_P3),
- setup_market_pile(CARD_M4),
- setup_market_pile(CARD_S4),
- setup_market_pile(CARD_P4),
- ]
+ switch (scenario) {
+ default:
+ case "Standard":
+ game.market = [
+ setup_market_pile(CARD_M2),
+ setup_market_pile(CARD_S2),
+ setup_market_pile(CARD_P2),
+ setup_market_pile(CARD_M3),
+ setup_market_pile(CARD_S3),
+ setup_market_pile(CARD_P3),
+ setup_market_pile(CARD_M4),
+ setup_market_pile(CARD_S4),
+ setup_market_pile(CARD_P4),
+ ]
+ break
+ case "Expansion":
+ game.market = [
+ setup_market_pile(CARD_M2),
+ setup_market_pile(CARD_S2),
+ setup_market_pile(CARD_P2),
+ setup_market_pile(CARD_M2X),
+ setup_market_pile(CARD_S2X),
+ setup_market_pile(CARD_P2X),
+ setup_market_pile(CARD_M3),
+ setup_market_pile(CARD_S3),
+ setup_market_pile(CARD_P3),
+ setup_market_pile(CARD_M3X),
+ setup_market_pile(CARD_S3X),
+ setup_market_pile(CARD_P3X),
+ setup_market_pile(CARD_M4),
+ setup_market_pile(CARD_S4B),
+ setup_market_pile(CARD_P4),
+ setup_market_pile(CARD_M4X),
+ setup_market_pile(CARD_S4X),
+ setup_market_pile(CARD_P4X),
+ ]
+ break
+ case "Random":
+ game.market = [
+ setup_market_pile(random(2) ? CARD_M2 : CARD_M2X),
+ setup_market_pile(random(2) ? CARD_S2 : CARD_S2X),
+ setup_market_pile(random(2) ? CARD_P2 : CARD_P2X),
+ setup_market_pile(random(2) ? CARD_M3 : CARD_M3X),
+ setup_market_pile(random(2) ? CARD_S3 : CARD_S3X),
+ setup_market_pile(random(2) ? CARD_P3 : CARD_P3X),
+ setup_market_pile(random(2) ? CARD_M4 : CARD_M4X),
+ setup_market_pile(random(2) ? CARD_S4B : CARD_S4X),
+ setup_market_pile(random(2) ? CARD_P4 : CARD_P4X),
+ ]
+ break
+ }
set_rival_emperor_location(POSTUMUS, AVAILABLE)
set_rival_emperor_location(PRIEST_KING, AVAILABLE)