Widget:CharacterTrackerScript
Jump to navigation
Jump to search
<script type="text/javascript">
(function($) { 'use strict';
var otherSkip = []; $('#tracker-filter-obtain > label').each(function() { otherSkip.push(this.dataset.value); });
function Uint8ArrayToBase64(bytes) { var binary = ; var len = bytes.byteLength; for (var i = 0; i < len; i++) binary += String.fromCharCode(bytes[i]); var result = window.btoa(binary); result = result.replace('=', ); // Remove any trailing '='s result = result.replace('+', '-'); // 62nd char of encoding result = result.replace('/', '_'); // 63rd char of encoding if (result == 'AAAA') return ; return result; }
function Base64ToUint8Array(text) { var s = text.replace('_', '/'); // 63rd char of encoding s = s.replace('-', '+'); // 62nd char of encoding var pl = (s.length % 4); if (pl > 0) s += '='.repeat(4-pl); // Restore any trailing '='s
var binary = window.atob(s); var len = binary.length; var result = new Uint8Array(len); for (var i = 0; i < len; i++) result[i] = binary.charCodeAt(i); return result; }
var last_hash = ;
$(window).on('hashchange', function() { if (window.location.hash != last_hash) { readHash(); updateUncap(); updateItems(); } });
function replaceHash(newHash) { if ((+newHash).charAt(0) !== '#') newHash = '#' + newHash; history.replaceState(, , newHash); last_hash = newHash; }
function readHash() { // format: Options;SSR Characters;SR Characters;R Characters;SSR Summons;SR Summons; R Summons // - Options is a base64 encoded json object // - Character/Summons are base64 encoded sets of bits, where each character is 3 bits offset by the counter in its ID last_hash = window.location.hash; var hash = window.location.hash.substr(1); var parts = hash.split(';'); var ix = 1; var strings = { 'c': {2: parts[3], 3: parts[2], 4: parts[1]}, 's': {2: parts[6], 3: parts[5], 4: parts[4]}, };
// load options var reOptions = /[g-z]{1}[0-9a-f]{1,8}/ig; var options = parts[0].match(reOptions); if (options != null) { for (var i = 0; i < options.length; i++) { var text = options[i]; var option = text.charAt(0); var bits = parseInt(text.substr(1), 16); var $option = $('div[data-option="'+option+'"]'); if ($option.length <= 0) continue; var $bits = $option.find('[data-bit]'); if ($bits.length <= 0) continue; $option.find('label').removeClass('mw-ui-progressive'); $bits.each(function() { var selected = ((1 << this.dataset.bit) & bits) > 0; if ($(this).is('input')) { $(this).prop('checked', selected); } else if (selected) { $(this).addClass('mw-ui-progressive'); } });
// verify we actually selected something if ($option.find('.mw-ui-progressive').length > 0) continue;
$option.find('label[data-value="*"]').addClass('mw-ui-progressive'); } }
// reset items $('.tracker-item').each(function() { this.dataset.evo = 0; this.dataset.owned = 'false'; evolve(this, 0); });
// load items for (var type in strings) { for (var rarity in strings[type]) { var str = strings[type][rarity]; if ((str == undefined) || (str.length == 0)) continue; var buffer = Base64ToUint8Array(str); var len = buffer.length / 3; for (var i = 0; i < len; i++) { var evos = 0; evos |= (buffer[i*3 ] << 0); evos |= (buffer[i*3+1] << 8); evos |= (buffer[i*3+2] << 16);
for (var j = 0; j < 8; j++) { var evo = (evos >> (j*3)) & 0x07; if (evo <= 0) continue; var short_id = + rarity + ('000'+(i*8+j)).slice(-3); var $items = $('.tracker-item[data-type="'+type+'"][data-short_id="'+short_id+'"]'); $items.each(function() { evolve(this, evo); }); } } } } }
function makeHash() { // for format see readHash var strings = { 'c': {2:,3:,4:}, 's': {2:,3:,4:}, }; var selected = { 'c': {2:{},3:{},4:{}}, 's': {2:{},3:{},4:{}}, };
// store which items have been selected $('.tracker-item.selected').each(function() { var short_id = this.dataset.short_id; if (short_id.length == 4) { var type = this.dataset.type; var rarity = parseInt(short_id[0], 10); if ((rarity < 2) || (rarity > 4)) return; var index = parseInt(short_id.substr(1), 10); selected[type][rarity][index] = parseInt(this.dataset.evo,10); } });
// convert to a bit array for (var type in selected) { for (var rarity in selected[type]) { var high_id = 0; var obj = selected[type][rarity]; for (var index in obj) high_id = Math.max(high_id, index);
// Group 8 items with 3 bits each var parts = Math.floor(high_id / 8) + 1; var size = parts * 3; var buffer = new Uint8Array(size);
for (var i = 0; i <= Math.floor(high_id / 8); i++) { var evos = 0x000000; for (var j = 0; j < 8; j++) { var evo = obj[i*8+j]; if (evo == undefined) evo = 0; evos |= (evo << (j*3)); } buffer[i*3] = (evos >> 0) & 0xFF; buffer[i*3+1] = (evos >> 8) & 0xFF; buffer[i*3+2] = (evos >> 16) & 0xFF; } strings[type][rarity] += Uint8ArrayToBase64(buffer); }
// Options are stored as hex encoded bit array var options = ; $('div[data-option]').each(function() { var $active = $(this).find('[data-bit].mw-ui-progressive, input[data-bit]:checked'); if ($active.length > 0) { var option = 0; $active.each(function() { option |= 1 << this.dataset.bit; }); options += this.dataset.option + option.toString(16); } });
replaceHash(options+';'+strings['c'][4]+';'+strings['c'][3]+';'+strings['c'][2]+';'+strings['s'][4]+';'+strings['s'][3]+';'+strings['s'][2]); } }
function evolve(node, levels) { var toggle = $(node.parentNode).hasClass('tracker-hide-uncap'); var evo = parseInt(node.dataset.evo, 10); if (toggle) { evo = evo > 0 ? 0 : 1; } else { evo += levels; if (evo > Math.max(node.dataset.evo_max, 1)) evo = 0; } node.dataset.evo = evo; node.dataset.owned = evo > 0 ? 'true' : 'false'; $(node).toggleClass('selected', evo > 0);
$(node).find('.tracker-uncap-star').each(function() { $(this).toggleClass('selected', evo > 0); evo -= 1; }); }
function updateUncap() { var cb = document.getElementById('tracker-character-uncap'); $('.tracker-box[id$="-characters"]').toggleClass('tracker-hide-uncap', !cb.checked); cb = document.getElementById('tracker-summon-uncap'); $('.tracker-box[id$="-summons"]').toggleClass('tracker-hide-uncap', !cb.checked); makeHash(); }
var starDivs = [];
function moveItems(div, type, element, rarity) { var tracker = document.getElementById(div); $('.tracker-item[data-type="'+type+'"][data-element="'+element+'"][data-rarity="'+rarity+'"]').each(function() { var node = this; node.dataset.owned = 'false'; node.dataset.evo = 0; if ($.isNumeric(node.dataset.baseevo) && $.isNumeric(node.dataset.maxevo)) { node.dataset.evo_base = parseInt(node.dataset.baseevo, 10); node.dataset.evo_max = parseInt(node.dataset.maxevo, 10); } else { node.dataset.evo_base = 0; node.dataset.evo_max = 0; } node.parentNode.removeChild(node); tracker.insertBefore(node, null);
var $uncap = $('
')
.addClass('tracker-uncap'); for (var i = 1; i <= node.dataset.evo_base; i++) {$uncap.append($('
')
.addClass('tracker-uncap-star') .addClass('tracker-uncap-base') ); } for (var i = node.dataset.evo_base+1; i <= node.dataset.evo_max; i++) {$uncap.append($('
')
.addClass('tracker-uncap-star') .addClass('tracker-uncap-max') ); } $(node).append($uncap); }); }
function getFilter(name) { var result = []; $('#tracker-filter-'+name+' > label.mw-ui-progressive').each(function() { if (this.dataset.value == '*') { result = true; } else { result.push(this.dataset.value); } }); return result; }
function updateItems() { console.time('updating'); var rarity = getFilter('rarity'); var type = getFilter('type'); var element = getFilter('element'); var obtain = getFilter('obtain'); var style = getFilter('style'); var race = getFilter('race'); var gender = getFilter('gender'); var maxevo = getFilter('maxevo'); var owned = getFilter('owned'); var search = $('#tracker-search').val(); var reSearch; try { reSearch = new RegExp('.*'+search+'.*','i'); } catch (e) { reSearch = new RegExp('.*'+search.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&")+'.*','i'); }
$('.tracker-item').each(function() { var visible = true; if ((rarity !== true) && (rarity.indexOf(this.dataset.rarity) === -1)) { visible = false; } else if ((type !== true) && (type.indexOf(this.dataset.type) === -1)) { visible = false; } else if ((element !== true) && (element.indexOf(this.dataset.element) === -1)) { visible = false; } else if ((style !== true) && (style.indexOf(this.dataset.style) === -1)) { visible = false; } else if ((race !== true) && (race.indexOf(this.dataset.race) === -1)) { visible = false; } else if ((gender !== true) && (gender.indexOf(this.dataset.gender) === -1)) { visible = false; } else if ((maxevo !== true) && (maxevo.indexOf(this.dataset.maxevo) === -1)) { visible = false; } else if ((owned !== true) && (owned.indexOf(this.dataset.owned) === -1)) { visible = false; } else if (obtain !== true) { visible = false; if ((obtain == 'other') && (otherSkip.indexOf(this.dataset.obtain) === -1)) visible = true else if ((obtain != 'other') && (obtain.indexOf(this.dataset.obtain) >= 0)) visible = true; } if (visible && (search.length > 0)) { visible = reSearch.test(this.dataset.id) || reSearch.test(this.dataset.name); } $(this).toggle(visible); }); $('.tracker-box').each(function() { $(this).show(); $(this).toggle($(this).children(':visible').length > 0); });
console.timeEnd('updating'); }
console.time('moving'); var elements = ['fire','water','earth','wind','light','dark','any']; var rarities = ['ssr','sr','r']; for (var ei = 0; ei < elements.length; ei++) { for (var ri = 0; ri < rarities.length; ri++) { var element = elements[ei]; var rarity = rarities[ri]; moveItems('tracker-'+element+'-characters', 'c', element, rarity); if (element != 'any') moveItems('tracker-'+element+'-summons', 's', element, rarity); } } console.timeEnd('moving');
$('.tracker-item').on('click', function(event) { event.preventDefault(); console.time('clickitem'); evolve(this, 1); makeHash(); console.timeEnd('clickitem'); });
$('.mw-ui-button-group > label').on('click', function(event) { console.time('clicklabel'); var group = this.parentNode; if (this.dataset.value == '*') { if (!$(this).hasClass('mw-ui-progressive')) { $(group).children('label').removeClass('mw-ui-progressive'); $(this).addClass('mw-ui-progressive'); } } else { $(group).children('label[data-value="*"]').removeClass('mw-ui-progressive'); $(this).toggleClass('mw-ui-progressive'); if ($(group).children('.mw-ui-progressive').length == 0) $(group).children('label[data-value="*"]').addClass('mw-ui-progressive'); } updateItems(); makeHash(); console.timeEnd('clicklabel'); });
$('#tracker-character-uncap').on('click', updateUncap); $('#tracker-summon-uncap').on('click', updateUncap);
$('#tracker-search').on('change', function() { updateItems(); }); $('#tracker-search').on('keyup', function() { updateItems(); });
readHash(); updateUncap(); updateItems(); })(jQuery);
</script>