MediaWiki:Gadget-fightcaverotations-core.js

From RuneRealm Wiki
Jump to navigation Jump to search

After saving, you may need to bypass your browser's cache to see the changes. For further information, see Wikipedia:Bypass your cache.

  • In most Windows and Linux browsers: Hold down Ctrl and press F5.
  • In Safari: Hold down ⇧ Shift and click the Reload button.
  • In Chrome and Firefox for Mac: Hold down both ⌘ Cmd+⇧ Shift and press R.
"use strict";

// This gadget updates the predicted rotation times on [[TzHaar Fight Cave/Rotations]]. Made by Gau Cho, but it was Fjara's idea

var ROTATION_CYCLE = 16;
function mod(a, n) {
  return a - n * Math.floor(a / n);
}
function getMinutesFromMidnight(time) {
  // Gets minutes from UTC midnight
  return time.getUTCHours() * 60 + time.getUTCMinutes();
}
function formatTime(time) {
  // Formats time (using the local timezone)
  return time.getHours() + ':' + ('0' + time.getMinutes()).slice(-2);
}
function getNextRotationTime(rotationID, time, nthCycle) {
  // Gets the time of the nth next cycle for the desired rotation, where the 0th cycle is the next time the rotation occurs
  if (rotationID < 0 || rotationID >= ROTATION_CYCLE) throw RangeError('rotationID invalid');
  var minutesFromMidnight = getMinutesFromMidnight(time);
  var offsetInMinutes = mod(rotationID - minutesFromMidnight, ROTATION_CYCLE);
  return new Date(time.getTime() + offsetInMinutes * 60000 + nthCycle * ROTATION_CYCLE * 60000);
}
function updateTimes() {
  var curTime = new Date();

  // Unhighlight the old row that was highlighted
  $('#rotation-table .table-yes').removeClass('table-yes');

  // Update the times of all the rows
  for (var rotationID = 0; rotationID < ROTATION_CYCLE; rotationID++) {
    // Calculated the next two desired times
    var nextRotationTime = getNextRotationTime(rotationID, curTime, 0);
    var thereafterRotationTime = getNextRotationTime(rotationID, curTime, 1);

    // rotationID 0 and 15 refer to the same rotation - this is the special case of the rotation that lasts for 2 minutes
    // We highlight if the time matches either rotationID 0 or 15, but display the time for rotationID 15 as it is 1 minute earlier (so we do rotationID 0 and then after rotationID 15)
    var rotationIDSelector = rotationID === 15 ? 0 : rotationID;
    if (rotationID === 15) {
      // We need to handle the edge case where we are in the second minute, in which case the rotation time will display to be 16 minutes too late
      if (nextRotationTime.getTime() === curTime.getTime() + 15 * 60000) {
        nextRotationTime = new Date(nextRotationTime.getTime() - 16 * 60000);
        thereafterRotationTime = new Date(thereafterRotationTime.getTime() - 16 * 60000);
      }
    }

    // Highlight the new current row
    if (nextRotationTime.getTime() === curTime.getTime()) {
      $('#rotation-' + rotationIDSelector).addClass('table-yes');
    }
    // Update the times
    $('#rotation-' + rotationIDSelector + ' > .rotation-time-first').text(formatTime(nextRotationTime));
    $('#rotation-' + rotationIDSelector + ' > .rotation-time-second').text(formatTime(thereafterRotationTime));
  }

  // Update the current time in the prose
  $('#rotation-time').text(formatTime(curTime));

  // Run the script at the exact moment that the minutes number changes
  var timeToNextMinute = 60000 - curTime.getTime() % 60000;
  setTimeout(updateTimes, timeToNextMinute);
}
$(updateTimes);