diff --git a/tunictracker/empty_overview.json b/tunictracker/empty_overview.json index 87d9dbb..3066afd 100644 --- a/tunictracker/empty_overview.json +++ b/tunictracker/empty_overview.json @@ -5,6 +5,10 @@ "entrances": 1312, "hints": 0, "codes": { - "empty": 0 + "???": { + "Distance": 0, + "Global": false, + "InRange": false + } } } diff --git a/tunictracker/tracker/static/tracker/assets/main.js b/tunictracker/tracker/static/tracker/assets/main.js index 5ef1a5e..2cc9d55 100644 --- a/tunictracker/tracker/static/tracker/assets/main.js +++ b/tunictracker/tracker/static/tracker/assets/main.js @@ -11,20 +11,18 @@ var total_checks = 0; var total_entrances = 0; // Global state internal -var server_address = ""; +var server_address = "localhost:51111"; var cross_codes = {}; +var can_access_api_server = true; -window.onload = () => { - get_updated_server_address(); +window.onload = async () => { + await get_updated_server_address(); fetch(`${document.URL}static/tracker/data/holy_cross_codes.json`) .then((response) => response.json()) .then( (data) => { cross_codes = JSON.parse(JSON.stringify(data)); - refresh_overview().then((overview) => { - perform_updates(true, true, true, true); - update_overview(overview, true); - }); + initialize_elements(); refresh_elements(); }, (error) => { @@ -33,40 +31,350 @@ window.onload = () => { ); }; -async function refresh_elements() { - const overview = await refresh_overview().catch(() => - console.log("Could not access the API server.") - ); +// A function to call when the page loads to ensure that we have the correct data when we connect to the server. +async function initialize_elements() { + // Grab all updates from the backend. + let overview = await refresh_overview(); + if (!overview.overview) { + return; + } + const checks = await refresh_checks(); + const entrances = await refresh_entrances(); + const hints = await refresh_hints(); + overview = overview.overview; - if (overview) { - document.getElementById("status-block").classList.add("hidden"); + // Initialize overview data. + current_checks = checks.collected; + current_entrances = entrances.found; + total_checks = checks.total; + total_entrances = entrances.total; + update_overview(overview, true); - const changed_seed = overview.seed != current_seed; - const changed_scene = overview.scene != current_scene; - const changed_checks = overview.items != current_checks; - const changed_entrances = overview.entrances != current_entrances; - const changed_hints = overview.hints != current_hints; - const any_change = - changed_seed || - changed_scene || - changed_checks || - changed_entrances || - changed_hints; + // Initialize breakdown list + let breakdown_list = document + .getElementById("breakdown-list") + .cloneNode(true); + let breakdown_list_item = breakdown_list.firstElementChild.cloneNode(true); + breakdown_list.innerHTML = ""; + breakdown_list.appendChild(breakdown_list_item.cloneNode(true)); + breakdown_list_item.classList.remove("hidden"); - if (any_change) { - await perform_updates( - changed_seed, - changed_checks, - changed_entrances, - changed_hints - ); - update_overview(overview, changed_scene); + // Initialize summary list + let summary_list = document.getElementById("summary-list").cloneNode(true); + let summary_list_item = + summary_list.firstElementChild.firstElementChild.cloneNode(true); + summary_list.firstElementChild.innerHTML = ""; + summary_list.firstElementChild.appendChild(summary_list_item.cloneNode(true)); + summary_list_item.classList.remove("hidden"); + + // Initialize codes list + let codes_list = document.getElementById("codes-list").cloneNode(true); + let codes_list_item = codes_list.firstElementChild.cloneNode(true); + codes_list.innerHTML = ""; + codes_list.appendChild(codes_list_item.cloneNode(true)); + codes_list_item.classList.remove("hidden"); + + // Initialize hints list + let hints_list = document.getElementById("hints-list").cloneNode(true); + let hints_list_item = hints_list.firstElementChild.cloneNode(true); + hints_list.innerHTML = ""; + hints_list.appendChild(hints_list_item.cloneNode(true)); + hints_list_item.classList.remove("hidden"); + + // Populate the breakdown list + Object.keys(checks.scenes).forEach((scene) => { + // One-time update the title for each scene. + if (current_scene == scene) { + breakdown_list_item.dataset.current = "true"; + breakdown_list_item.classList.remove("hidden", "order-last"); + breakdown_list_item.classList.add("order-first"); + } else { + breakdown_list_item.dataset.current = "false"; + breakdown_list_item.classList.add("hidden", "order-last"); + breakdown_list_item.classList.remove("order-first"); } - await update_codes(overview.codes); + breakdown_list_item.dataset.breakdownScene = scene; + breakdown_list_item.querySelector(".breakdown-block-title").textContent = + scene; + + // Populate checks data + breakdown_list_item.querySelector( + ".breakdown-block-checks-title" + ).textContent = `Checks: ${checks.scenes[scene].collected}/${checks.scenes[scene].total}/(${checks.scenes[scene].remaining} left)`; + breakdown_list_item.querySelector( + ".breakdown-block-checks-title" + ).dataset.checksCollected = checks.scenes[scene].collected; + breakdown_list_item.querySelector( + ".breakdown-block-checks-title" + ).dataset.checksRemaining = checks.scenes[scene].remaining; + breakdown_list_item.querySelector( + ".breakdown-block-checks-title" + ).dataset.checksTotal = checks.scenes[scene].total; + + // Populate entrances data + breakdown_list_item.querySelector( + ".breakdown-block-entrances-title" + ).textContent = `Entrances: ${entrances.scenes[scene].found}/${entrances.scenes[scene].total}/(${entrances.scenes[scene].remaining} left)`; + breakdown_list_item.querySelector( + ".breakdown-block-entrances-title" + ).dataset.entrancesFound = entrances.scenes[scene].found; + breakdown_list_item.querySelector( + ".breakdown-block-entrances-title" + ).dataset.entrancesRemaining = entrances.scenes[scene].remaining; + breakdown_list_item.querySelector( + ".breakdown-block-entrances-title" + ).dataset.entrancesTotal = entrances.scenes[scene].total; + + // Initialize checks list + let new_breakdown_block_checks_list = breakdown_list_item + .querySelector(".breakdown-block-checks-list") + .cloneNode(true); + let new_breakdown_block_checks_list_item = + new_breakdown_block_checks_list.firstElementChild.cloneNode(true); + new_breakdown_block_checks_list.innerHTML = ""; + new_breakdown_block_checks_list.appendChild( + new_breakdown_block_checks_list_item.cloneNode(true) + ); + new_breakdown_block_checks_list_item.classList.remove("hidden"); + + // Initialize entrances list + let new_breakdown_block_entrances_list = breakdown_list_item + .querySelector(".breakdown-block-entrances-list") + .cloneNode(true); + let new_breakdown_block_entrances_list_item = + new_breakdown_block_entrances_list.firstElementChild.cloneNode(true); + new_breakdown_block_entrances_list.innerHTML = ""; + new_breakdown_block_entrances_list.appendChild( + new_breakdown_block_entrances_list_item.cloneNode(true) + ); + new_breakdown_block_entrances_list_item.classList.remove("hidden"); + + // Initialize mapped list + let new_breakdown_block_mapped_list = breakdown_list_item + .querySelector(".breakdown-block-mapped-list") + .cloneNode(true); + let new_breakdown_block_mapped_list_item = + new_breakdown_block_mapped_list.firstElementChild.cloneNode(true); + new_breakdown_block_mapped_list.innerHTML = ""; + new_breakdown_block_mapped_list.appendChild( + new_breakdown_block_mapped_list_item.cloneNode(true) + ); + new_breakdown_block_mapped_list_item.classList.remove("hidden"); + + // Create checks list + Object.keys(checks.scenes[scene].checks).forEach((check) => { + new_breakdown_block_checks_list_item.textContent = `❌ ${check}`; + if (!checks.scenes[scene].checks[check].name) { + new_breakdown_block_checks_list.appendChild( + new_breakdown_block_checks_list_item.cloneNode(true) + ); + } + }); + + // Create entrances list and mapped list + Object.keys(entrances.scenes[scene].doors).forEach((entrance) => { + if (!entrances.scenes[scene].doors[entrance].door) { + new_breakdown_block_entrances_list_item.textContent = `❌ ${entrance}`; + new_breakdown_block_entrances_list.appendChild( + new_breakdown_block_entrances_list_item.cloneNode(true) + ); + } else { + new_breakdown_block_mapped_list_item.dataset.scene = + entrances.scenes[scene].doors[entrance].scene; + new_breakdown_block_mapped_list_item.textContent = `✔️ ${entrance} -> ${entrances.scenes[scene].doors[entrance].door}`; + new_breakdown_block_mapped_list.appendChild( + new_breakdown_block_mapped_list_item.cloneNode(true) + ); + } + }); + + // Replace lists in breakdown + breakdown_list_item + .querySelector(".breakdown-block-checks-list") + .replaceWith(new_breakdown_block_checks_list.cloneNode(true)); + breakdown_list_item + .querySelector(".breakdown-block-entrances-list") + .replaceWith(new_breakdown_block_entrances_list.cloneNode(true)); + breakdown_list_item + .querySelector(".breakdown-block-mapped-list") + .replaceWith(new_breakdown_block_mapped_list.cloneNode(true)); + + // Add breakdown to list + breakdown_list.appendChild(breakdown_list_item.cloneNode(true)); + }); + + // Populate the summary list + for (const scene of Object.keys(checks.scenes)) { + // One-time update data for scene + summary_list_item.dataset.scene = scene; + summary_list_item.querySelector(".summary-title").textContent = scene; + + // Update checks and entrances + summary_list_item.dataset.checksCollected = checks.scenes[scene].collected; + summary_list_item.dataset.checksRemaining = checks.scenes[scene].remaining; + summary_list_item.dataset.checksTotal = checks.scenes[scene].total; + summary_list_item.querySelector( + ".summary-checks" + ).textContent = `Checks: ${checks.scenes[scene].collected}/${checks.scenes[scene].total} (${checks.scenes[scene].total})`; + summary_list_item.dataset.entrancesFound = entrances.scenes[scene].found; + summary_list_item.dataset.entrancesRemaining = + entrances.scenes[scene].remaining; + summary_list_item.dataset.entrancesTotal = entrances.scenes[scene].total; + summary_list_item.querySelector( + ".summary-entrances" + ).textContent = `Entrances: ${entrances.scenes[scene].found}/${entrances.scenes[scene].total} (${entrances.scenes[scene].total})`; + + // Hide summaries for scenes with no entrances + if (entrances.scenes[scene].total <= 0) { + summary_list_item.classList.add("hidden"); + } else { + summary_list_item.classList.remove("hidden"); + } + + // Apply color coding and add summary to list + summary_list_item.firstElementChild.replaceWith( + await apply_summary_colors({ + element: summary_list_item.firstElementChild.cloneNode(true), + checks_collected: checks.scenes[scene].collected, + checks_total: checks.scenes[scene].total, + entrances_found: entrances.scenes[scene].found, + entrances_total: entrances.scenes[scene].total, + }) + ); + summary_list.firstElementChild.appendChild( + summary_list_item.cloneNode(true) + ); + } + + // Populate the codes list + Object.keys(overview.codes) + .sort((i, j) => { + return overview.codes[i].Distance - overview.codes[j].Distance; + }) + .forEach((codename, index) => { + // One-time update data for code + codes_list_item.dataset.codename = codename; + codes_list_item.dataset.order = index; + codes_list_item.querySelector(".codes-list-item-title").textContent = + codename; + + // Update code + if (overview.codes[codename].Global) { + codes_list_item.querySelector(".codes-list-item-code").textContent = + cross_codes["Global"][codename] + .replace(/U/g, "⬆️") + .replace(/R/g, "➡️") + .replace(/D/g, "⬇️") + .replace(/L/g, "⬅️"); + } else { + codes_list_item.querySelector(".codes-list-item-code").textContent = + cross_codes[overview.scene][codename] + .replace(/U/g, "⬆️") + .replace(/R/g, "➡️") + .replace(/D/g, "⬇️") + .replace(/L/g, "⬅️"); + } + + // Add code to list + codes_list.appendChild(codes_list_item.cloneNode(true)); + }); + Object.keys(cross_codes.Default).forEach((codename) => { + // One-time update data for default code + codes_list_item.dataset.codename = codename; + codes_list_item.dataset.order = "last"; + codes_list_item.querySelector(".codes-list-item-title").textContent = + codename; + + // Update code + codes_list_item.querySelector(".codes-list-item-code").textContent = + cross_codes.Default[codename] + .replace(/U/g, "⬆️") + .replace(/R/g, "➡️") + .replace(/D/g, "⬇️") + .replace(/L/g, "⬅️"); + + // Add code to list + codes_list.appendChild(codes_list_item.cloneNode(true)); + }); + + // Populate the hints list + Object.keys(hints).forEach((hint) => { + // Update hint + hints_list_item.firstElementChild.textContent = hints[hint]; + + // Add hint to list + hints_list.appendChild(hints_list_item.cloneNode(true)); + }); + + // Replace breakdown list + document + .getElementById("breakdown-list") + .replaceWith(breakdown_list.cloneNode(true)); + + // Replace summary list + document + .getElementById("summary-list") + .replaceWith(summary_list.cloneNode(true)); + + // Replace codes list + document.getElementById("codes-list").replaceWith(codes_list.cloneNode(true)); + + // Replace hints list + document.getElementById("hints-list").replaceWith(hints_list.cloneNode(true)); + + // update_if_changes(overview); + // update_checks(checks); + // update_entrances(entrances); + // update_hints(hints); + return; +} + +async function refresh_elements() { + const response = await refresh_overview(); + + if (response.overview) { + if (!can_access_api_server) { + console.log("I found the server!"); + can_access_api_server = true; + await initialize_elements(); + } + update_if_changes(response.overview); + } else { + if (can_access_api_server) { + console.log("Could not access the API server."); + } + can_access_api_server = false; } setTimeout(refresh_elements, 500); } +async function update_if_changes(overview) { + document.getElementById("status-block").classList.add("hidden"); + + const changed_seed = overview.seed != current_seed; + const changed_scene = overview.scene != current_scene; + const changed_checks = overview.items != current_checks; + const changed_entrances = overview.entrances != current_entrances; + const changed_hints = overview.hints != current_hints; + const any_change = + changed_seed || + changed_scene || + changed_checks || + changed_entrances || + changed_hints; + + if (any_change) { + await perform_updates( + changed_seed, + changed_checks, + changed_entrances, + changed_hints + ); + update_overview(overview, changed_scene); + } + await update_codes(overview.codes); +} + async function perform_updates( changed_seed, changed_checks, @@ -104,9 +412,9 @@ async function get_updated_server_address() { (data) => { const parsed_data = JSON.parse(JSON.stringify(data)); server_address = parsed_data["listen_address"]; - if (parsed_data["backend_filepath_updated"]) { - get_updated_filepath(); - } + // if (parsed_data["backend_filepath_updated"]) { + // get_updated_filepath(); + // } }, (error) => { console.log(error); @@ -115,9 +423,18 @@ async function get_updated_server_address() { } async function refresh_overview() { - const response = await fetch(`${server_address}overview`); - const data = await response.json(); - return data; + try { + const response = await fetch(`${server_address}overview`); + if (response.ok) { + const data = await response.json(); + if (!("error" in data)) { + return { overview: data, error: null }; + } + } + return { overview: null, error: null }; + } catch (e) { + return { overview: null, error: e }; + } } async function refresh_hints() { @@ -249,7 +566,6 @@ async function update_codes(codes) { .getElementById("codes-list") .querySelector(`[data-codename="${code}"]`).classList ).filter((classname) => classname.startsWith("order-")); - // console.log(classes); if (classes.length > 0) { document .getElementById("codes-list") @@ -344,7 +660,15 @@ async function apply_summary_colors(summary) { "text-highlight-both-text" ); } + } else { + summary.element.classList.add( + "from-highlight-undiscovered-light", + "to-highlight-undiscovered-dark", + "text-highlight-undiscovered-text" + ); } + + return summary.element; } async function update_summary(updates) { @@ -353,7 +677,7 @@ async function update_summary(updates) { .getElementById("summary-list") .querySelector(`[data-scene="${updates.scene}"]`) .querySelector(".summary-checks"); - summary_checks.textContent = `Checks: ${updates.checks.collected}/${summary_checks.dataset.checksTotal} (${updates.checks.remaining} left)`; + summary_checks.textContent = `Checks: ${updates.checks.collected}/${summary_checks.dataset.checksTotal} (${updates.checks.remaining})`; summary_checks.dataset.checksUndiscovered = updates.checks.collected; apply_summary_colors({ element: document @@ -414,45 +738,52 @@ async function update_checks(checks) { document.getElementById("breakdown-list").children ); breakdown_list.forEach((scene) => { - // Create variables for element pointers. - let scene_title = scene.querySelector(".breakdown-block-title").textContent; - if (scene_title) { - const scene_checks = parseInt( - scene.querySelector(".breakdown-block-checks-title").dataset.checks - ); - if (scene_checks != checks.scenes[scene_title].collected) { - scene.querySelector(".breakdown-block-checks-title").dataset.checks = - scene_checks; - update_summary({ - scene: scene_title, - checks: { - collected: checks.scenes[scene_title].collected, - remaining: checks.scenes[scene_title].remaining, - }, - }); - scene.querySelector( - ".breakdown-block-checks-title" - ).textContent = `Checks: ${checks.scenes[scene_title].collected}/${checks.scenes[scene_title].total} (${checks.scenes[scene_title].remaining})`; + if (scene.querySelector(".breakdown-block-title").textContent) { + // Create variables for element pointers. + let scene_title = scene.querySelector( + ".breakdown-block-title" + ).textContent; + if (scene_title) { + const scene_checks = parseInt( + scene.querySelector(".breakdown-block-checks-title").dataset.checks + ); + if (scene_checks != checks.scenes[scene_title].collected) { + scene.querySelector(".breakdown-block-checks-title").dataset.checks = + scene_checks; + update_summary({ + scene: scene_title, + checks: { + collected: checks.scenes[scene_title].collected, + remaining: checks.scenes[scene_title].remaining, + }, + }); + scene.querySelector( + ".breakdown-block-checks-title" + ).textContent = `Checks: ${checks.scenes[scene_title].collected}/${checks.scenes[scene_title].total} (${checks.scenes[scene_title].remaining})`; - new_breakdown_block_checks_list.innerHTML = ""; - breakdown_block_checks_list_item.classList.remove("hidden"); - Object.keys(checks.scenes[scene_title].checks).forEach((check) => { - if (checks.scenes[scene_title].checks[check].name == "") { - breakdown_block_checks_list_item.textContent = `❌ ${check}`; - new_breakdown_block_checks_list.appendChild( - breakdown_block_checks_list_item.cloneNode(true) - ); - } - }); - document - .getElementById("breakdown-list") - .querySelector(`[data-breakdown-scene="${scene_title}"]`) - .querySelector(".breakdown-block-checks-list").innerHTML = ""; - document - .getElementById("breakdown-list") - .querySelector(`[data-breakdown-scene="${scene_title}"]`) - .querySelector(".breakdown-block-checks-list") - .replaceWith(new_breakdown_block_checks_list.cloneNode(true)); + new_breakdown_block_checks_list.innerHTML = ""; + new_breakdown_block_checks_list.appendChild( + breakdown_block_checks_list_item.cloneNode(true) + ); + breakdown_block_checks_list_item.classList.remove("hidden"); + Object.keys(checks.scenes[scene_title].checks).forEach((check) => { + if (checks.scenes[scene_title].checks[check].name == "") { + breakdown_block_checks_list_item.textContent = `❌ ${check}`; + new_breakdown_block_checks_list.appendChild( + breakdown_block_checks_list_item.cloneNode(true) + ); + } + }); + document + .getElementById("breakdown-list") + .querySelector(`[data-breakdown-scene="${scene_title}"]`) + .querySelector(".breakdown-block-checks-list").innerHTML = ""; + document + .getElementById("breakdown-list") + .querySelector(`[data-breakdown-scene="${scene_title}"]`) + .querySelector(".breakdown-block-checks-list") + .replaceWith(new_breakdown_block_checks_list.cloneNode(true)); + } } } }); @@ -483,66 +814,76 @@ async function update_entrances(entrances) { document.getElementById("breakdown-list").children ); breakdown_list.forEach((scene) => { - // Create variables for element pointers. - let scene_title = scene.querySelector(".breakdown-block-title").textContent; - if (scene_title) { - const scene_entrances = parseInt( - scene.querySelector(".breakdown-block-entrances-title").dataset - .entrances - ); - if (scene_entrances != entrances.scenes[scene_title].found) { - scene.querySelector(".breakdown-block-checks-title").dataset.entrances = - scene_entrances; - update_summary({ - scene: scene_title, - entrances: { - found: entrances.scenes[scene_title].found, - remaining: entrances.scenes[scene_title].remaining, - }, - }); - scene.querySelector( - ".breakdown-block-entrances-title" - ).textContent = `Entrances: ${entrances.scenes[scene_title].found}/${entrances.scenes[scene_title].total} (${entrances.scenes[scene_title].remaining})`; + if (scene.querySelector(".breakdown-block-title").textContent) { + // Create variables for element pointers. + let scene_title = scene.querySelector( + ".breakdown-block-title" + ).textContent; + if (scene_title) { + const scene_entrances = parseInt( + scene.querySelector(".breakdown-block-entrances-title").dataset + .entrances + ); + if (scene_entrances != entrances.scenes[scene_title].found) { + scene.querySelector( + ".breakdown-block-checks-title" + ).dataset.entrances = scene_entrances; + update_summary({ + scene: scene_title, + entrances: { + found: entrances.scenes[scene_title].found, + remaining: entrances.scenes[scene_title].remaining, + }, + }); + scene.querySelector( + ".breakdown-block-entrances-title" + ).textContent = `Entrances: ${entrances.scenes[scene_title].found}/${entrances.scenes[scene_title].total} (${entrances.scenes[scene_title].remaining})`; - new_breakdown_block_entrances_list.innerHTML = ""; - breakdown_block_entrances_list_item.classList.remove("hidden"); - new_breakdown_block_mapped_list.innerHTML = ""; - breakdown_block_mapped_list_item.classList.remove("hidden"); + new_breakdown_block_entrances_list.innerHTML = ""; + new_breakdown_block_entrances_list.appendChild( + breakdown_block_entrances_list_item.cloneNode(true) + ); + breakdown_block_entrances_list_item.classList.remove("hidden"); + new_breakdown_block_mapped_list.innerHTML = ""; + breakdown_block_mapped_list_item.classList.remove("hidden"); - Object.keys(entrances.scenes[scene_title].doors).forEach((entrance) => { - if (entrances.scenes[scene_title].doors[entrance].door == "") { - breakdown_block_entrances_list_item.textContent = `❌ ${entrance}`; - new_breakdown_block_entrances_list.appendChild( - breakdown_block_entrances_list_item.cloneNode(true) - ); - } else { - breakdown_block_mapped_list_item.textContent = `✔️ ${entrance} -> ${entrances.scenes[scene_title].doors[entrance].door}`; - breakdown_block_mapped_list_item.id = `${entrance}-mapped`; - breakdown_block_mapped_list_item.dataset.scene = - entrances.scenes[scene_title].doors[entrance].scene; - new_breakdown_block_mapped_list.appendChild( - breakdown_block_mapped_list_item.cloneNode(true) - ); - } - }); - document - .getElementById("breakdown-list") - .querySelector(`[data-breakdown-scene="${scene_title}"]`) - .querySelector(".breakdown-block-entrances-list").innerHTML = ""; - document - .getElementById("breakdown-list") - .querySelector(`[data-breakdown-scene="${scene_title}"]`) - .querySelector(".breakdown-block-entrances-list") - .replaceWith(new_breakdown_block_entrances_list.cloneNode(true)); - document - .getElementById("breakdown-list") - .querySelector(`[data-breakdown-scene="${scene_title}"]`) - .querySelector(".breakdown-block-mapped-list").innerHTML = ""; - document - .getElementById("breakdown-list") - .querySelector(`[data-breakdown-scene="${scene_title}"]`) - .querySelector(".breakdown-block-mapped-list") - .replaceWith(new_breakdown_block_mapped_list.cloneNode(true)); + Object.keys(entrances.scenes[scene_title].doors).forEach( + (entrance) => { + if (entrances.scenes[scene_title].doors[entrance].door == "") { + breakdown_block_entrances_list_item.textContent = `❌ ${entrance}`; + new_breakdown_block_entrances_list.appendChild( + breakdown_block_entrances_list_item.cloneNode(true) + ); + } else { + breakdown_block_mapped_list_item.textContent = `✔️ ${entrance} -> ${entrances.scenes[scene_title].doors[entrance].door}`; + breakdown_block_mapped_list_item.id = `${entrance}-mapped`; + breakdown_block_mapped_list_item.dataset.scene = + entrances.scenes[scene_title].doors[entrance].scene; + new_breakdown_block_mapped_list.appendChild( + breakdown_block_mapped_list_item.cloneNode(true) + ); + } + } + ); + document + .getElementById("breakdown-list") + .querySelector(`[data-breakdown-scene="${scene_title}"]`) + .querySelector(".breakdown-block-entrances-list").innerHTML = ""; + document + .getElementById("breakdown-list") + .querySelector(`[data-breakdown-scene="${scene_title}"]`) + .querySelector(".breakdown-block-entrances-list") + .replaceWith(new_breakdown_block_entrances_list.cloneNode(true)); + document + .getElementById("breakdown-list") + .querySelector(`[data-breakdown-scene="${scene_title}"]`) + .querySelector(".breakdown-block-mapped-list").innerHTML = ""; + document + .getElementById("breakdown-list") + .querySelector(`[data-breakdown-scene="${scene_title}"]`) + .querySelector(".breakdown-block-mapped-list") + .replaceWith(new_breakdown_block_mapped_list.cloneNode(true)); + } } } }); @@ -552,6 +893,8 @@ async function update_hints(hints) { let hints_list = document.getElementById("hints-list").cloneNode(true); let hints_list_item = hints_list.firstElementChild.cloneNode(true); hints_list.innerHTML = ""; + hints_list.appendChild(hints_list_item.cloneNode(true)); + hints_list_item.classList.remove("hidden"); Object.keys(hints).forEach((hint_index) => { let hint = hints[hint_index].split( /(\[[\w\s]+?\]|\"[\w \d\>\<#.\-\']+\"|\<[\w\d#]+\>)/gm @@ -599,9 +942,7 @@ async function update_hints(hints) { async function update_scene(scene) { Array.from(document.getElementById("breakdown-list").children).forEach( (breakdown) => { - const breakdown_title = breakdown.querySelector( - ".breakdown-block-title" - ).textContent; + const breakdown_title = breakdown.dataset.breakdownScene; if (breakdown_title == scene) { document .getElementById("breakdown-list") @@ -632,7 +973,7 @@ async function update_scene(scene) { .classList.add("hidden"); document .getElementById("breakdown-list") - .querySelector(`[data-breakdown-scene="${scene}"]`) + .querySelector(`[data-breakdown-scene="${breakdown_title}"]`) .classList.add("order-last"); document .getElementById("breakdown-list") @@ -648,12 +989,12 @@ async function update_scene(scene) { if (summary_scene == scene) { document .getElementById("summary-list") - .firstElementChild.querySelector(`[data-scene="${scene}"]`) + .querySelector(`[data-scene="${scene}"]`) .classList.add("hidden"); } else if (!(summary_scene == "")) { document .getElementById("summary-list") - .firstElementChild.querySelector(`[data-scene="${summary_scene}"]`) + .querySelector(`[data-scene="${summary_scene}"]`) .classList.remove("hidden"); } }); diff --git a/tunictracker/tracker/static/tracker/data/holy_cross_codes.json b/tunictracker/tracker/static/tracker/data/holy_cross_codes.json index e8667d6..db47249 100644 --- a/tunictracker/tracker/static/tracker/data/holy_cross_codes.json +++ b/tunictracker/tracker/static/tracker/data/holy_cross_codes.json @@ -79,5 +79,8 @@ "Holy Cross Door": "DRULUR", "Holy Cross (Blue Lines)": "URULURULURDRULDLURULURULU", "Tree Holy Cross Chest": "LDRLUD" + }, + "???": { + "???": "UDLR" } } diff --git a/tunictracker/tracker/templates/tracker/breakdown/block.html b/tunictracker/tracker/templates/tracker/breakdown/block.html index aee0432..02f1dfd 100644 --- a/tunictracker/tracker/templates/tracker/breakdown/block.html +++ b/tunictracker/tracker/templates/tracker/breakdown/block.html @@ -12,7 +12,7 @@
-
+
{% for check_name, check in scene_data.checks.checks.items %} @@ -25,14 +25,14 @@
-
+
Entrances: {{ scene_data.entrances.found }}/{{ scene_data.entrances.total }} ({{ scene_data.entrances.remaining }} left)

-
+
{% for entrance_origin, entrance_destination in scene_data.entrances.doors.items %} @@ -54,7 +54,6 @@ {% if entrance_destination.door %}