summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Andersson <tor@ccxvii.net>2023-06-21 21:18:28 +0200
committerTor Andersson <tor@ccxvii.net>2023-07-07 18:39:37 +0200
commit78eb830571c26ebbfbcb8bc0608b11db868aeb90 (patch)
tree48b672dd6125849e851ed21e71d3d69ff7fe5292
parentd8aa3a523ce28ec3e3e616ad2c090bd3f4f835fa (diff)
downloadtime-of-crisis-78eb830571c26ebbfbcb8bc0608b11db868aeb90.tar.gz
Praetorian Guard.
-rw-r--r--play.css21
-rw-r--r--play.js6
-rw-r--r--rules.js213
3 files changed, 163 insertions, 77 deletions
diff --git a/play.css b/play.css
index b2ea395..f23699f 100644
--- a/play.css
+++ b/play.css
@@ -90,6 +90,14 @@ body.senate svg .region.selected {
stroke-dasharray: 8 4;
}
+body.military svg .region.selected {
+ fill: hsl(358, 78%, 51%);
+ fill-opacity: 0.3;
+ stroke: hsl(358, 78%, 51%);
+ stroke-width: 4px;
+ stroke-dasharray: 8 4;
+}
+
body.military svg .sea.action {
fill: hsl(206, 100%, 35%);
fill-opacity: 0.25;
@@ -174,20 +182,11 @@ body.military svg .sea.action {
.capital.action {
display: block;
border: 5px solid white;
- //box-shadow: 0px 0px 8px white;
+ background-color: #fff8;
+ box-shadow: 0 0 6px white, inset 0 0 6px black;
z-index: 2;
}
-body.military .capital.action {
- border-color: hsl(358, 78%, 51%);
- background-color: hsla(358, 75%, 51%, 0.2);
-}
-
-body.populace .capital.action {
- border-color: hsl(44, 80%, 52%);
- background-color: hsla(44, 80%, 52%, 0.2);
-}
-
body.p3 #Hispania_NPG { display: block }
body.p3 #Africa_NPG { display: block }
body.p3 #Aegyptus_NPG { display: block }
diff --git a/play.js b/play.js
index 18550e4..09e9217 100644
--- a/play.js
+++ b/play.js
@@ -747,11 +747,13 @@ function layout_available(list, dx, x0, y0) {
let y = 1650 + 45 - y0
let x = 25 + x0
for (let item of list) {
- item.style.left = x + "px"
+ let xo = item.my_id % 6
+ if (list.length < 6)
+ xo -= 1
+ item.style.left = (x + xo * dx) + "px"
item.style.top = y + "px"
item.style.zIndex = 1
item.my_stack = 0
- x += dx
}
}
diff --git a/rules.js b/rules.js
index 7c2d3e3..d131ceb 100644
--- a/rules.js
+++ b/rules.js
@@ -50,7 +50,7 @@ TODO
[x] grow mobs
[x] flip barbarians
-[ ] praetorian guard
+[x] praetorian guard
[ ] damnatio memoriae
[ ] pretender
[ ] place
@@ -1218,7 +1218,7 @@ states.take_actions = {
gen_action_governor(id)
break
case AVAILABLE:
- if (sip >= 1)
+ if (sip >= 1 || has_unused_praetorian_guard())
gen_action_governor(id)
break
default:
@@ -1485,14 +1485,9 @@ states.take_actions = {
set_legion_full_strength(find_reduced_legion_in_army(game.selected_general))
},
- capital(where) {
- push_undo()
- set_general_inside_capital(game.selected_general)
- },
-
enter() {
push_undo()
- set_general_inside_capital(game.selected_general)
+ enter_capital()
},
leave() {
@@ -1525,10 +1520,17 @@ states.take_actions = {
if (get_general_location(game.selected_general) === AVAILABLE)
create_army(where)
else
- move_army_to(game.selected_general, where, true)
+ 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()
+ },
+
barbarian(id) {
push_undo()
goto_battle_vs_barbarian(get_general_location(game.selected_general), game.selected_general, id)
@@ -1545,6 +1547,13 @@ states.take_actions = {
},
}
+// FREE ACTION: ENTER PROVINCIAL CAPITAL
+
+function enter_capital() {
+ set_general_inside_capital(game.selected_general)
+ // TODO: seat of power / breakaway
+}
+
// ACTION: IMPROVE SUPPORT
function improve_support() {
@@ -1633,38 +1642,41 @@ function place_governor(where, new_governor) {
update_neutral_italia()
}
-function calc_needed_votes(where) {
+function calc_needed_votes(where, pg) {
let n = get_support(where) * 2 // base number of votes
let old_governor = get_province_governor(where)
let old_player = (old_governor < 0) ? -1 : (old_governor / 6 | 0)
- let army_general = get_capital_general(where)
- if (army_general >= 0) {
- let army_player = army_general / 6 | 0
- let army_size = count_units_in_army(army_general)
- if (army_player === old_player)
- n += army_size
- else if (army_player === game.current)
- n -= army_size
+ // Praetorian Guard ignores units in capital
+ if (!pg) {
+ let army_general = get_capital_general(where)
+ if (army_general >= 0) {
+ let army_player = army_general / 6 | 0
+ let army_size = count_units_in_army(army_general)
+ if (army_player === old_player)
+ n += army_size
+ else if (army_player === game.current)
+ n -= army_size
+ }
+ if (has_militia(where))
+ n += 1
}
- if (has_militia(where))
- n += 1
return Math.max(1, n)
}
states.place_governor = {
prompt() {
let [ mip, sip, pip ] = game.ip
- let need = calc_needed_votes(game.misc.where)
+ let need = calc_needed_votes(game.misc.where, false)
let votes = game.misc.spend
if (game.misc.where === ITALIA)
votes += count_own_basilicas()
view.color = SENATE
view.selected_region = game.misc.where
-
prompt(`Place Governor: ${sip} Senate. Rolling ${votes} dice. ${need} votes needed.`)
-
- view.actions.spend_senate = (sip >= 1)
-
+ if (sip >= 1)
+ view.actions.spend_senate = 1
+ else
+ view.actions.spend_senate = 0
view.actions.roll = 1
},
spend_senate() {
@@ -1673,33 +1685,96 @@ states.place_governor = {
game.misc.spend += 1
},
roll() {
- let need = calc_needed_votes(game.misc.where)
- let have = 0
-
- set_placed_governor(game.misc.where)
+ roll_to_place_governor()
+ },
+}
+states.praetorian_guard = {
+ prompt() {
+ let [ mip, sip, pip ] = game.ip
+ let need = calc_needed_votes(game.misc.where, true)
+ let votes = game.misc.spend
if (game.misc.where === ITALIA)
- game.misc.spend += count_own_basilicas()
+ votes += count_own_basilicas()
+ view.color = MILITARY
+ view.selected_region = game.misc.where
+ prompt(`Praetorian Guard: ${mip} Military. Rolling ${votes} dice. ${need} votes needed.`)
+ if (mip >= 1)
+ view.actions.spend_military = 1
+ else
+ view.actions.spend_military = 0
+ view.actions.roll = 1
+ },
+ spend_military() {
+ push_undo()
+ spend_ip(MILITARY, 1)
+ game.misc.spend += 1
+ },
+ roll() {
+ roll_to_place_governor()
+ },
+}
+function roll_to_place_governor(pg) {
+ let need = calc_needed_votes(game.misc.where, pg)
+ let have = 0
+
+ set_placed_governor(game.misc.where)
+
+ if (game.misc.where === ITALIA)
+ game.misc.spend += count_own_basilicas()
+
+ if (pg)
+ log("Praetorian Guard in S" + game.misc.where)
+ else
log("Place Governor in S" + game.misc.where)
- if (is_neutral_province(game.misc.where))
- have = roll_dice(game.misc.spend, 1)
- else if (has_quaestor(game.misc.where))
- have = roll_dice(game.misc.spend, 3)
- else
- have = roll_dice(game.misc.spend, 2)
- if (have >= need) {
- logi("Success!")
- place_governor(game.misc.where, game.selected_governor)
- } else {
- logi("Failed!")
- game.selected_governor = -1
- }
+ if (is_neutral_province(game.misc.where))
+ have = roll_dice(game.misc.spend, 1)
+ else if (!pg && has_quaestor(game.misc.where))
+ have = roll_dice(game.misc.spend, 3)
+ else
+ have = roll_dice(game.misc.spend, 2)
- game.misc = null
- game.state = "take_actions"
- },
+ if (have >= need) {
+ logi("Success!")
+ place_governor(game.misc.where, game.selected_governor)
+ } else {
+ logi("Failed!")
+ }
+
+ game.misc = null
+ game.state = "take_actions"
+}
+
+// ACTION: PRAETORIAN GUARD
+
+function has_unused_praetorian_guard() {
+ return game.ip[MILITARY] >= 1 && !is_own_province(ITALIA) && !has_placed_governor(ITALIA) && has_praetorian_guard_card()
+}
+
+function has_praetorian_guard_card() {
+ let played = false
+ let used = false
+ for (let c of game.played)
+ if (c >= CARD_M4[0] && c <= CARD_M4[1])
+ played = true
+ for (let c of game.used)
+ if (c >= CARD_M4[0] && c <= CARD_M4[1])
+ used = true
+ return played && !used
+}
+
+function can_play_praetorian_guard() {
+ if (game.selected_governor >= 0 && get_governor_location(game.selected_governor) === AVAILABLE)
+ return game.ip[MILITARY] >= 1 && !is_own_province(ITALIA) && !has_placed_governor(ITALIA)
+ return false
+}
+
+function play_praetorian_guard() {
+ spend_ip(MILITARY, 1)
+ game.misc = { spend: 1, where: ITALIA }
+ game.state = "praetorian_guard"
}
// ACTION: CREATE ARMY
@@ -1729,9 +1804,11 @@ function gen_move_army() {
let from = get_general_location(game.selected_general)
if (mip >= 1) {
for (let to of ADJACENT[from]) {
- if (!is_sea(to))
+ if (!is_sea(to)) {
gen_action_region(to)
- else if (mip >= 2)
+ if (can_enter_capital(to))
+ gen_action_capital(to)
+ } else if (mip >= 2)
gen_action_region(to)
}
}
@@ -1746,23 +1823,22 @@ states.move_army_at_sea = {
},
region(to) {
push_undo()
- move_army_to(game.selected_general, to, true)
+ move_army_to(game.selected_general, to)
},
capital(to) {
push_undo()
- move_army_to(game.selected_general, to, true)
+ move_army_to(game.selected_general, to)
+ enter_capital()
},
}
-function move_army_to(who, to, go_inside) {
+function move_army_to(who, to) {
log("Moved Army to S" + to + ".")
remove_general_castra(who)
spend_ip(MILITARY, 1)
set_general_location(who, to)
- if (can_enter_capital(to) && go_inside)
- set_general_inside_capital(who)
if (is_sea(to))
game.state = "move_army_at_sea"
@@ -1855,15 +1931,17 @@ function can_foederati_from_region(where) {
return false
}
-function gen_foederati(where) {
+function gen_foederati(where, recruit) {
let tribe_count = get_tribe_count()
for (let tribe = 0; tribe < tribe_count; ++tribe) {
let id = find_active_barbarian_of_tribe(where, tribe)
if (id >= 0)
gen_action_barbarian(id)
- id = find_inactive_barbarian_of_tribe(where, tribe)
- if (id >= 0)
- gen_action_barbarian(id)
+ if (recruit || is_province(where)) {
+ id = find_inactive_barbarian_of_tribe(where, tribe)
+ if (id >= 0)
+ gen_action_barbarian(id)
+ }
}
}
@@ -1877,10 +1955,13 @@ function can_foederati_from_region_and_adjacent(from) {
}
function can_play_foederati() {
+ let where = get_selected_region()
if (game.selected_general >= 0)
- if (count_legions_in_army(game.selected_general) > count_barbarians_in_army(game.selected_general))
- if (can_foederati_from_region_and_adjacent(get_general_location(game.selected_general)))
- return true
+ if (can_foederati_from_region_and_adjacent(where))
+ return true
+ if (game.selected_governor >= 0)
+ if (has_lone_militia(where) && can_foederati_from_region_and_adjacent(where))
+ return true
return false
}
@@ -1890,18 +1971,22 @@ function play_foederati() {
states.foederati = {
prompt() {
- prompt("Foederati: Recruit a Barbarian.")
+ prompt("Foederati: Remove or recruit a Barbarian.")
view.selected_general = game.selected_general
let from = get_general_location(game.selected_general)
- gen_foederati(from)
+ let recruit = (game.selected_general >= 0 && count_legions_in_army(game.selected_general) > count_barbarians_in_army(game.selected_general))
+ gen_foederati(from, recruit)
for (let to of ADJACENT[from])
- gen_foederati(to)
+ gen_foederati(to, recruit)
},
barbarian(id) {
let tribe = get_barbarian_tribe(id)
let from = get_barbarian_location(id)
log("Foederati " + BARBARIAN_NAME[tribe] + " from S" + from)
- set_barbarian_location(id, ARMY + game.selected_general)
+ if (game.selected_general >= 0 && count_legions_in_army(game.selected_general) > count_barbarians_in_army(game.selected_general))
+ set_barbarian_location(id, ARMY + game.selected_general)
+ else
+ eliminate_barbarian(id)
game.state = "take_actions"
},
}