diff options
Diffstat (limited to 'play.js')
-rw-r--r-- | play.js | 750 |
1 files changed, 451 insertions, 299 deletions
@@ -1,5 +1,93 @@ "use strict" +// === SYNC with rules.js === + +const TRIBE_COUNT = [ 0, 5, 3, 4, 5 ] + +const ITALIA = 0 +const ASIA = 1 +const GALLIA = 2 +const MACEDONIA = 3 +const PANNONIA = 4 +const THRACIA = 5 + +const AEGYPTUS = 6 +const AFRICA = 7 +const HISPANIA = 8 + +const BRITANNIA = 9 +const GALATIA = 10 +const SYRIA = 11 + +const ALAMANNI_HOMELAND = 12 +const FRANKS_HOMELAND = 13 +const GOTHS_HOMELAND = 14 +const NOMADS_HOMELAND = 15 +const SASSANIDS_HOMELAND = 16 + +const MARE_OCCIDENTALE = 17 +const MARE_ORIENTALE = 18 +const OCEANUS_ATLANTICUS = 19 +const PONTUS_EUXINUS = 20 + +const AVAILABLE = 21 +const UNAVAILABLE = 22 + +const ARMY = 23 + +const first_barbarian = [ 0, 10, 20, 30, 40 ] +const first_governor = [ 0, 6, 12, 18 ] +const first_general = [ 0, 6, 12, 18 ] + +const REGION_NAME = [ + "Italia", + "Asia", + "Gallia", + "Macedonia", + "Pannonia", + "Thracia", + "Aegyptus", + "Africa", + "Hispania", + "Britannia", + "Galatia", + "Syria", + "Alamanni Homeland", + "Franks Homeland", + "Goths Homeland", + "Nomads Homeland", + "Sassanids Homeland", + "Mare Occidentale", + "Mare Orientale", + "Oceanus Atlanticus", + "Pontus Euxinus", + "Available", + "Unavailable", +] + +function is_no_place_governor(province) { return province >= view.support.length } +function get_support(province) { return view.support[province] } +function get_barbarian_location(id) { return view.barbarians[id] & 63 } +function is_barbarian_inactive(id) { return view.barbarians[id] & 64 } +function get_legion_location(ix) { return view.legions[ix] & 63 } +function is_legion_reduced(ix) { return view.legions[ix] & 64 } +function is_legion_unused(ix) { return view.legions[ix] === AVAILABLE } +function get_governor_location(id, loc) { return view.governors[id] & 63 } +function get_general_location(id) { return view.generals[id] & 63 } +function is_general_inside_capital(id) { return view.generals[id] & 64 } +function has_general_castra(id) { return view.castra & (1 << id) } +function has_militia_castra(province) { return view.mcastra & (1 << province) } +function has_quaestor(province) { return view.quaestor & (1 << province) } +function has_militia(province) { return view.militia & (1 << province) } +function get_mobs(province) { return view.mobs[province] } +function has_amphitheater(province) { return view.amphitheater & (1 << province) } +function has_basilica(province) { return view.basilica & (1 << province) } +function has_limes(province) { return view.limes & (1 << province) } +function is_breakaway(province) { return view.breakaway & (1 << province) } +function is_seat_of_power(province) { return view.seat_of_power & (1 << province) } + +// === END SYNC === + function set_has(set, item) { let a = 0 let b = set.length - 1 @@ -16,83 +104,95 @@ function set_has(set, item) { return false } -const REGION_LAYOUT = [ - [1038,743,70,70], - [1793,1380,70,70], - [741,1204,70,70], - [1790,908,70,70], - [325,177,70,70], - [2048,842,70,70], - [554,418,70,70], - [249,892,70,70], - [1477,850,70,70], - [1214,536,70,70], - [2174,1193,70,70], - [1594,631,70,70], - [1370,200,195,15], - [900,200,135,15], - [1840,235,130,15], - [705,1495,165,25], - [2295,980,190,25], - [720,890,90,60], - [1770,1170,100,60], - [130,495,80,50], - [1970,620,130,60], -] +const PLAYER_CLASS = [ "red", "blue", "yellow", "green" ] + +const BOXES = { + "Thracia Support": [1502,720,258,52], + "Syria Support": [2034,1280,258,52], + "Pannonia Support": [1154,626,258,53], + "Macedonia Support": [1384,936,258,53], + "Hispania Support": [154,980,258,53], + "Gallia Support": [460,507,258,53], + "Galatia Support": [1954,931,258,53], + "Britannia Support": [231,260,258,52], + "Asia Support": [1679,1000,258,52], + "Africa Support": [647,1290,258,53], + "Aegyptus Support": [1700,1468,258,53], + "Italia Support 2": [1054,887,258,52], + "Italia Support 1": [1028,835,258,52], + "Thracia Capital": [1594,631,70,70], + "Syria Capital": [2174,1193,70,70], + "Pannonia Capital": [1214,536,70,70], + "Macedonia Capital": [1477,850,70,70], + "Italia Capital": [1038,743,70,70], + "Hispania Capital": [249,892,70,70], + "Gallia Capital": [554,418,70,70], + "Galatia Capital": [2048,842,70,70], + "Britannia Capital": [325,177,70,70], + "Asia Capital": [1790,908,70,70], + "Africa Capital": [741,1204,70,70], + "Aegyptus Capital": [1793,1380,70,70], + "Pontus Euxinus XY": [1970,620,130,60], + "Mare Orientale XY": [1770,1170,100,60], + "Mare Occidentale XY": [720,890,90,60], + "Oceanus Atlanticus XY": [130,495,80,50], + "Nomads XY": [705,1495,165,25], + "Sassanids XY": [2295,980,190,25], + "Goths XY": [1840,235,130,15], + "Alamanni XY": [1370,200,195,15], + "Franks XY": [900,200,135,15], + "SCORE TRACK": [40,40,2469,80], + "CRISIS TABLE": [2195,189,262,326], +} -const REGION_LAYOUT2 = [ - [1054,887,258,52], - [1700,1468,258,53], - [647,1290,258,53], - [1679,1000,258,52], - [231,260,258,52], - [1954,931,258,53], - [460,507,258,53], - [154,980,258,53], - [1384,936,258,53], - [1154,626,258,53], - [2034,1280,258,52], - [1502,720,258,52], +const LAYOUT_XY = [ + BOXES["Italia Capital"], + BOXES["Asia Capital"], + BOXES["Gallia Capital"], + BOXES["Macedonia Capital"], + BOXES["Pannonia Capital"], + BOXES["Thracia Capital"], + BOXES["Aegyptus Capital"], + BOXES["Africa Capital"], + BOXES["Hispania Capital"], + BOXES["Britannia Capital"], + BOXES["Galatia Capital"], + BOXES["Syria Capital"], + BOXES["Alamanni XY"], + BOXES["Franks XY"], + BOXES["Goths XY"], + BOXES["Nomads XY"], + BOXES["Sassanids XY"], + BOXES["Mare Occidentale XY"], + BOXES["Mare Orientale XY"], + BOXES["Oceanus Atlanticus XY"], + BOXES["Pontus Euxinus XY"], ] -const REGION_NAME = [ - "Italia", - "Aegyptus", - "Africa", - "Asia", - "Britannia", - "Galatia", - "Gallia", - "Hispania", - "Macedonia", - "Pannonia", - "Syria", - "Thracia", - "Alamanni", - "Franks", - "Goths", - "Nomads", - "Sassanids", - "Mare Occidentale", - "Mare Orientale", - "Oceanus Atlanticus", - "Pontus Euxinus", +const LAYOUT_SUPPORT = [ + BOXES["Italia Support 1"], + BOXES["Asia Support"], + BOXES["Gallia Support"], + BOXES["Macedonia Support"], + BOXES["Pannonia Support"], + BOXES["Thracia Support"], + BOXES["Aegyptus Support"], + BOXES["Africa Support"], + BOXES["Hispania Support"], + BOXES["Britannia Support"], + BOXES["Galatia Support"], + BOXES["Syria Support"], ] let ui = { cards: [], - barbarians: [], - legions: [], militia: [], - barbarian_leaders: [], - rival_emperors: [], body: document.querySelector("body"), header: document.querySelector("header"), - available_generals: document.getElementById("available_generals"), - available_governors: document.getElementById("available_governors"), hand: document.getElementById("hand"), draw: document.getElementById("draw"), discard: document.getElementById("discard"), + played: document.getElementById("played"), market: document.getElementById("market"), pieces: document.getElementById("pieces"), legacy: [ @@ -109,29 +209,32 @@ let ui = { ], regions: [ document.getElementById("mapsvg").getElementById("region_italia"), - document.getElementById("mapsvg").getElementById("region_aegyptus"), - document.getElementById("mapsvg").getElementById("region_africa"), document.getElementById("mapsvg").getElementById("region_asia"), - document.getElementById("mapsvg").getElementById("region_britannia"), - document.getElementById("mapsvg").getElementById("region_galatia"), document.getElementById("mapsvg").getElementById("region_gallia"), - document.getElementById("mapsvg").getElementById("region_hispania"), document.getElementById("mapsvg").getElementById("region_macedonia"), document.getElementById("mapsvg").getElementById("region_pannonia"), - document.getElementById("mapsvg").getElementById("region_syria"), document.getElementById("mapsvg").getElementById("region_thracia"), + + document.getElementById("mapsvg").getElementById("region_aegyptus"), + document.getElementById("mapsvg").getElementById("region_africa"), + document.getElementById("mapsvg").getElementById("region_hispania"), + + document.getElementById("mapsvg").getElementById("region_britannia"), + document.getElementById("mapsvg").getElementById("region_galatia"), + document.getElementById("mapsvg").getElementById("region_syria"), + document.getElementById("mapsvg").getElementById("region_alamanni"), document.getElementById("mapsvg").getElementById("region_franks"), document.getElementById("mapsvg").getElementById("region_goths"), document.getElementById("mapsvg").getElementById("region_nomads"), document.getElementById("mapsvg").getElementById("region_sassanids"), + document.getElementById("mapsvg").getElementById("region_mare_occidentale"), document.getElementById("mapsvg").getElementById("region_mare_orientale"), document.getElementById("mapsvg").getElementById("region_oceanus_atlanticus"), document.getElementById("mapsvg").getElementById("region_pontus_euxinus"), ], capital: [], - province_governor: [], quaestor: [], amphitheater: [], basilica: [], @@ -142,75 +245,30 @@ let ui = { document.getElementById("barbarian_die_1"), document.getElementById("barbarian_die_2"), ], - generals: [ - [ - document.getElementById("red_general_0"), - document.getElementById("red_general_1"), - document.getElementById("red_general_2"), - document.getElementById("red_general_3"), - document.getElementById("red_general_4"), - document.getElementById("red_general_5"), - ], - [ - document.getElementById("blue_general_0"), - document.getElementById("blue_general_1"), - document.getElementById("blue_general_2"), - document.getElementById("blue_general_3"), - document.getElementById("blue_general_4"), - document.getElementById("blue_general_5"), - ], - [ - document.getElementById("yellow_general_0"), - document.getElementById("yellow_general_1"), - document.getElementById("yellow_general_2"), - document.getElementById("yellow_general_3"), - document.getElementById("yellow_general_4"), - document.getElementById("yellow_general_5"), - ], - [ - document.getElementById("green_general_0"), - document.getElementById("green_general_1"), - document.getElementById("green_general_2"), - document.getElementById("green_general_3"), - document.getElementById("green_general_4"), - document.getElementById("green_general_5"), - ], - ], - governors: [ - [ - document.getElementById("red_governor_0"), - document.getElementById("red_governor_1"), - document.getElementById("red_governor_2"), - document.getElementById("red_governor_3"), - document.getElementById("red_governor_4"), - document.getElementById("red_governor_5"), - ], - [ - document.getElementById("blue_governor_0"), - document.getElementById("blue_governor_1"), - document.getElementById("blue_governor_2"), - document.getElementById("blue_governor_3"), - document.getElementById("blue_governor_4"), - document.getElementById("blue_governor_5"), - ], - [ - document.getElementById("yellow_governor_0"), - document.getElementById("yellow_governor_1"), - document.getElementById("yellow_governor_2"), - document.getElementById("yellow_governor_3"), - document.getElementById("yellow_governor_4"), - document.getElementById("yellow_governor_5"), - ], - [ - document.getElementById("green_governor_0"), - document.getElementById("green_governor_1"), - document.getElementById("green_governor_2"), - document.getElementById("green_governor_3"), - document.getElementById("green_governor_4"), - document.getElementById("green_governor_5"), - ], - ], + neutral_governors: [], + barbarian_leaders: [], + rival_emperors: [], + legions: [], + barbarians: [ [], [], [], [], [] ], + generals: [ [], [], [], [] ], + governors: [ [], [], [], [] ], castra: [ [], [], [], [] ], + mcastra: [], +} + +function get_province_governor_player(where) { + let np = view.legacy.length + for (let p = 0; p < np; ++p) + for (let i = 0; i < 6; ++i) + if (get_governor_location(first_governor[p] + i) === where) + return p + return -1 +} + +function is_neutral_province(where) { + if (is_no_place_governor(where)) + return false + return get_province_governor_player(where) < 0 } function show(elt) { @@ -234,30 +292,36 @@ function create(t, p, ...c) { return e } -function create_piece(p) { +function create_thing(p) { let e = create("div", p) ui.pieces.appendChild(e) return e } +function create_piece(id, action, css_class, dom_id) { + if (dom_id) + return create_thing({ className: css_class + " hide", id: dom_id, my_action: action, my_id: id }) + return create_thing({ className: css_class + " hide", my_action: action, my_id: id }) +} + let action_register = [] -function register_action(e, action, id) { - e.my_action = action - e.my_id = id - e.onmousedown = on_click_action - action_register.push(e) +function register_action(target, action, id) { + target.my_action = action + target.my_id = id + target.onmousedown = (evt) => on_click_action(evt, target) + action_register.push(target) } -function on_click_action(evt) { +function on_click_action(evt, target) { if (evt.button === 0) { - if (evt.target.my_stack) { + if (target.my_stack) { evt.stopPropagation() - if (focus_stack(evt.target.my_stack)) - if (!send_action(evt.target.my_action, evt.target.my_id)) + if (focus_stack(target.my_stack)) + if (!send_action(target.my_action, target.my_id)) blur_stack() } else { - if (send_action(evt.target.my_action, evt.target.my_id)) + if (send_action(target.my_action, target.my_id)) evt.stopPropagation() } } @@ -269,8 +333,8 @@ document.getElementById("map").addEventListener("mousedown", function (evt) { }) function create_building(region, className, xoff, yoff) { - let [ x, y, w, h ] = REGION_LAYOUT2[region] - let e = create_piece({ className }) + let [ x, y, w, h ] = LAYOUT_SUPPORT[region] + let e = create_thing({ className }) e.style.left = x + (w>>1) + xoff - 46 + "px" e.style.top = y + h + yoff + "px" return e @@ -290,11 +354,6 @@ function on_init() { c += n } - function init_barbarians(b, n, className) { - for (let i = 0; i < n; ++i) - ui.barbarians[b + i] = create_piece({ className, my_action: "barbarian", my_id: b + i }) - } - init_cards(12, "card influence_m1") init_cards(12, "card influence_s1") init_cards(12, "card influence_p1") @@ -308,20 +367,38 @@ function on_init() { init_cards(6, "card influence_s4") init_cards(6, "card influence_p4") - init_barbarians(0, 10, "alamanni hide") - init_barbarians(10, 10, "franks hide") - init_barbarians(20, 10, "goths hide") - init_barbarians(30, 10, "nomads hide") - init_barbarians(40, 10, "sassanids hide") - for (let i = 0; i < 33; ++i) - ui.legions[i] = create_piece({ className: "legion hide", id: "legion_" + i, my_action: "legion", my_id: i }) + ui.legions[i] = create_piece(i, "legion", "legion", "legion_" + i) + + ui.barbarian_leaders[0] = create_piece(0, "barbarian_leader", "goths", "cniva") + ui.barbarian_leaders[1] = create_piece(1, "barbarian_leader", "sassanids", "ardashir") + ui.barbarian_leaders[2] = create_piece(2, "barbarian_leader", "sassanids", "shapur") + + ui.rival_emperors[0] = create_piece(0, "rival_emperor", "rival_emperor", "postumus") + ui.rival_emperors[1] = create_piece(1, "rival_emperor", "rival_emperor", "priest_king") + ui.rival_emperors[2] = create_piece(2, "rival_emperor", "rival_emperor", "zenobia") + + for (let i = 0; i < 10; ++i) { + ui.barbarians[0][i] = create_piece(0 + i, "barbarian", "alamanni") + ui.barbarians[1][i] = create_piece(10 + i, "barbarian", "franks") + ui.barbarians[2][i] = create_piece(20 + i, "barbarian", "goths") + ui.barbarians[3][i] = create_piece(30 + i, "barbarian", "nomads") + ui.barbarians[4][i] = create_piece(40 + i, "barbarian", "sassanids") + } + + for (let p = 0; p < 4; ++p) { + for (let g = 0; g < 6; ++g) { + ui.castra[p][g] = create_thing({ className: "castra hide" }) + ui.governors[p][g] = create_piece(p * 6 + g, "governor", PLAYER_CLASS[p] + " governor n" + g) + ui.generals[p][g] = create_piece(p * 6 + g, "general", PLAYER_CLASS[p] + " general n" + g) + } + } for (let region = 0; region < 12; ++region) { - ui.militia[region] = create_piece({ className: "militia hide", my_action: "militia", my_id: region }) + ui.mcastra[region] = create_thing({ className: "castra hide" }) + ui.militia[region] = create_thing({ className: "militia hide", my_action: "militia", my_id: region }) ui.capital[region] = document.getElementById(REGION_NAME[region] + "_Capital") ui.quaestor[region] = document.getElementById(REGION_NAME[region] + "_Quaestor") - ui.province_governor[region] = document.getElementById(REGION_NAME[region] + "_Governor") if (true) { ui.amphitheater[region] = create_building(region, "amphitheater hide", -48 - 3, 6) @@ -332,28 +409,15 @@ function on_init() { ui.basilica[region] = create_building(region, "basilica hide", 0, 6) ui.limes[region] = create_building(region, "limes hide", 96 + 5, 6) } - } - for (let region = 0; region < 12; ++region) register_action(ui.capital[region], "capital", region) - for (let region = 0; region < 12 + 5 + 4; ++region) register_action(ui.regions[region], "region", region) - - for (let pi = 0; pi < 4; ++pi) { - for (let ai = 0; ai < 6; ++ai) { - ui.castra[pi][ai] = create_piece({ className: "castra hide" }) - register_action(ui.generals[pi][ai], "general", 100 + 100 * pi + ai) - register_action(ui.governors[pi][ai], "governor", 100 + 100 * pi + ai) - } + + ui.neutral_governors[region] = create_thing({ className: "neutral governor hide" }) + } + for (let region = 12; region < 21; ++region) { + register_action(ui.regions[region], "region", region) } - - ui.barbarian_leaders[0] = create_piece({ id: "cniva", className: "goths hide", my_action: "barbarian_leader", my_id: 0 }) - ui.barbarian_leaders[1] = create_piece({ id: "ardashir", className: "goths hide", my_action: "barbarian_leader", my_id: 1 }) - ui.barbarian_leaders[2] = create_piece({ id: "shapur", className: "goths hide", my_action: "barbarian_leader", my_id: 2 }) - - ui.rival_emperors[0] = create_piece({ id: "postumus", className: "rival hide", my_action: "rival_emperor", my_id: 0 }) - ui.rival_emperors[1] = create_piece({ id: "priest_king", className: "rival hide", my_action: "rival_emperor", my_id: 1 }) - ui.rival_emperors[2] = create_piece({ id: "zenobia", className: "rival hide", my_action: "rival_emperor", my_id: 2 }) } let stack_count = new Array(12 + 5).fill(0) @@ -378,7 +442,7 @@ function blur_stack() { } function layout_stack(id, list, region, in_capital) { - let [ x, y, w, h ] = REGION_LAYOUT[region] + let [ x, y, w, h ] = LAYOUT_XY[region] let dx = 8 let dy = 8 let z = 1 @@ -414,25 +478,53 @@ function layout_stack(id, list, region, in_capital) { } } +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" + item.style.top = y + "px" + item.style.zIndex = 1 + item.my_stack = 0 + x += dx + } +} + +function layout_governor(e, color, region) { + e.className = color + " governor s" + get_support(region) + e.style.left = (LAYOUT_SUPPORT[region][0] - 1) + "px" + e.style.top = (LAYOUT_SUPPORT[region][1] - 1) + "px" +} + +function layout_governor_available(e, color) { + e.className = color + " governor" +} + +function layout_governor_unavailable(e, color, ix) { + e.className = color + " governor n" + ix +} + function on_update() { + let player_count = view.legacy.length + stack_cache = {} ui.body.classList.toggle("p1", view.solo === 1) - ui.body.classList.toggle("p2", view.players.length === 2) - ui.body.classList.toggle("p3", view.players.length === 3) - ui.body.classList.toggle("p4", view.players.length === 4) + ui.body.classList.toggle("p2", player_count === 2) + ui.body.classList.toggle("p3", player_count === 3) + ui.body.classList.toggle("p4", player_count === 4) ui.header.classList.toggle("player_red", view.current === 0) ui.header.classList.toggle("player_blue", view.current === 1) ui.header.classList.toggle("player_yellow", view.current === 2) ui.header.classList.toggle("player_green", view.current === 3) - if (view.players.length < 4) + if (player_count < 4) hide(document.getElementById("role_Green")) else show(document.getElementById("role_Green")) - if (view.players.length < 3) + if (player_count < 3) hide(document.getElementById("role_Yellow")) else show(document.getElementById("role_Yellow")) @@ -442,131 +534,120 @@ function on_update() { ui.discard.replaceChildren() ui.market.replaceChildren() - for (let i = 0; i < view.players.length; ++i) { - let legacy = view.players[i].legacy - let turns = view.players[i].emperor_turns + for (let pi = 0; pi < player_count; ++pi) { + let legacy = view.legacy[pi] + let turns = view.emperor_turns[pi] if (legacy > 40) { legacy -= 40 - ui.legacy[i].classList.toggle("legacy_40", true) + ui.legacy[pi].classList.toggle("legacy_40", true) } else { - ui.legacy[i].classList.toggle("legacy_40", false) + ui.legacy[pi].classList.toggle("legacy_40", false) } let y = 30 - for (let k = 0; k < i; ++k) { - let k_legacy = view.players[k].legacy + for (let k = 0; k < pi; ++k) { + let k_legacy = view.legacy[k] if (k_legacy > 40) k_legacy -= 40 if (legacy === k_legacy) y += 20 } - show(ui.legacy[i]) - ui.legacy[i].style.left = Math.round(43 + legacy * 60.2) + "px" - ui.legacy[i].style.top = (2 + y) + "px" + show(ui.legacy[pi]) + ui.legacy[pi].style.left = Math.round(43 + legacy * 60.2) + "px" + ui.legacy[pi].style.top = (2 + y) + "px" y = 30 - for (let k = 0; k < i; ++k) { - let k_turns = view.players[k].emperor_turns + for (let k = 0; k < pi; ++k) { + let k_turns = view.emperor_turns[k] if (turns === k_turns) y += 20 } - show(ui.emperor_turns[i]) - ui.emperor_turns[i].style.left = Math.round(41 + turns * 60.2) + "px" - ui.emperor_turns[i].style.top = (0 + y) + "px" + show(ui.emperor_turns[pi]) + ui.emperor_turns[pi].style.left = Math.round(41 + turns * 60.2) + "px" + ui.emperor_turns[pi].style.top = (0 + y) + "px" } - for (let pi = view.players.length; pi < 4; ++pi) { + for (let pi = player_count; pi < 4; ++pi) { hide(ui.legacy[pi]) hide(ui.emperor_turns[pi]) - for (let ai = 0; ai < 6; ++ai) { - ui.generals[pi][ai].remove() - ui.governors[pi][ai].remove() - } } for (let region = 0; region < 12; ++region) { - let who = -1 - for (let pi = 0; pi < view.players.length; ++pi) - for (let ai = 0; ai < 6; ++ai) - if (view.players[pi].governors[ai] === region) - who = pi - if (who < 0) - ui.province_governor[region].classList = "neutral governor s" + view.support[region] - else if (who === 0) - ui.province_governor[region].classList = "red governor s" + view.support[region] - else if (who === 1) - ui.province_governor[region].classList = "blue governor s" + view.support[region] - else if (who === 2) - ui.province_governor[region].classList = "yellow governor s" + view.support[region] - else if (who === 3) - ui.province_governor[region].classList = "green governor s" + view.support[region] - - if (view.quaestor & (1 << region)) + if (has_quaestor(region)) show(ui.quaestor[region]) else hide(ui.quaestor[region]) - if (view.amphitheater & (1 << region)) + if (has_amphitheater(region)) show(ui.amphitheater[region]) else hide(ui.amphitheater[region]) - if (view.basilica & (1 << region)) + if (has_basilica(region)) show(ui.basilica[region]) else hide(ui.basilica[region]) - if (view.limes & (1 << region)) + if (has_limes(region)) show(ui.limes[region]) else hide(ui.limes[region]) - if (view.militia & (1 << region)) + if (has_militia(region)) show(ui.militia[region]) else hide(ui.militia[region]) } for (let i = 0; i < 33; ++i) { - if (view.legions[i] >= 0) { + if (is_legion_unused(i)) + hide(ui.legions[i]) + else show(ui.legions[i]) - if (view.is_legion_reduced[i]) - ui.legions[i].classList.toggle("reduced", true) + if (is_legion_reduced(i)) + ui.legions[i].classList.toggle("reduced", true) + else + ui.legions[i].classList.toggle("reduced", false) + } + + // TODO: Cniva, Ardashir, and Shapur + // TODO: Zenobia, Postumus, Priest King + + let tribe_count = TRIBE_COUNT[player_count] + for (let tribe = 0; tribe < TRIBE_COUNT[player_count]; ++tribe) { + for (let i = 0; i < 10; ++i) { + show(ui.barbarians[tribe][i]) + if (is_barbarian_inactive(first_barbarian[tribe] + i)) + ui.barbarians[tribe][i].classList.toggle("inactive", true) else - ui.legions[i].classList.toggle("reduced", false) - } else { - hide(ui.legions[i]) + ui.barbarians[tribe][i].classList.toggle("inactive", false) } } - for (let i = 0; i < 50; ++i) { - if (view.barbarians[i] >= 0) { - show(ui.barbarians[i]) - if (view.is_barbarian_inactive[i]) - ui.barbarians[i].classList.toggle("inactive", true) - else - ui.barbarians[i].classList.toggle("inactive", false) - } else { - hide(ui.barbarians[i]) + for (let tribe = TRIBE_COUNT[player_count]; tribe < 5; ++tribe) { + for (let i = 0; i < 10; ++i) { + hide(ui.barbarians[tribe][i]) } } stack_count.fill(1) for (let region = 0; region < 12 + 5; ++region) { - for (let tribe = 0; tribe < 5; ++tribe) { + for (let tribe = 0; tribe < tribe_count; ++tribe) { let active_barbarians = [] let inactive_barbarians = [] - for (let i = tribe * 10; i < tribe * 10 + 10; ++i) { - // TODO: Cniva, Ardashir, and Shapur - if (view.barbarians[i] === region) { - if (view.is_barbarian_inactive[i]) - inactive_barbarians.push(ui.barbarians[i]) + // TODO: Cniva, Ardashir, and Shapur + for (let i = 0; i < 10; ++i) { + let loc = get_barbarian_location(first_barbarian[tribe], i) + let inactive = is_barbarian_inactive(first_barbarian[tribe], i) + if (loc === region) { + if (inactive) + inactive_barbarians.push(ui.barbarians[tribe][i]) else - active_barbarians.push(ui.barbarians[i]) + active_barbarians.push(ui.barbarians[tribe][i]) } } if (active_barbarians.length > 0) @@ -577,100 +658,145 @@ function on_update() { } for (let region = 0; region < 12; ++region) { - if (view.militia & (1 << region)) { + if (has_militia(region)) { let lone_militia = true - for (let pi = 0; pi < view.players.length; ++pi) { - for (let ai = 0; ai < 6; ++ai) { - if (view.players[pi].generals[ai] === region) - if (view.players[pi].capital & (1 << ai)) - lone_militia = false + for (let pi = 0; pi < player_count; ++pi) { + for (let i = 0; i < 6; ++i) { + let loc = get_general_location(first_general[pi] + i) + let inside = is_general_inside_capital(first_general[pi] + i) + if (loc === region && inside) + lone_militia = false + } + } + if (lone_militia) { + let mcastra = has_militia_castra(region) + if (mcastra) { + show(ui.mcastra[region]) + layout_stack(0, [ ui.militia[region], ui.mcastra[region] ], region, true) + } else { + hide(ui.mcastra[region]) + layout_stack(0, [ ui.militia[region] ], region, true) } } - if (lone_militia) - layout_stack(0, [ ui.militia[region] ], region, true) + } + + if (is_no_place_governor(region)) { + hide(ui.neutral_governors[region]) + } else { + if (is_neutral_province(region)) { + show(ui.neutral_governors[region]) + layout_governor(ui.neutral_governors[region], "neutral", region) + } else { + hide(ui.neutral_governors[region]) + } } } - for (let pi = 0; pi < view.players.length; ++pi) { - let p = view.players[pi] + for (let pi = 0; pi < player_count; ++pi) { + let avail_stack = [] for (let ai = 0; ai < 6; ++ai) { - let id = 100 + 100 * pi + ai - - let r = p.generals[ai] + let id = ARMY + first_general[pi] + ai + let region = get_general_location(first_general[pi] + ai) + let inside = is_general_inside_capital(first_general[pi] + ai) + let castra = has_general_castra(first_general[pi] + ai) let e = ui.generals[pi][ai] - if (r >= 0) { + show(e) + if (region < 21) { let stack = [] - if (e.parentNode !== ui.pieces) - ui.pieces.appendChild(e) - if ((view.militia & (1 << r)) && (p.capital & (1 << ai))) - stack.push(ui.militia[r]) + if (has_militia(region) && inside) + stack.push(ui.militia[region]) - for (let i = 0; i < 33; ++i) { - if (view.legions[i] === id) { - stack.push(ui.legions[i]) + for (let tribe = 0; tribe < tribe_count; ++tribe) { + for (let i = 0; i < 10; ++i) { + let loc = get_barbarian_location(first_barbarian[tribe] + i) + if (loc === id) + stack.push(ui.barbarians[tribe][i]) } } - for (let i = 0; i < 50; ++i) - if (view.barbarians[i] === id) - stack.push(ui.barbarians[i]) + for (let i = 0; i < 33; ++i) { + let loc = get_legion_location(i) + if (loc === id) + stack.push(ui.legions[i]) + } stack.push(e) - if (p.castra & (1 << ai)) { + if (castra) { show(ui.castra[pi][ai]) stack.push(ui.castra[pi][ai]) } else { hide(ui.castra[pi][ai]) } - if (p.capital & (1 << ai)) - layout_stack(id, stack, r, true) + if (inside) + layout_stack(id, stack, region, true) else - layout_stack(id, stack, r, false) + layout_stack(id, stack, region, false) } else { - if (e.parentNode !== ui.available_generals) - ui.available_generals.appendChild(e) + avail_stack.push(e) } + e.classList.toggle("unavailable", region === UNAVAILABLE) + } + layout_available(avail_stack, 63, pi * 625 + 0, 30) + } - if (p.governors[ai] < 0) - show(ui.governors[pi][ai]) - else - hide(ui.governors[pi][ai]) + for (let pi = 0; pi < player_count; ++pi) { + let avail_stack = [] + for (let ai = 0; ai < 6; ++ai) { + let id = 100 + 100 * pi + ai + let region = get_governor_location(first_governor[pi] + ai) + let e = ui.governors[pi][ai] + if (region >= 1 && region < 12) { + layout_governor(e, PLAYER_CLASS[pi], region) + } else { + if (region === AVAILABLE) + layout_governor_available(e, PLAYER_CLASS[pi]) + else + layout_governor_unavailable(e, PLAYER_CLASS[pi], ai) + avail_stack.push(e) + } + e.classList.toggle("unavailable", region === UNAVAILABLE) } + layout_available(avail_stack, 58, pi * 625 + 325, 27) } - if (view.dice[0] > 0) { - ui.dice[0].className = "dice black d" + view.dice[0] - ui.dice[1].className = "dice white d" + view.dice[1] - } else { - ui.dice[0].className = "dice hide" - ui.dice[1].className = "dice hide" + ui.dice[0].className = "dice black d" + view.dice[0] + ui.dice[1].className = "dice white d" + view.dice[1] + ui.dice[2].className = "dice black d" + view.dice[2] + ui.dice[3].className = "dice white d" + view.dice[3] + + if (view.events) { + for (let c of view.events) + ui.played.appendChild(ui.cards[c]) } - if (view.dice[2] > 0) { - ui.dice[2].className = "dice black d" + view.dice[0] - ui.dice[3].className = "dice white d" + view.dice[1] - } else { - ui.dice[2].className = "dice hide" - ui.dice[3].className = "dice hide" + + ui.played.replaceChildren() + if (view.played) { + for (let c of view.played) + ui.played.appendChild(ui.cards[c]) } + ui.hand.replaceChildren() if (view.hand) { for (let c of view.hand) ui.hand.appendChild(ui.cards[c]) } + ui.draw.replaceChildren() if (view.draw) { for (let c of view.draw) ui.draw.appendChild(ui.cards[c]) } + ui.discard.replaceChildren() if (view.discard) { for (let c of view.discard) ui.discard.appendChild(ui.cards[c]) } + ui.market.replaceChildren() for (let pile of view.market) { if (pile.length > 0) ui.market.appendChild(ui.cards[pile[0]]) @@ -679,6 +805,32 @@ function on_update() { for (let e of action_register) e.classList.toggle("action", is_action(e.my_action, e.my_id)) + action_button("enter", "Enter Capital") + action_button("leave", "Leave Capital") + + action_button("spend", "Spend") + action_button("roll", "Roll") + + action_button("militia", "Place Militia") + action_button("support", "Increase Support Level") + action_button("hold_games", "Hold Games") + action_button("build_improvement", "Build an Improvement") + + action_button("disperse_mob", "Disperse Mob") + action_button("train_legions", "Train Legions") + action_button("add_legion_to_army", "Add Legion to Army") + action_button("move_army", "Move Army") + action_button("initiate_battle", "Initiate Battle") + + action_button("amphitheater", "Amphitheater") + action_button("basilica", "Basilica") + action_button("limes", "Limes") + + action_button("recall", "Recall") + action_button("recruit", "Recruit") + action_button("place", "Place") + action_button("create_army", "Create Army") + action_button("end_actions", "End Actions") action_button("done", "Done") |