summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Andersson <tor@ccxvii.net>2023-06-21 13:56:02 +0200
committerTor Andersson <tor@ccxvii.net>2023-07-07 18:39:37 +0200
commit45501d068bfed96bfe0713b228f6a018a4528b89 (patch)
tree5f844e5c600c939a7e0b3bfb8d61ad59c76ba86b
parentf8d83c065a6ed85026a9bcadbdc961a0afea684e (diff)
downloadtime-of-crisis-45501d068bfed96bfe0713b228f6a018a4528b89.tar.gz
Card events.
-rw-r--r--play.css4
-rw-r--r--play.js20
-rw-r--r--rules.js153
3 files changed, 147 insertions, 30 deletions
diff --git a/play.css b/play.css
index 0a283d5..b0df22d 100644
--- a/play.css
+++ b/play.css
@@ -431,6 +431,10 @@ body.p2 #Galatia_NPG { display: block }
transform: translate(0px, 0px);
}
+.card.used {
+ filter: brightness(75%)
+}
+
#discard .card.action {
box-shadow: 0 0 0px 3px #a00;
}
diff --git a/play.js b/play.js
index 05e0742..da6f215 100644
--- a/play.js
+++ b/play.js
@@ -1033,32 +1033,42 @@ function on_update() {
ui.played.replaceChildren()
if (view.played) {
- for (let c of view.played)
+ for (let c of view.played) {
ui.played.appendChild(ui.cards[c])
+ ui.cards[c].classList.toggle("used", set_has(view.used, c))
+ }
}
ui.hand.replaceChildren()
if (view.hand) {
- for (let c of view.hand)
+ for (let c of view.hand) {
ui.hand.appendChild(ui.cards[c])
+ ui.cards[c].classList.remove("used")
+ }
}
ui.draw.replaceChildren()
if (view.draw) {
- for (let c of view.draw)
+ for (let c of view.draw) {
ui.draw.appendChild(ui.cards[c])
+ ui.cards[c].classList.remove("used")
+ }
}
ui.discard.replaceChildren()
if (view.discard) {
- for (let c of view.discard)
+ for (let c of view.discard) {
ui.discard.appendChild(ui.cards[c])
+ ui.cards[c].classList.remove("used")
+ }
}
ui.market.replaceChildren()
for (let c of view.market) {
- if (c > 0)
+ if (c > 0) {
ui.market.appendChild(ui.cards[c])
+ ui.cards[c].classList.remove("used")
+ }
}
for (let e of action_register)
diff --git a/rules.js b/rules.js
index 408175f..9c34674 100644
--- a/rules.js
+++ b/rules.js
@@ -10,7 +10,7 @@ TODO
[x] crisis barbarians
[ ] crisis pax deorum
-[ ] tribute
+[x] tribute
[ ] foederati
[ ] mobs
@@ -22,15 +22,15 @@ TODO
[ ] combat advance into capital
[ ] combat flanking maneuver
-[ ] quaestor
- [ ] place
- [ ] remove at start
- [ ] remove when replaced
+[x] quaestor
+ [x] place
+ [x] remove at start
+ [x] remove when replaced
[ ] castra
- [ ] place
- [ ] remove at start
- [ ] remove when move/attack
+ [x] place
+ [x] remove at start
+ [x] remove when move/attack
[ ] take hits in battle
[ ] support check
@@ -197,7 +197,6 @@ const GOTHS = 2
const NOMADS = 3
const SASSANIDS = 4
-const TRIBE_COUNT = [ 0, 5, 3, 4, 5 ]
const BARBARIAN_COUNT = [ 0, 50, 30, 40, 50 ]
const first_barbarian = [ 0, 10, 20, 30, 40 ]
const last_barbarian = [ 9, 19, 29, 39, 49 ]
@@ -384,10 +383,31 @@ function card_event_name(c) {
}
function can_play_card_event(c) {
+ if (c >= CARD_M1[0] && c <= CARD_M1[1]) return false
+ if (c >= CARD_M2[0] && c <= CARD_M2[1]) return can_play_castra()
+ if (c >= CARD_M3[0] && c <= CARD_M3[1]) return false // "Flanking Maneuver"
+ if (c >= CARD_M4[0] && c <= CARD_M4[1]) return can_play_praetorian_guard()
+ if (c >= CARD_S1[0] && c <= CARD_S1[1]) return false
+ if (c >= CARD_S2[0] && c <= CARD_S2[1]) return can_play_tribute()
+ if (c >= CARD_S3[0] && c <= CARD_S3[1]) return can_play_foederati()
+ if (c >= CARD_S4[0] && c <= CARD_S4[1]) return false // "Damnatio Memoriae"
+ if (c >= CARD_P1[0] && c <= CARD_P1[1]) return false
+ if (c >= CARD_P2[0] && c <= CARD_P2[1]) return can_play_quaestor()
+ if (c >= CARD_P3[0] && c <= CARD_P3[1]) return can_play_mob()
+ if (c >= CARD_P4[0] && c <= CARD_P4[1]) return false // "Pretender"
return false
}
function play_card_event(c) {
+ if (c >= CARD_M2[0] && c <= CARD_M2[1]) play_castra()
+ if (c >= CARD_M3[0] && c <= CARD_M3[1]) play_flanking_maneuver()
+ if (c >= CARD_M4[0] && c <= CARD_M4[1]) play_praetorian_guard()
+ if (c >= CARD_S2[0] && c <= CARD_S2[1]) play_tribute()
+ if (c >= CARD_S3[0] && c <= CARD_S3[1]) play_foederati()
+ if (c >= CARD_S4[0] && c <= CARD_S4[1]) play_damnatio_memoriae()
+ if (c >= CARD_P2[0] && c <= CARD_P2[1]) play_quaestor()
+ if (c >= CARD_P3[0] && c <= CARD_P3[1]) play_mob()
+ if (c >= CARD_P4[0] && c <= CARD_P4[1]) play_pretender()
}
function add_card_ip(c) {
@@ -513,6 +533,14 @@ function set_militia_battled(province) { game.mbattled |= (1 << province) }
// === COMPOUND STATE ===
+function get_selected_region() {
+ if (game.selected_governor >= 0)
+ return get_governor_location(game.selected_governor)
+ if (game.selected_general >= 0)
+ return get_governor_location(game.selected_general)
+ return UNAVAILABLE
+}
+
function for_each_current_general(f) {
let a = game.current * 6
for (let id = a; id < a + 6; ++id)
@@ -618,6 +646,10 @@ function get_player_count() {
return game.legacy.length
}
+function get_tribe_count() {
+ return game.legacy.length + 1
+}
+
function can_enter_capital(where) {
// No Capital
if (is_no_place_governor(where))
@@ -678,6 +710,13 @@ function has_active_barbarians(where) {
return some_barbarian((id, loc, active) => loc === where && active)
}
+function find_active_barbarian_of_tribe(where, tribe) {
+ for (let id = first_barbarian[tribe]; id <= last_barbarian[tribe]; ++id)
+ if (get_barbarian_location(id) === where && is_barbarian_active(id))
+ return id
+ return -1
+}
+
function has_barbarian_leader(where) {
for (let i = 0; i < 3; ++i)
if (game.barbarian_leaders[i] === where)
@@ -969,7 +1008,7 @@ function goto_ira_deorum() {
logi("Ira Deorum")
game.count = 0
- let tribe_count = BARBARIAN_COUNT[get_player_count()]
+ let tribe_count = get_tribe_count()
for (let tribe = 0; tribe < tribe_count; ++tribe)
if (find_inactive_barbarian_at_home(tribe) >= 0)
game.count |= (1 << tribe)
@@ -982,7 +1021,7 @@ function goto_ira_deorum() {
states.ira_deorum = {
prompt() {
prompt("Ira Deorum: Activate one Barbarian in each tribe's homeland.")
- let tribe_count = BARBARIAN_COUNT[get_player_count()]
+ let tribe_count = get_tribe_count()
for (let tribe = 0; tribe < tribe_count; ++tribe)
if (game.count & (1 << tribe))
gen_action_barbarian(find_inactive_barbarian_at_home(tribe))
@@ -1314,10 +1353,8 @@ states.take_actions = {
set_add(game.played, c)
add_card_ip(c)
} else if (set_has(game.played, c)) {
- log("TODO - use event")
- set_delete(game.played, c)
set_add(game.used, c)
- action_play_card_event(c)
+ play_card_event(c)
}
},
@@ -1507,6 +1544,8 @@ function remove_governor(where) {
remove_all_mobs(where)
remove_militia(where)
+ remove_militia_castra(where)
+ remove_quaestor(where)
let old_governor = get_province_governor(where)
if (old_governor >= 0) {
@@ -1524,6 +1563,7 @@ function remove_governor(where) {
function place_governor(where, new_governor) {
remove_all_mobs(where)
remove_militia(where)
+ remove_militia_castra(where)
let old_governor = get_province_governor(where)
if (old_governor >= 0) {
@@ -1642,19 +1682,13 @@ function gen_move_army() {
if (mip >= 1) {
for (let to of ADJACENT[from]) {
if (!is_sea(to))
- gen_move_to_region(to)
+ gen_action_region(to)
else if (mip >= 2)
- gen_move_to_region(to)
+ gen_action_region(to)
}
}
}
-function gen_move_to_region(to) {
-// if (is_province(to) && can_enter_capital(to))
-// gen_action_capital(to)
- gen_action_region(to)
-}
-
states.move_army_at_sea = {
prompt() {
let [ mip, sip, pip ] = game.ip
@@ -1664,7 +1698,6 @@ states.move_army_at_sea = {
},
region(to) {
push_undo()
- // XXX move_army_to(game.selected_general, to, false)
move_army_to(game.selected_general, to, true)
},
capital(to) {
@@ -1676,6 +1709,8 @@ states.move_army_at_sea = {
function move_army_to(who, to, go_inside) {
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)
@@ -1687,6 +1722,71 @@ function move_army_to(who, to, go_inside) {
game.state = "take_actions"
}
+// CARD: CASTRA
+
+function can_play_castra() {
+ let where = get_selected_region()
+ if (game.selected_governor >= 0 && is_province(where))
+ return has_lone_militia(where) && !has_militia_castra(where)
+ if (game.selected_general >= 0 && is_province(where))
+ return !has_general_castra(where)
+ return false
+}
+
+function play_castra() {
+ let where = get_selected_region()
+ if (game.selected_governor >= 0 && is_province(where))
+ add_militia_castra(where)
+ if (game.selected_general >= 0)
+ add_general_castra(game.selected_general)
+}
+
+function can_play_quaestor() {
+ let where = get_selected_region()
+ if (game.selected_governor >= 0 && is_province(where))
+ return !has_quaestor(where)
+ return false
+}
+
+function play_quastor() {
+ let where = get_selected_region()
+ add_quaestor(where)
+}
+
+function can_play_tribute() {
+ for (let where = 0; where < 12; ++where)
+ if (has_active_barbarians(where))
+ return true
+ return false
+}
+
+function play_tribute() {
+ game.state = "tribute"
+}
+
+states.tribute = {
+ prompt() {
+ prompt("Tribute: Flip a single tribe to their inactive side in any province.")
+ let tribe_count = get_tribe_count()
+ for (let where = 0; where < 12; ++where) {
+ for (let tribe = 0; tribe < tribe_count; ++tribe) {
+ let id = find_active_barbarian_of_tribe(where, tribe)
+ if (id >= 0)
+ gen_action_barbarian(id)
+ }
+ }
+ },
+ barbarian(target) {
+ let where = get_barbarian_location(target)
+ let tribe = get_barbarian_tribe(target)
+ log("Tribute " + BARBARIAN_NAME[tribe] + " in S" + where)
+ for (let id = first_barbarian[tribe]; id <= last_barbarian[tribe]; ++id)
+ if (get_barbarian_location(id) === where && is_barbarian_active(id))
+ set_barbarian_inactive(id)
+ game.state = "take_actions"
+ },
+}
+
// === COMBAT ===
function goto_battle_vs_general(where, attacker, target) {
@@ -1713,10 +1813,12 @@ function goto_battle(type, where, attacker, target) {
spend_ip(MILITARY, 1)
game.misc = { type, where, attacker, target }
game.state = "battle"
- if (attacker >= 0)
+ if (attacker >= 0) {
+ remove_general_castra(who)
set_general_battled(attacker)
- else
+ } else {
set_militia_battled(where)
+ }
}
function gen_initiate_battle(where) {
@@ -2365,6 +2467,7 @@ exports.view = function (state, player_name) {
dice: game.dice,
events: game.active_events,
played: game.played,
+ used: game.used,
market: game.market.map(m => m[0] | 0),
legacy: game.legacy,