Toggle menu
Toggle preferences menu
Toggle personal menu
Not logged in
Your IP address will be publicly visible if you make any edits.

MediaWiki:Common.js: Difference between revisions

MediaWiki interface page
No edit summary
No edit summary
Line 132: Line 132:




       function filterTable() {
       /* ===========================
        FIXED COMPETITION LEADERBOARD
        =========================== */


        const selectedDungeon = dungeonSelect.value;
      function buildCompetitionLeaderboard() {
        const playerSearch = playerInput.value.toLowerCase();


         const rows = Array.from(table.querySelectorAll("tr")).slice(1);
         const rows = Array.from(table.querySelectorAll("tr")).slice(1);
        const playerPoints = {};
        function getPoints(rank) {
          const scoring = {
            1: 25, 2: 20, 3: 17, 4: 15, 5: 13,
            6: 11, 7: 10, 8: 9, 9: 8, 10: 7,
            11: 6, 12: 5, 13: 4, 14: 3, 15: 2
          };
          return scoring[rank] || 1;
        }


         rows.forEach(row => {
         rows.forEach(row => {


           const dungeon = row.cells[1].innerText.trim();
           const rank = parseInt(row.cells[0].innerText);
           const player = row.cells[2].innerText.toLowerCase();
           const player = row.cells[2].innerText.trim();


           row.style.display =
           if (!player || isNaN(rank)) return;
            (selectedDungeon === "All" || dungeon === selectedDungeon) &&
            player.includes(playerSearch)
              ? ""
              : "none";


        });
          const points = getPoints(rank);


      }
          playerPoints[player] = (playerPoints[player] || 0) + points;


      dungeonSelect.addEventListener("change", filterTable);
        });
      playerInput.addEventListener("input", filterTable);


      sortAndRank();
        const leaderboard = Object.entries(playerPoints)
    }
          .map(([player, points]) => ({ player, points }))
  }
          .sort((a, b) => b.points - a.points);


        const existing = document.getElementById("competitionLeaderboard");
        if (existing) existing.remove();


  /* ===========================
        const container = document.createElement("div");
    PARTY TABLE
        container.id = "competitionLeaderboard";
    =========================== */
        container.style.marginBottom = "20px";


  const partyTable = document.getElementById("partyLeaderboardTable");
        const title = document.createElement("h2");
        title.innerText = "🏆 Competition Leaderboard";
        container.appendChild(title);


  if (partyTable) {
        const tableEl = document.createElement("table");
        tableEl.className = "wikitable";
        tableEl.style.width = "50%";


    const partyContainer = document.getElementById("partyFilterContainer");
        tableEl.innerHTML = `
          <tr>
            <th>Rank</th>
            <th>Player</th>
            <th>Points</th>
          </tr>
        `;


    if (partyContainer) {
        leaderboard.forEach((entry, index) => {


      const wrapper = document.createElement("div");
          const medals = ["🥇", "🥈", "🥉"];
      wrapper.style.marginBottom = "15px";


      const dungeonLabel = document.createElement("strong");
          const row = document.createElement("tr");
      dungeonLabel.innerText = "Dungeon: ";
      wrapper.appendChild(dungeonLabel);


      const dungeonSelect = document.createElement("select");
          row.innerHTML = `
      dungeonSelect.style.marginRight = "20px";
            <td>${medals[index] || (index + 1)}</td>
            <td>${entry.player}</td>
            <td>${entry.points}</td>
          `;


      const dungeons = [
          tableEl.appendChild(row);
        "All",
        "Wolf's Den","Wolf's Den II","Wolf's Den III",
        "The Red Nest","For The Eggs",
        "Scarlet Revenge","Scarlet Revenge II",
        "Promised One","Promised One II","Promised One III",
        "Lost and Found","The Hostage","Cactus On Fire",
        "Deep Echoes","Deep Echoes II","Deep Echoes III",
        "King's Hoard","King's Hoard II",
        "Hall of Daggers"
      ];


      dungeons.forEach(name => {
         });
         const option = document.createElement("option");
        option.value = name;
        option.textContent = name;
        dungeonSelect.appendChild(option);
      });


      wrapper.appendChild(dungeonSelect);
        container.appendChild(tableEl);
        table.parentNode.insertBefore(container, table);


       const playerLabel = document.createElement("strong");
       }
      playerLabel.innerText = "Players: ";
      wrapper.appendChild(playerLabel);


      const playerInput = document.createElement("input");
      playerInput.type = "text";
      playerInput.placeholder = "Search player name...";
      playerInput.style.padding = "4px";
      wrapper.appendChild(playerInput);


       partyContainer.appendChild(wrapper);
       function filterTable() {


        const selectedDungeon = dungeonSelect.value;
        const playerSearch = playerInput.value.toLowerCase();


      function sortAndRankParty() {
        const rows = Array.from(table.querySelectorAll("tr")).slice(1);


         const rows = Array.from(partyTable.querySelectorAll("tr")).slice(1);
         rows.forEach(row => {


        rows.sort((a,b) => {
          const dungeon = row.cells[1].innerText.trim();
          const player = row.cells[2].innerText.toLowerCase();


           const dungeonA = a.cells[1].innerText.trim();
           row.style.display =
          const dungeonB = b.cells[1].innerText.trim();
            (selectedDungeon === "All" || dungeon === selectedDungeon) &&
            player.includes(playerSearch)
              ? ""
              : "none";


          if (dungeonA < dungeonB) return -1;
        });
          if (dungeonA > dungeonB) return 1;


          return parseTime(a.cells[5].innerText) - parseTime(b.cells[5].innerText);
      }


        });
      dungeonSelect.addEventListener("change", filterTable);
      playerInput.addEventListener("input", filterTable);


        rows.forEach(row => partyTable.appendChild(row));
      sortAndRank();
      buildCompetitionLeaderboard(); // ✅ ONLY RUNS ON LOAD
    }
  }




        let currentDungeon = "";
  /* ===========================
        let dungeonRank = 0;
    PARTY TABLE (unchanged)
        let prevTime = null;
    =========================== */
        let position = 0;


        rows.forEach(row => {
  const partyTable = document.getElementById("partyLeaderboardTable");


          const dungeon = row.cells[1].innerText.trim();
  if (partyTable) {
          const time = parseTime(row.cells[5].innerText);
          const rankCell = row.cells[0];


          if (dungeon !== currentDungeon) {
    function sortAndRankParty() {
            currentDungeon = dungeon;
            dungeonRank = 1;
            position = 1;
            prevTime = time;
          } else {
            position++;


            if (time !== prevTime) {
      const rows = Array.from(partyTable.querySelectorAll("tr")).slice(1);
              dungeonRank = position;
            }


            prevTime = time;
      rows.sort((a,b) => {
          }


          if (dungeonRank === 1) rankCell.innerHTML = "🥇 1";
        const dungeonA = a.cells[1].innerText.trim();
          else if (dungeonRank === 2) rankCell.innerHTML = "🥈 2";
        const dungeonB = b.cells[1].innerText.trim();
          else if (dungeonRank === 3) rankCell.innerHTML = "🥉 3";
          else rankCell.innerText = dungeonRank;


         });
         if (dungeonA < dungeonB) return -1;
        if (dungeonA > dungeonB) return 1;


      }
        return parseTime(a.cells[5].innerText) - parseTime(b.cells[5].innerText);


      });


       function filterPartyTable() {
       rows.forEach(row => partyTable.appendChild(row));


        const selectedDungeon = dungeonSelect.value;
      let currentDungeon = "";
        const playerSearch = playerInput.value.toLowerCase();
      let dungeonRank = 0;
      let prevTime = null;
      let position = 0;


        const rows = Array.from(partyTable.querySelectorAll("tr")).slice(1);
      rows.forEach(row => {


         rows.forEach(row => {
         const dungeon = row.cells[1].innerText.trim();
        const time = parseTime(row.cells[5].innerText);
        const rankCell = row.cells[0];


           const dungeon = row.cells[1].innerText.trim();
        if (dungeon !== currentDungeon) {
           const player = row.cells[3].innerText.toLowerCase();
           currentDungeon = dungeon;
          dungeonRank = 1;
          position = 1;
           prevTime = time;
        } else {
          position++;


           row.style.display =
           if (time !== prevTime) {
            (selectedDungeon === "All" || dungeon === selectedDungeon) &&
             dungeonRank = position;
             player.includes(playerSearch)
          }
              ? ""
              : "none";


         });
          prevTime = time;
         }


      }
        if (dungeonRank === 1) rankCell.innerHTML = "🥇 1";
        else if (dungeonRank === 2) rankCell.innerHTML = "🥈 2";
        else if (dungeonRank === 3) rankCell.innerHTML = "🥉 3";
        else rankCell.innerText = dungeonRank;


       dungeonSelect.addEventListener("change", filterPartyTable);
       });
      playerInput.addEventListener("input", filterPartyTable);


      sortAndRankParty();
     }
     }
    sortAndRankParty();
   }
   }


});
});

