Jump to content
This is a wiki for a reason. Anyone can contribute. If you see something that is inaccurate or can be improved, don't ask that it be fixed--just improve it.
[ Disclaimer, Create new user --- Wiki markup help, Install P99 ]

MediaWiki:BuffLines.js

From p99 Backup
Revision as of 17:19, 19 January 2019 by imported>Loramin
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Note: After publishing, you may have to bypass your browser's cache to see the changes.

  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
  • Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5.
// List of classes that cast buffs
var eqClasses = ['Bard', 'Cleric', 'Druid', 'Enchanter', 'Magician', 'Necromancer', 'Paladin', 'Ranger', 'Shadow Knight', 'Shaman', 'Wizard']
var sources = ['Consumable', 'Clickable', 'Proc', 'Spell', 'Worn'];
var itemSources = ['Consumable', 'Clickable', 'Proc', 'Worn'];
var targets = ['Group', 'Self-only', 'Single'];

/**
 * Converts a class/source/target into an ID, eg. Group => groupFilter
 */
var makeId = function(thing) {
  if (thing === 'Self-only') return 'selfOnlyFilter';
  if (thing === 'Shadow Knight') return 'shadowKnightFilter';
  return thing.toLowerCase() + 'Filter';
};

/**
  * @returns the HTML for a label/checkbox combination for one filter type
  */
var buildCheckboxLine = function(type, label) {
  label = isNaN(label) ? label : type;
  return '  <label><input id="' + makeId(type) + '"checked class="filter" type="checkbox"/> ' + label + '</label>';
};

var isChecked = function(thingToCheck) {
  return $('#' + makeId(thingToCheck)).is(':checked');
};

var isItemSource = function(line) {
  return (
    doesLineMatchThisAndType('Consumable', line) ||
    doesLineMatchThisAndType('Clickable', line) ||
    doesLineMatchThisAndType('Proc', line) ||
    doesLineMatchThisAndType('Worn', line)
  );
}

var isSingle = function(line) {
  var isGroup = line.toLowerCase().indexOf('group') !== -1;
  var isSelfOnly = line.toLowerCase().indexOf('self-only') !== -1;
  return !isGroup && !isSelfOnly;
}

/**
 * Checks whether the provided line matches the provided type
 * eg. doesLineMatchThisAndType('target', 'single', line) would only
 *     return true if the line was for a single-target buff (ie. it had no 
 *     "self-only" or "group")
 */
var doesLineMatchThisAndType = function(type, line) {
  line = line.toLowerCase();
  type = type.toLowerCase();
  // "Spell" matches if none of the item sources match
  if (type === 'spell') return !isItemSource(line);
  // Single matches if neither a group nor self-only match
  if (type === 'single') return isSingle(line);
  return line.indexOf(type) !== -1;
};

/**
 * Higher Order function which returns a function that returns true only if
 * the line both matches the provided type and if that type
 * should be shown (ie. is checked)
 */
var hasTypeInLineAndTypeIsShown = function(line) { 
  return function(type) {
    // If this type (eg. Shaman spells) isn't checked, don't show it
    if (!isChecked(type)) return false;

    // Otherwise, show it if this line matches (eg. it is a Shaman spell)
    return doesLineMatchThisAndType(type,  line);
  };
};

/**
 * @returns true if the provided line matches an item source that is checked
 */
var hasMatchingItemSource = function(line) {
  return itemSources.some(hasTypeInLineAndTypeIsShown(line));
};

/**
 * @returns true if the provided line matches a class that is checked, and the
 *          "Spell" source is currently checked
 */
var hasMatchingSpellSource = function(line) {
  return isChecked('Spell') && 
         eqClasses.some(hasTypeInLineAndTypeIsShown(line));
};

/**
 * @returns true if the provided line matches a target that has been checked
 */
var hasMatchingTarget = function(line) {
  return targets.some(hasTypeInLineAndTypeIsShown(line));
};


var shouldShow = function(line) {
  var isBuff = line.startsWith('+');
  var itemSourceIsShown = hasMatchingItemSource(line);
  var spellSourceIsShown = hasMatchingSpellSource(line);
  var targetIsShown = hasMatchingTarget(line);
  var isShown = !isBuff || ( // non-buff lines are always shown
    // line must match a class or item source
    (itemSourceIsShown || spellSourceIsShown) &&
    // line must also match a target
    targetIsShown
  );
  //if (!isShown) console.log(line, 'isBuff, itemSourceIsShown, spellSourceIsShown, targetIsShown', isBuff, itemSourceIsShown, spellSourceIsShown, targetIsShown);
  return isShown;
};

var areAllClassCheckboxesChecked = function() {
  return eqClasses.every(function(eqClass) {
    return $('#' + makeId(eqClass)).is(':checked')
  });
};
var areAllClassCheckboxesUnchecked = function() {
  return eqClasses.every(function(eqClass) {
    return !$('#' + makeId(eqClass)).is(':checked')
  });
};

var checkAllClassBoxes = function() {
  eqClasses.forEach(function(eqClass) {
    $('#' + makeId(eqClass)).trigger('click').prop('checked', true);
  });
};

var uncheckAllClassBoxes = function() {
  eqClasses.forEach(function(eqClass) {
    $('#' + makeId(eqClass)).trigger('click').prop('checked', false);
  });
};

// Filter buffs when a buff checkbox is clicked
var handleFilterCheckboxClick = function(e) {
  $('#content li').each(function(i, el) {
    var line = $(el).text().trim();
    var shouldBeShown = shouldShow(line);
    $(el).toggle(shouldBeShown);
  });
  // If all of the checkboxes are checked, ensure the All box is checked
  // (and vice versa if they're all unchecked)
  if (!areAllClassCheckboxesChecked()) {
    $('#allClassFilter').prop('checked', false);
  } else if (!areAllClassCheckboxesUnchecked()) {
    $('#allClassFilter').prop('checked', true);
  }
};

var handleAllClassCheckboxChange = function(e) {
  if (e.target.checked && !areAllClassCheckboxesChecked()) {
    checkAllClassBoxes();
  } else if (!e.target.checked && !areAllClassCheckboxesUnchecked()) {
    uncheckAllClassBoxes();
  }
};

$(function() {
  // Replace placeholder with checkboxes (since wiki doesn't allow checkboxesw)
  $('#checkboxesPlaceHolder').replaceWith(
    '<div>' +
    '  <div><strong>Source:</strong> ' + 
       sources.map(buildCheckboxLine).join(' ') + '</div>' +
    '  <div><strong>Target:</strong> ' + 
       targets.map(buildCheckboxLine).join(' ') + '</div>' +
    '  <div>' +
    '    <strong>Class:</strong> ' +
    '    <label><input id="allClassFilter"checked type="checkbox"/> All</label>' +
         eqClasses.map(buildCheckboxLine).join(' ') +
    '  </div>' +
    '</div>'
  );
  // When they are clicked, filter
  $('.filter').click(handleFilterCheckboxClick);
  $('#allClassFilter').change(handleAllClassCheckboxChange);
});