|
|
| Line 91: |
Line 91: |
| } | | } |
| })(); | | })(); |
| /* ===========================
| |
| Dungeon Leaderboard Script
| |
| =========================== */
| |
|
| |
| mw.hook('wikipage.content').add(function () { | | mw.hook('wikipage.content').add(function () { |
|
| |
|
| var table = document.getElementById("leaderboardTable"); | | var table = document.querySelector('.wikitable'); |
| if (!table) return; // Only run on leaderboard page | | if (!table) return; |
| | |
| var dungeonFilter = document.getElementById("filterDungeon");
| |
| var typeFilter = document.getElementById("filterType");
| |
| var addBtn = document.getElementById("addRunBtn");
| |
| | |
| /* ---------- Time Parsing ---------- */
| |
|
| |
|
| function parseTime(t) { | | function parseTime(t) { |
| if (!t || t.indexOf(":") === -1) return 999999; | | if (!t.includes(":")) return 999999; |
| var parts = t.split(":"); | | var parts = t.split(":"); |
| return parseInt(parts[0], 10) * 60 + parseInt(parts[1], 10); | | return parseInt(parts[0],10) * 60 + parseInt(parts[1],10); |
| }
| |
| | |
| /* ---------- Sorting & Ranking ---------- */
| |
| | |
| function sortAndRank() {
| |
| | |
| var rows = Array.prototype.slice.call(table.rows, 1);
| |
| | |
| rows.sort(function (a, b) {
| |
| return parseTime(a.cells[6].innerText) -
| |
| parseTime(b.cells[6].innerText);
| |
| });
| |
| | |
| rows.forEach(function (row) {
| |
| table.appendChild(row);
| |
| });
| |
| | |
| rows.forEach(function (row, index) {
| |
| var rankCell = row.cells[0];
| |
| | |
| if (index === 0) rankCell.innerHTML = "🥇 1";
| |
| else if (index === 1) rankCell.innerHTML = "🥈 2";
| |
| else if (index === 2) rankCell.innerHTML = "🥉 3";
| |
| else rankCell.innerText = index + 1;
| |
| });
| |
| } | | } |
|
| |
|
| /* ---------- Filtering ---------- */ | | var rows = Array.from(table.rows).slice(1); |
| | |
| function filterTable() {
| |
| | |
| var selectedDungeon = dungeonFilter ? dungeonFilter.value : "All";
| |
| var selectedType = typeFilter ? typeFilter.value : "All";
| |
| | |
| Array.prototype.slice.call(table.rows, 1).forEach(function (row) {
| |
| | |
| var dungeon = row.cells[1].innerText.trim();
| |
| var type = row.cells[2].innerText.trim();
| |
|
| |
|
| var show =
| | rows.sort(function(a,b){ |
| (selectedDungeon === "All" || dungeon === selectedDungeon) &&
| | return parseTime(a.cells[3].innerText) - |
| (selectedType === "All" || type === selectedType);
| | parseTime(b.cells[3].innerText); |
| | }); |
|
| |
|
| row.style.display = show ? "" : "none";
| | rows.forEach(row => table.appendChild(row)); |
| });
| |
| } | |
| | |
| if (dungeonFilter)
| |
| dungeonFilter.addEventListener("change", filterTable);
| |
| | |
| if (typeFilter)
| |
| typeFilter.addEventListener("change", filterTable);
| |
| | |
| /* ---------- Submit Modal ---------- */
| |
| | |
| if (addBtn) {
| |
| | |
| addBtn.addEventListener("click", function () {
| |
| | |
| var overlay = document.createElement("div");
| |
| overlay.style.position = "fixed";
| |
| overlay.style.top = "0";
| |
| overlay.style.left = "0";
| |
| overlay.style.width = "100%";
| |
| overlay.style.height = "100%";
| |
| overlay.style.background = "rgba(0,0,0,0.6)";
| |
| overlay.style.display = "flex";
| |
| overlay.style.alignItems = "center";
| |
| overlay.style.justifyContent = "center";
| |
| overlay.style.zIndex = "9999";
| |
| | |
| var modal = document.createElement("div");
| |
| modal.style.background = "#fff";
| |
| modal.style.padding = "20px";
| |
| modal.style.width = "420px";
| |
| modal.style.borderRadius = "8px";
| |
| | |
| modal.innerHTML = `
| |
| <h3>Submit Dungeon Run</h3>
| |
| | |
| <label>Dungeon:</label><br>
| |
| <input type="text" id="runDungeon"><br><br>
| |
| | |
| <label>Type:</label><br>
| |
| <select id="runType">
| |
| <option value="Solo">Solo</option>
| |
| <option value="Party">Party</option>
| |
| </select><br><br>
| |
| | |
| <div id="partySizeSection" style="display:none;">
| |
| <label>Party Size:</label><br>
| |
| <select id="runPartySize">
| |
| <option>1</option>
| |
| <option>2</option>
| |
| <option>3</option>
| |
| <option>4</option>
| |
| </select><br><br>
| |
| </div>
| |
| | |
| <div id="weaponSection">
| |
| <label>Weapon (Solo Only):</label><br>
| |
| <select id="runWeapon">
| |
| <option>Bow</option>
| |
| <option>Great Sword</option>
| |
| <option>Sword & Shield</option>
| |
| </select><br><br>
| |
| </div>
| |
| | |
| <label>Player / Party:</label><br>
| |
| <input type="text" id="runPlayer"><br><br>
| |
| | |
| <label>Time (MM:SS):</label><br>
| |
| <input type="text" id="runTime"><br><br>
| |
| | |
| <label>Date:</label><br>
| |
| <input type="text" id="runDate"><br><br>
| |
| | |
| <label>Screenshot:</label><br>
| |
| <small>Upload first via <a href="/wiki/Special:Upload" target="_blank">Upload File</a></small><br>
| |
| <input type="text" id="runScreenshot"><br><br>
| |
| | |
| <button id="submitRun">Generate Entry</button>
| |
| <button id="cancelRun">Cancel</button>
| |
| `;
| |
| | |
| overlay.appendChild(modal);
| |
| document.body.appendChild(overlay);
| |
| | |
| var runType = document.getElementById("runType");
| |
| var partySizeSection = document.getElementById("partySizeSection");
| |
| var weaponSection = document.getElementById("weaponSection");
| |
| | |
| runType.addEventListener("change", function () {
| |
| if (this.value === "Party") {
| |
| partySizeSection.style.display = "block";
| |
| weaponSection.style.display = "none";
| |
| } else {
| |
| partySizeSection.style.display = "none";
| |
| weaponSection.style.display = "block";
| |
| }
| |
| });
| |
| | |
| document.getElementById("cancelRun").onclick = function () {
| |
| document.body.removeChild(overlay);
| |
| };
| |
| | |
| document.getElementById("submitRun").onclick = function () {
| |
| | |
| var dungeon = document.getElementById("runDungeon").value;
| |
| var type = runType.value;
| |
| var partySize = type === "Solo" ? "1" :
| |
| document.getElementById("runPartySize").value;
| |
| var weapon = type === "Solo" ?
| |
| document.getElementById("runWeapon").value : "—";
| |
| var player = document.getElementById("runPlayer").value;
| |
| var time = document.getElementById("runTime").value;
| |
| var date = document.getElementById("runDate").value;
| |
| var screenshot = document.getElementById("runScreenshot").value;
| |
| | |
| if (!player || !time || !date || !screenshot) {
| |
| alert("All required fields must be completed.");
| |
| return;
| |
| }
| |
| | |
| var row = `
| |
| |-
| |
| |
| |
| | ${dungeon}
| |
| | ${type}
| |
| | ${partySize}
| |
| | ${player}
| |
| | ${weapon}
| |
| | ${time}
| |
| | ${date}
| |
| | [[File:${screenshot}|120px]]
| |
| `;
| |
| | |
| alert("Copy this row and paste at bottom of table:\n\n" + row);
| |
| document.body.removeChild(overlay);
| |
| };
| |
| });
| |
| }
| |
|
| |
|
| /* ---------- Init ---------- */ | | rows.forEach(function(row, index){ |
| | row.cells[0].innerHTML = |
| | index === 0 ? "🥇 1" : |
| | index === 1 ? "🥈 2" : |
| | index === 2 ? "🥉 3" : |
| | index + 1; |
| | }); |
|
| |
|
| sortAndRank();
| |
| }); | | }); |