From 8b075ffb322b7f885aebe67d4712ffd008cb4878 Mon Sep 17 00:00:00 2001 From: Tor Andersson Date: Wed, 21 Jun 2023 14:57:49 +0200 Subject: Foederati. --- play.css | 4 ++ rules.js | 133 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 126 insertions(+), 11 deletions(-) diff --git a/play.css b/play.css index b0df22d..42f36d0 100644 --- a/play.css +++ b/play.css @@ -522,6 +522,10 @@ body.p2 #Galatia_NPG { display: block } .influence_p4 + .influence_p4 { margin-left: -180px; } .influence_s4 + .influence_s4 { margin-left: -180px; } +#played .influence_m1 + .influence_p1 { margin-left: -180px } +#played .influence_m1 + .influence_s1 { margin-left: -180px } +#played .influence_p1 + .influence_s1 { margin-left: -180px } + /* PANELS */ .panel { diff --git a/rules.js b/rules.js index 9c34674..ee5ea7f 100644 --- a/rules.js +++ b/rules.js @@ -6,21 +6,26 @@ TODO ---- +-- castra/quaestor - directly or extra select target step? + [x] crisis ira deorum [x] crisis barbarians [ ] crisis pax deorum [x] tribute -[ ] foederati +[x] foederati [ ] mobs [ ] disperse mob [ ] combat victory +[ ] combat remove general if army is eliminated +[ ] combat battle screen - splay stack / dialog for watching contents and taking hits [ ] combat retreat out of capital [ ] combat retreat barbarians to homeland [ ] combat advance into capital [ ] combat flanking maneuver +[ ] combat - select both inactive/active barbarian for hits [x] quaestor [x] place @@ -31,6 +36,7 @@ TODO [x] place [x] remove at start [x] remove when move/attack + [ ] move militia to general at end of turn [ ] take hits in battle [ ] support check @@ -710,6 +716,13 @@ function has_active_barbarians(where) { return some_barbarian((id, loc, active) => loc === where && active) } +function find_barbarian_of_tribe(where, tribe) { + for (let id = first_barbarian[tribe]; id <= last_barbarian[tribe]; ++id) + if (get_barbarian_location(id) === where) + return id + return -1 +} + 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)) @@ -717,6 +730,13 @@ function find_active_barbarian_of_tribe(where, tribe) { return -1 } +function find_inactive_barbarian_of_tribe(where, tribe) { + for (let id = first_barbarian[tribe]; id <= last_barbarian[tribe]; ++id) + if (get_barbarian_location(id) === where && is_barbarian_inactive(id)) + return id + return -1 +} + function has_barbarian_leader(where) { for (let i = 0; i < 3; ++i) if (game.barbarian_leaders[i] === where) @@ -811,10 +831,18 @@ function count_barbarians_in_province(tribe, where) { return n } -function count_legions_in_army(id) { +function count_legions_in_army(army_id) { let n = 0 - for (let i = 0; i < LEGION_COUNT; ++i) - if (get_legion_location(i) === ARMY + id) + for (let id = 0; id < LEGION_COUNT; ++id) + if (get_legion_location(id) === ARMY + army_id) + ++n + return n +} + +function count_barbarians_in_army(army_id) { + let n = 0 + for (let id = 0; id < game.barbarians.length; ++id) + if (get_barbarian_location(id) === ARMY + army_id) ++n return n } @@ -1342,6 +1370,9 @@ states.take_actions = { end_actions() { push_undo() + // TODO: move militia castra to castra with stacked general + game.selected_governor = -1 + game.selected_general = -1 goto_support_check() }, @@ -1647,6 +1678,7 @@ states.place_governor = { place_governor(game.misc.where, game.selected_governor) } else { logi("Failed!") + game.selected_governor = -1 } game.misc = null @@ -1735,12 +1767,18 @@ function can_play_castra() { function play_castra() { let where = get_selected_region() - if (game.selected_governor >= 0 && is_province(where)) + if (game.selected_governor >= 0 && is_province(where)) { + log("Castra in S" + where) add_militia_castra(where) - if (game.selected_general >= 0) + } + if (game.selected_general >= 0) { + log("Castra on " + GENERAL_NAME[game.selected_general]) add_general_castra(game.selected_general) + } } +// CARD: QUAESTOR + function can_play_quaestor() { let where = get_selected_region() if (game.selected_governor >= 0 && is_province(where)) @@ -1748,11 +1786,14 @@ function can_play_quaestor() { return false } -function play_quastor() { +function play_quaestor() { let where = get_selected_region() + log("Quaestor in S" + where) add_quaestor(where) } +// CARD: TRIBUTE + function can_play_tribute() { for (let where = 0; where < 12; ++where) if (has_active_barbarians(where)) @@ -1787,6 +1828,68 @@ states.tribute = { }, } +// CARD: FOEDERATI + +function can_foederati_from_region(where) { + let tribe_count = get_tribe_count() + for (let tribe = 0; tribe < tribe_count; ++tribe) { + if (find_barbarian_of_tribe(where, tribe) >= 0) + return true + } + return false +} + +function gen_foederati(where) { + 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) + } +} + +function can_foederati_from_region_and_adjacent(from) { + if (can_foederati_from_region(from)) + return true + for (let to of ADJACENT[from]) + if (can_foederati_from_region(to)) + return true + return false +} + +function can_play_foederati() { + 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 + return false +} + +function play_foederati() { + game.state = "foederati" +} + +states.foederati = { + prompt() { + prompt("Foederati: Recruit a Barbarian.") + view.selected_general = game.selected_general + let from = get_general_location(game.selected_general) + gen_foederati(from) + for (let to of ADJACENT[from]) + gen_foederati(to) + }, + 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) + game.state = "take_actions" + }, +} + // === COMBAT === function goto_battle_vs_general(where, attacker, target) { @@ -1814,7 +1917,7 @@ function goto_battle(type, where, attacker, target) { game.misc = { type, where, attacker, target } game.state = "battle" if (attacker >= 0) { - remove_general_castra(who) + remove_general_castra(attacker) set_general_battled(attacker) } else { set_militia_battled(where) @@ -1827,10 +1930,17 @@ function gen_initiate_battle(where) { if (loc === where && is_enemy_general(id)) gen_action_general(id) }) - for_each_barbarian((id, loc) => { - if (loc === where) + 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) - }) + else if (is_province(where)) { + id = find_inactive_barbarian_of_tribe(where, tribe) + if (id >= 0) + gen_action_barbarian(id) + } + } if (is_enemy_province(where)) { if (has_lone_militia(where)) gen_action_militia(where) @@ -2453,6 +2563,7 @@ exports.view = function (state, player_name) { militia: game.militia, quaestor: game.quaestor, castra: game.castra, + mcastra: game.mcastra, amphitheater: game.amphitheater, basilica: game.basilica, limes: game.limes, -- cgit v1.2.3