diff options
-rw-r--r-- | const.js | 1 | ||||
-rw-r--r-- | play.css | 1 | ||||
-rw-r--r-- | play.html | 9 | ||||
-rw-r--r-- | play.js | 54 | ||||
-rw-r--r-- | rules.js | 79 |
5 files changed, 122 insertions, 22 deletions
@@ -26,6 +26,7 @@ const PIECE_FACTION_TYPE_NAME = [ [ "Temple", "Raja", null ], [ null, null, "Invader" ] ] +const LAST_CAVALRY = 9 // Sequence of Play options const ELIGIBLE = 0 @@ -204,6 +204,7 @@ path.tip { stroke: white; stroke-dasharray: 4 4; } .token.action { pointer-events: auto; + box-shadow: 0 0 0 3px white; } .token.tributary, .token.ds_ctl, .token.bk_ctl, .token.ve_ctl { border-radius: 50% } @@ -321,15 +321,6 @@ c-32 0 -38 0 -46 2 -11 2 -20 5 -23 6 -2 0 -5 2 -8 3 -4 1 -10 4 -14 6 -6 4 <div class="token" id="token_bk_influence" style="left:25px;top:1195px"></div> <div class="token" id="token_ve_influence" style="left:25px;top:1300px"></div> <div class="token" id="token_mongol_cavalry" style="left:89px;top:220px"></div> - <div class="token cavalry charge" id="cavalry_1" style="left:700px;top:100px"></div> - <div class="token cavalry screen" id="cavalry_2" style="left:700px;top:110px"></div> - <div class="token cavalry charge" id="cavalry_3" style="left:700px;top:120px"></div> - <div class="token cavalry screen" id="cavalry_4" style="left:700px;top:130px"></div> - <div class="token cavalry charge" id="cavalry_5" style="left:700px;top:140px"></div> - <div class="token cavalry screen" id="cavalry_6" style="left:700px;top:150px"></div> - <div class="token cavalry charge" id="cavalry_7" style="left:700px;top:160px"></div> - <div class="token cavalry screen" id="cavalry_8" style="left:700px;top:170px"></div> - </div> <div id="pieces"> @@ -6,6 +6,7 @@ const first_piece = data.first_piece const last_piece = data.last_piece +const last_cavalry = 9 // :r !python3 tools/genlayout.py const LAYOUT = { @@ -436,6 +437,7 @@ let ui = { status: document.getElementById("status"), spaces: [], control: [], + cavalry: [], card_tip: document.getElementById("card_tip"), this_card: document.getElementById("this_card"), shaded_event: document.getElementById("shaded_event"), @@ -451,14 +453,6 @@ let ui = { token_bk_influence: document.getElementById("token_bk_influence"), token_ve_influence: document.getElementById("token_ve_influence"), token_mongol_cavalry: document.getElementById("token_mongol_cavalry"), - cavalry_1: document.getElementById("cavalry_1"), - cavalry_2: document.getElementById("cavalry_2"), - cavalry_3: document.getElementById("cavalry_3"), - cavalry_4: document.getElementById("cavalry_4"), - cavalry_5: document.getElementById("cavalry_5"), - cavalry_6: document.getElementById("cavalry_6"), - cavalry_7: document.getElementById("cavalry_7"), - cavalry_8: document.getElementById("cavalry_8"), }, pieces: [], resources: [ @@ -523,6 +517,14 @@ function init_ui() { ui.unshaded_event.onmouseenter = on_focus_unshaded_event ui.unshaded_event.onmouseleave = on_focus_this_event + // player cavalry tokens + for (let i = 0; i <= LAST_CAVALRY; ++i) { + let e = null + ui.cavalry[i] = e = create("div", { className: "token cavalry charge" }) + document.getElementById("tokens").appendChild(e) + register_action(e, "token", i) + } + for (let s = 0; s < 26; ++s) { let e = null @@ -637,6 +639,12 @@ function get_layout_xy(s, f = "Center") { return LAYOUT_CACHE[f][s] } +function filter_calvary_tokens(list, faction) { + for (let i = 0; i <= last_cavalry; ++i) + if (view.cavalry[i] === faction) + list.push(ui.cavalry[i]) +} + function filter_piece_list(list, space, faction, type) { for (let i = first_piece[faction][type]; i <= last_piece[faction][type]; ++i) if (view.pieces[i] === space) @@ -727,6 +735,15 @@ function layout_available_bases(list, x0, y0, rows, dx, dy) { } } +function layout_cavalry(list, x0, y0, dy) { + let x = x0 + let y = y0 + let ll = list.length + for (let i = 0; i < ll; ++i) { + place_piece(list[ll-i-1], x, y + (dy * (ll-i)), ll-i) + } +} + let sop_xy = [ [876, 1445, 0, 13], // ELIGIBLE [876, 1307, 11, 0], // SOP_LIMITED_COMMAND @@ -856,6 +873,9 @@ function on_update() { ui.resources[BK].classList.toggle("action", is_action("resources", BK)) ui.resources[VE].classList.toggle("action", is_action("resources", VE)) + for (let i = 0; i <= LAST_CAVALRY; ++i) + ui.cavalry[i].classList.toggle("action", is_action("token", i)) + update_player_active(NAME_DS, view.current === DS) update_player_active(NAME_VE, view.current === VE) update_player_active(NAME_BK, view.current === BK) @@ -939,6 +959,24 @@ function on_update() { } } + // layout cavalry + items.length = 0 + filter_calvary_tokens(items, DS) + layout_cavalry(items, 1125, 120, 14) + + items.length = 0 + filter_calvary_tokens(items, BK) + layout_cavalry(items, 200, 935, 14) + + items.length = 0 + filter_calvary_tokens(items, VE) + layout_cavalry(items, 200, 1435, 14) + + items.length = 0 + filter_calvary_tokens(items, AVAILABLE) + layout_cavalry(items, 725, 90, 14) + + // layout pieces items.length = 0 filter_piece_list(items, AVAILABLE, DS, DISC) layout_available_bases(items, 1050, 250, 1, 45, 0) @@ -98,6 +98,7 @@ exports.view = function (state, role) { bk_inf: 0, ve_inf: 0, deck: [ this_card, deck_size, game.of_gods_and_kings ], + cavalry: game.cavalry, cylinder: game.cylinder, pieces: game.pieces, tributary: game.tributary, @@ -194,7 +195,7 @@ exports.setup = function (seed, scenario, _options) { control: [0, 0, 0], rebel: [null, 0, 0], // amir/raja rebel status pieces: Array(104).fill(AVAILABLE), // piece locations - cavalry: [0, 0, 0], + cavalry: Array(10).fill(AVAILABLE), deck: [], cmd: { type: null, @@ -261,6 +262,10 @@ function setup_standard() { setup_piece(VE, ELITE, 2, S_VE_INF_2) setup_piece(VE, ELITE, 2, S_VE_INF_3) setup_piece(VE, ELITE, 2, S_VE_INF_4) + + // Two cavalry to DS + set_cavalry_faction(0, DS) + set_cavalry_faction(1, DS) } function setup_piece(faction, type, count, where) { @@ -373,6 +378,11 @@ function goto_build() { game.state = "build" } +function goto_cavalry(n_cavalry) { + game.cmd.n_count = n_cavalry + game.state = "cavalry" +} + function goto_collect() { init_command("Collect") game.state = "collect" @@ -606,10 +616,24 @@ states.build = { } } +states.cavalry = { + prompt() { + view.prompt = `Gain Cavalry: Take ${game.cmd.n_count} calvary tokens` + + gen_take_cavalry(game.current) + }, + token(c) { + game.cmd.n_count -= 1 + set_cavalry_faction(c, game.current) + if (!game.cmd.n_count) + game.state = "command_decree" + + } +} + states.collect = { - // TODO : Add horses logic to trade prompt() { - view.prompt = `Collect tribute: Collect ${collect_count()} from half the Tributaries prosperity` + view.prompt = `Collect Tribute: Collect ${collect_count()} from half the Tributaries prosperity` gen_action_resources(DS) }, @@ -618,7 +642,7 @@ states.collect = { add_resources(DS, c) logi_resources(DS, c) game.decree = 0 - game.state = "command_decree" + goto_cavalry(2) } } @@ -897,7 +921,7 @@ states.trade = { add_resources(game.current, t) logi_resources(BK, t) game.decree = 0 - game.state = "command_decree" + goto_cavalry(trade_cavalry_count()) } } @@ -918,9 +942,12 @@ function gen_any_command() { view.actions.conscript = can_conscript() ? 1 : 0 view.actions.govern = can_govern() ? 1 : 0 view.actions.march = can_march() ? 1 : 0 + // view.actions.attack = can_attack() ? 1 : 0 } else if (game.current === BK || game.current === VE) { view.actions.rally = can_rally() ? 1 : 0 + // view.actions.migrate = can_migrate() ? 1 : 0 view.actions.rebel = can_rebel() ? 1 : 0 + // view.actions.attack = can_attack() ? 1 : 0 } } @@ -1317,6 +1344,43 @@ function piece_type(p) { throw "IMPOSSIBLE" } +/* CAVALRY */ + +function available_cavalry() { + let n = 0 + for (let c = 0; c <= LAST_CAVALRY; ++c) + if (game.cavalry[c] === AVAILABLE) + n += 1 + return n +} + +function gen_take_cavalry(faction) { + let can_place = false + for (let c = 0; c <= LAST_CAVALRY; ++c) { + if (game.cavalry[c] === AVAILABLE) { + gen_action_token(c) + can_place = true + } + } + if (!can_place && faction === game.current) { + for (let c = 0; c <= LAST_CAVALRY; ++c) { + if (game.cavalry[c] !== faction) + gen_action_token(c) + } + } + return can_place +} + +function set_cavalry_faction(c, f) { + game.cavalry[c] = f +} + +function trade_cavalry_count() { + if (game.bk_inf === 0) return 1; + if (game.bk_inf <= 2) return 2; + return 3; +} + /* UTILS */ function add_resources(faction, n) { @@ -1367,6 +1431,10 @@ function gen_action_space(s) { gen_action("space", s) } +function gen_action_token(t) { + gen_action("token", t) +} + /* LOGGING */ function log(msg) { @@ -1867,6 +1935,7 @@ const PIECE_FACTION_TYPE_NAME = [ [ "Temple", "Raja", null ], [ null, null, "Invader" ] ] +const LAST_CAVALRY = 9 // Sequence of Play options const ELIGIBLE = 0 |