"use strict"
const wing_name = [ "red", "pink", "blue", "dkblue" ]
const reactions = [ "Screen", "Counterattack", "Absorb" ]
let ui = {
main: document.querySelector("main"),
role_row: [ document.getElementById("role_First"), document.getElementById("role_Second") ],
role_name: [ document.getElementById("role1"), document.getElementById("role2") ],
name: [ document.getElementById("name1"), document.getElementById("name2") ],
front: [ document.getElementById("front1"), document.getElementById("front2") ],
morale: [ document.getElementById("morale1"), document.getElementById("morale2") ],
pool: [ document.getElementById("pool1"), document.getElementById("pool2") ],
reserve: [ document.getElementById("reserve1"), document.getElementById("reserve2") ],
cards: {},
slots: {},
slot_sticks: {},
slot_cubes: {},
slot_dice: {},
dice: [],
sticks: [],
cubes: [],
}
let action_register = []
function register_action(e, action, id, fizzle=null) {
e.my_id = id
e.my_action = action
e.my_fizzle = fizzle
e.onclick = on_click_action
action_register.push(e)
return e
}
function on_click_action(evt) {
if (evt.button === 0) {
if (send_action(evt.target.my_action, evt.target.my_id))
evt.stopPropagation()
if (evt.target.my_fizzle)
if (send_action(evt.target.my_fizzle, evt.target.my_id))
evt.stopPropagation()
}
}
function is_action(action, arg) {
if (arg === undefined)
return !!(view.actions && view.actions[action] === 1)
return !!(view.actions && view.actions[action] && view.actions[action].includes(arg))
}
function create_div(className, text) {
let e = document.createElement("div")
e.className = className
if (text)
e.innerHTML = text
return e
}
function append_div(parent, className, text) {
let e = create_div(className, text)
parent.appendChild(e)
return e
}
function create_formation_slot(id, top) {
let card = data.cards[id]
let e = create_div("slot " + wing_name[card.wing])
if (top) {
ui.slot_dice[id] = append_div(e, "slot_dice")
e.appendChild(ui.cards[id])
}
if (card.special)
ui.slot_cubes[id] = append_div(e, "slot_cubes")
else
ui.slot_sticks[id] = append_div(e, "slot_sticks")
if (!top) {
e.appendChild(ui.cards[id])
ui.slot_dice[id] = append_div(e, "slot_dice")
}
return e
}
function create_formation_card(id) {
let card = data.cards[id]
let e = create_div("card formation " + wing_name[card.wing])
let e_a1 = null
let e_a2 = null
register_action(e, "card", id)
append_div(e, "name " + wing_name[card.wing], card.name)
if (card.special === 1)
append_div(e, "strength", "I")
else if (card.special === 2)
append_div(e, "strength", "II")
else if (card.special === 3)
append_div(e, "strength", "III")
else
append_div(e, "strength", card.strength)
if (card.dice) {
if (card.star)
append_div(e, "dice_area", card.dice + '
★
')
else
append_div(e, "dice_area", card.dice)
}
function create_action(a, ix) {
let ee = append_div(e, "action_row")
let et
if (reactions.includes(a.type))
et = append_div(ee, "action_type reaction", a.type)
else
et = append_div(ee, "action_type", a.type)
register_action(et, "a" + ix, id, "f" + ix)
append_div(ee, "action_requirement", a.requirement)
if (Array.isArray(a.target))
append_div(ee, "action_target", a.target.map(t=>data.cards[t].name).join(", "))
else
append_div(ee, "action_target", a.target)
if (a.effect)
append_div(ee, "action_effect", a.effect)
return et
}
if (card.actions.length >= 1)
e_a1 = create_action(card.actions[0], 1)
if (card.actions.length >= 2)
e_a2 = create_action(card.actions[1], 2)
if (card.rule_text)
append_div(e, "rule_text", card.rule_text)
if (card.lore_text)
append_div(e, "lore_text", card.lore_text)
if (card.retire) {
let ee = append_div(e, "retire", "RETIRE")
register_action(ee, "retire", id)
} else if (card.pursuit) {
append_div(e, "reserve", "PURSUIT")
} else if (card.reserve) {
if (card.reserve.length === 0)
append_div(e, "reserve", "IN RESERVE (Commanded)")
else
append_div(e, "reserve", "IN RESERVE (" + card.reserve.map(c => data.cards[c].name).join(" or ") + ")")
}
append_div(e, "number", card.number)
return e
}
function fill_card_row(top, parent, list) {
parent.replaceChildren()
for (let id of list) {
let i, n
if (!ui.cards[id])
ui.cards[id] = create_formation_card(id)
if (!ui.slots[id])
ui.slots[id] = create_formation_slot(id, top)
parent.append(ui.slots[id])
ui.cards[id].classList.toggle("selected", view.selected === id)
n = map_get(view.cubes, id, 0)
for (let i = 0; i < n; ++i)
add_cube(ui.slot_cubes[id])
n = map_get(view.sticks, id, 0)
for (let i = 0; i < n; ++i)
add_stick(ui.slot_sticks[id])
}
}
function add_cube(parent) {
for (let i = 0; i < 10; ++i) {
if (ui.cubes[i].parentElement === null) {
parent.appendChild(ui.cubes[i])
return
}
}
throw Error("OUT OF CUBES ERROR")
}
function add_stick(parent) {
for (let i = 0; i < 80; ++i) {
if (ui.sticks[i].parentElement === null) {
parent.appendChild(ui.sticks[i])
return
}
}
throw Error("OUT OF CUBES ERROR")
}
function on_update() {
let p1 = 0, p2 = 1
if (player === "First")
p1 = 1, p2 = 0
ui.main.dataset.scenario = data.scenarios[view.scenario].number
ui.name[p1].textContent = data.scenarios[view.scenario].players[0].name
ui.name[p2].textContent = data.scenarios[view.scenario].players[1].name
ui.role_name[p1].textContent = data.scenarios[view.scenario].players[0].name
ui.role_name[p2].textContent = data.scenarios[view.scenario].players[1].name
for (let e of ui.cubes)
e.remove()
for (let e of ui.sticks)
e.remove()
fill_card_row(p2, ui.reserve[p1], view.reserve[0])
fill_card_row(p2, ui.front[p1], view.front[0])
fill_card_row(p1, ui.reserve[p2], view.reserve[1])
fill_card_row(p1, ui.front[p2], view.front[1])
for (let i = 0; i < view.morale[0]; ++i)
add_cube(ui.morale[p1])
for (let i = 0; i < view.morale[1]; ++i)
add_cube(ui.morale[p2])
function update_die(d, p) {
let v = view.dice[d * 2 + 0]
let c = view.dice[d * 2 + 1]
ui.dice[d].className = "die d" + v
if (c < 0)
ui.pool[p].appendChild(ui.dice[d])
else
ui.slot_dice[c].appendChild(ui.dice[d])
}
for (let i = 0; i < 6; ++i) {
update_die(i, p1)
update_die(i+6, p2)
}
for (let e of action_register) {
if (e.my_fizzle) {
e.classList.toggle("action", is_action(e.my_action, e.my_id) || is_action(e.my_fizzle, e.my_id))
e.classList.toggle("fizzle", is_action(e.my_fizzle, e.my_id))
} else {
e.classList.toggle("action", is_action(e.my_action, e.my_id))
}
}
action_button("bombard", "Bombard")
action_button("roll", "Roll")
action_button("pass", "Pass")
action_button("done", "Done")
action_button("end_turn", "End turn")
action_button("undo", "Undo")
}
for (let i = 0; i < 10; ++i)
ui.cubes[i] = create_div("cube")
for (let i = 0; i < 80; ++i)
ui.sticks[i] = create_div("stick")
for (let i = 0; i < 12; ++i)
ui.dice[i] = register_action(create_div("die d0"), "die", i)
function map_get(map, key, missing) {
let a = 0
let b = (map.length >> 1) - 1
while (a <= b) {
let m = (a + b) >> 1
let x = map[m<<1]
if (key < x)
b = m - 1
else if (key > x)
a = m + 1
else
return map[(m<<1)+1]
}
return missing
}