From b2c68b84481e4393fd13d78184318bbe22ff427c Mon Sep 17 00:00:00 2001 From: Tor Andersson Date: Wed, 22 Nov 2023 01:55:38 +0100 Subject: lotsa stuff --- play.js | 288 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 288 insertions(+) create mode 100644 play.js (limited to 'play.js') diff --git a/play.js b/play.js new file mode 100644 index 0000000..176a006 --- /dev/null +++ b/play.js @@ -0,0 +1,288 @@ +"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, "reserve", "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 +} -- cgit v1.2.3