Revision as of 13:53, 18 March 2026

/* Any JavaScript here will be loaded for all users on every page load. */

mw.hook('wikipage.content').add(function ($content) {
  $content.find('.spoiler').on('click', function () {
    $(this).toggleClass('revealed');
  });
});


/* ===========================
   Dungeon Speedrun Leaderboard
   =========================== */

mw.hook('wikipage.content').add(function () {

  function parseTime(t) {
    if (!t || !t.includes(":")) return 999999;
    const parts = t.trim().split(":");
    return parseInt(parts[0], 10) * 60 + parseInt(parts[1], 10);
  }


  /* ===========================
     SOLO TABLE
     =========================== */

  const table = document.getElementById("leaderboardTable");

  if (table) {

    const container = document.getElementById("filterContainer");

    if (container) {

      const wrapper = document.createElement("div");
      wrapper.style.marginBottom = "15px";

      const dungeonLabel = document.createElement("strong");
      dungeonLabel.innerText = "Dungeon: ";
      wrapper.appendChild(dungeonLabel);

      const dungeonSelect = document.createElement("select");
      dungeonSelect.style.marginRight = "20px";

      const dungeons = [
        "All",
        "Wolf's Den","Wolf's Den II","Wolf's Den III",
        "The Red Nest","For The Eggs",
        "Scarlet Revenge","Scarlet Revenge II",
        "Promised One","Promised One II","Promised One III",
        "Lost and Found","The Hostage","Cactus On Fire",
        "Deep Echoes","Deep Echoes II","Deep Echoes III",
        "King's Hoard","King's Hoard II",
        "Hall of Daggers"
      ];

      dungeons.forEach(name => {
        const option = document.createElement("option");
        option.value = name;
        option.textContent = name;
        dungeonSelect.appendChild(option);
      });

      wrapper.appendChild(dungeonSelect);

      const playerLabel = document.createElement("strong");
      playerLabel.innerText = "Player: ";
      wrapper.appendChild(playerLabel);

      const playerInput = document.createElement("input");
      playerInput.type = "text";
      playerInput.placeholder = "Search player name...";
      playerInput.style.padding = "4px";
      wrapper.appendChild(playerInput);

      container.appendChild(wrapper);


      function sortAndRank() {

        const rows = Array.from(table.querySelectorAll("tr")).slice(1);

        rows.sort((a,b) => {

          const dungeonA = a.cells[1].innerText.trim();
          const dungeonB = b.cells[1].innerText.trim();

          if (dungeonA < dungeonB) return -1;
          if (dungeonA > dungeonB) return 1;

          return parseTime(a.cells[4].innerText) - parseTime(b.cells[4].innerText);

        });

        rows.forEach(row => table.appendChild(row));


        let currentDungeon = "";
        let dungeonRank = 0;
        let prevTime = null;
        let position = 0;

        rows.forEach(row => {

          const dungeon = row.cells[1].innerText.trim();
          const time = parseTime(row.cells[4].innerText);
          const rankCell = row.cells[0];

          if (dungeon !== currentDungeon) {
            currentDungeon = dungeon;
            dungeonRank = 1;
            position = 1;
            prevTime = time;
          } else {
            position++;

            if (time !== prevTime) {
              dungeonRank = position;
            }

            prevTime = time;
          }

          if (dungeonRank === 1) rankCell.innerHTML = "🥇 1";
          else if (dungeonRank === 2) rankCell.innerHTML = "🥈 2";
          else if (dungeonRank === 3) rankCell.innerHTML = "🥉 3";
          else rankCell.innerText = dungeonRank;

        });

      }


      /* ===========================
         FIXED COMPETITION LEADERBOARD
         =========================== */

      function buildCompetitionLeaderboard() {

        const rows = Array.from(table.querySelectorAll("tr")).slice(1);

        const playerPoints = {};

        function getPoints(rank) {
          const scoring = {
            1: 25, 2: 20, 3: 17, 4: 15, 5: 13,
            6: 11, 7: 10, 8: 9, 9: 8, 10: 7,
            11: 6, 12: 5, 13: 4, 14: 3, 15: 2
          };
          return scoring[rank] || 1;
        }

        rows.forEach(row => {

          const rank = parseInt(row.cells[0].innerText);
          const player = row.cells[2].innerText.trim();

          if (!player || isNaN(rank)) return;

          const points = getPoints(rank);

          playerPoints[player] = (playerPoints[player] || 0) + points;

        });

        const leaderboard = Object.entries(playerPoints)
          .map(([player, points]) => ({ player, points }))
          .sort((a, b) => b.points - a.points);

        const existing = document.getElementById("competitionLeaderboard");
        if (existing) existing.remove();

        const container = document.createElement("div");
        container.id = "competitionLeaderboard";
        container.style.marginBottom = "20px";

        const title = document.createElement("h2");
        title.innerText = "🏆 Competition Leaderboard";
        container.appendChild(title);

        const tableEl = document.createElement("table");
        tableEl.className = "wikitable";
        tableEl.style.width = "50%";

        tableEl.innerHTML = `
          <tr>
            <th>Rank</th>
            <th>Player</th>
            <th>Points</th>
          </tr>
        `;

        leaderboard.forEach((entry, index) => {

          const medals = ["🥇", "🥈", "🥉"];

          const row = document.createElement("tr");

          row.innerHTML = `
            <td>${medals[index] || (index + 1)}</td>
            <td>${entry.player}</td>
            <td>${entry.points}</td>
          `;

          tableEl.appendChild(row);

        });

        container.appendChild(tableEl);
        table.parentNode.insertBefore(container, table);

      }


      function filterTable() {

        const selectedDungeon = dungeonSelect.value;
        const playerSearch = playerInput.value.toLowerCase();

        const rows = Array.from(table.querySelectorAll("tr")).slice(1);

        rows.forEach(row => {

          const dungeon = row.cells[1].innerText.trim();
          const player = row.cells[2].innerText.toLowerCase();

          row.style.display =
            (selectedDungeon === "All" || dungeon === selectedDungeon) &&
            player.includes(playerSearch)
              ? ""
              : "none";

        });

      }

      dungeonSelect.addEventListener("change", filterTable);
      playerInput.addEventListener("input", filterTable);

      sortAndRank();
      buildCompetitionLeaderboard(); // ✅ ONLY RUNS ON LOAD
    }
  }


  /* ===========================
     PARTY TABLE (unchanged)
     =========================== */

  const partyTable = document.getElementById("partyLeaderboardTable");

  if (partyTable) {

    function sortAndRankParty() {

      const rows = Array.from(partyTable.querySelectorAll("tr")).slice(1);

      rows.sort((a,b) => {

        const dungeonA = a.cells[1].innerText.trim();
        const dungeonB = b.cells[1].innerText.trim();

        if (dungeonA < dungeonB) return -1;
        if (dungeonA > dungeonB) return 1;

        return parseTime(a.cells[5].innerText) - parseTime(b.cells[5].innerText);

      });

      rows.forEach(row => partyTable.appendChild(row));

      let currentDungeon = "";
      let dungeonRank = 0;
      let prevTime = null;
      let position = 0;

      rows.forEach(row => {

        const dungeon = row.cells[1].innerText.trim();
        const time = parseTime(row.cells[5].innerText);
        const rankCell = row.cells[0];

        if (dungeon !== currentDungeon) {
          currentDungeon = dungeon;
          dungeonRank = 1;
          position = 1;
          prevTime = time;
        } else {
          position++;

          if (time !== prevTime) {
            dungeonRank = position;
          }

          prevTime = time;
        }

        if (dungeonRank === 1) rankCell.innerHTML = "🥇 1";
        else if (dungeonRank === 2) rankCell.innerHTML = "🥈 2";
        else if (dungeonRank === 3) rankCell.innerHTML = "🥉 3";
        else rankCell.innerText = dungeonRank;

      });

    }

    sortAndRankParty();
  }

});