summaryrefslogtreecommitdiff
path: root/play.js
diff options
context:
space:
mode:
authorTor Andersson <tor@ccxvii.net>2023-05-27 19:28:16 +0200
committerTor Andersson <tor@ccxvii.net>2023-07-07 18:39:23 +0200
commit495090873cf62a1ca698cee18a2d292fc30aa292 (patch)
tree7b179325adf10a13ab3827ddafe320249a2d3e06 /play.js
parent069a9310cea47805d5b8d55d04961b9e5b3d9527 (diff)
downloadtime-of-crisis-495090873cf62a1ca698cee18a2d292fc30aa292.tar.gz
Stuff.
Diffstat (limited to 'play.js')
-rw-r--r--play.js750
1 files changed, 451 insertions, 299 deletions
diff --git a/play.js b/play.js
index 3559f92..6a08084 100644
--- a/play.js
+++ b/play.js
@@ -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")