|
|
|
@ -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");
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|