Widget:SpawnMap

RLQ.push(['jquery', function {

var isFandomMobile = document.body.classList.contains('skin-fandommobile');

var id = ''; var pointSize = parseInt(''); var $select = $(' ') .append($(' ').val('').text('Select a creature')) .change(function {    showGroups($(this).val);  });

var names = []; spawnData.forEach(function (group) { group.e.forEach(function (entry) { entry.s.forEach(function (spawn) {     if (names.indexOf(spawn.n) == -1) {        names.push(spawn.n);      }      if (translations[spawn.n] && names.indexOf(translations[spawn.n]) == -1) {        names.push(translations[spawn.n]);      }    }); }); }); names.sort.forEach(function (name) { $select.append($(' ').text(name)); }); $('.legend-container.' + id).append($select);

var urlHash = decodeURIComponent(window.location.hash); if (urlHash) { $select.val(urlHash.substr(1)); $select.change; }

function formatPercent(v, precision, threshold) { v = (v * 100).toFixed(precision); if (v < threshold) { return '<' + threshold + '%'; }	return v + '%'; }

function showGroups(name) { var $mapContainer = $('#map-' + id).find('.map-container'); var $legendContainer = $('.legend-container.' + id);

// clear the map $mapContainer.children('.spawn-group').remove; $legendContainer.find('.groups-legend').remove; $legendContainer.find('.details-toggle').remove; if (!name) return; // get the second creature's name if exists var name2 = null; if (translations[name]) { // translation for a name exists? name2 = translations[name]; } else { // name is a translation? Object.keys(translations).forEach(function (key) {     if (translations[key] == name) {        name2 = key;      }    }); }

// filter the groups with the creature var groups = spawnData.filter(function (group) {   var include = false;    group.e.forEach(function (entry) { entry.s.forEach(function (spawn) {       if (spawn.n == name || spawn.n == name2) {          include = true;        }      }); });   return include;  });

// draw spawn areas or points to the map var $mapImg = isFandomMobile ? $mapContainer.find('img.resourcemap') : $mapContainer.children.last; var offsetTop = parseFloat($mapContainer.data('bordertop')); var offsetLeft = parseFloat($mapContainer.data('borderleft')); var offsetRight = parseFloat($mapContainer.data('borderright')); var offsetBottom = parseFloat($mapContainer.data('borderbottom')); var imgWidth = $mapImg.prop('width'); var imgHeight = $mapImg.prop('height'); var mapWidth = offsetRight - offsetLeft; var mapHeight = offsetBottom - offsetTop;

var spawnProbabilities = {};

// show groups info/legend if (groups.length) { $detailsToggle = $('').append($(' ').click(function { if (this.checked) { $groupsLegend.find('li.is-detail').show; } else { $groupsLegend.find('li.is-detail').hide; }   })).append(' full spawn groups details'); $legendContainer.append($detailsToggle);

var $groupsLegend = $(''); groups.forEach(function (group) {     var $group = $('')        .append($(' ') .append($('').val(group.n)           .change(function  { var $this = $(this); var $mapGroup = $('#group-' + $this.val); var $legendGroup = $this.closest('li').find('ul'); if ($this.prop('checked')) { $mapGroup.show; $legendGroup.show; } else { $mapGroup.hide; $legendGroup.hide; }           }))          .append(' ' + group.n.replace(/DinoSpawnEntries_?|SpawnEntries_?/i, '')));      $groupsLegend.append($group);      var $groupEntries = $('');      $group.append($groupEntries);

var spawnProbability = 0; group.e.forEach(function (entry) {       var hasName = entry.s.find(function (npc) { return npc.n == name || npc.n == name2; });       var $entry = $('').text(entry.n + ': ' + formatPercent(entry.c, 1, 0.1));        if (!hasName) {          $entry.addClass('is-detail');        }        $groupEntries.append($entry);        var $npcs = $('');        $entry.append($npcs);

entry.s.forEach(function (npc) {         var classProbability = npc.c <= -0.99 ? 1 : npc.c;          var $npc = $('').text(npc.n + ': ' + formatPercent(classProbability, classProbability <= 0.1 ? 1 : 0, 0.1));          $npcs.append($npc);          if (npc.n == name || npc.n == name2) {            spawnProbability += classProbability * entry.c;          }        }); });     spawnProbabilities[group.n] = spawnProbability;    });

$groupsLegend.find('li.is-detail').hide; // hide details by default $legendContainer.append($groupsLegend); }

var cssRarityClasses = ['cr-region-map-very-rare', 'cr-region-map-rare', 'cr-region-map-very-uncommon', 'cr-region-map-uncommon', 'cr-region-map-common', 'cr-region-map-very-common'];

groups.forEach(function (group) {   var $group = $(' ').attr('id', 'group-' + group.n);    group.s.forEach(function (spawn) { var spawnAmount = (spawnProbabilities[group.n] ? spawnProbabilities[group.n] : 0) * spawn.f;     spawn.p.forEach(function (point) {        var spawnRarity = Math.min(5, Math.round(1.5 * (Math.log(1 + 2 * spawnAmount))));        var rarityClass = cssRarityClasses[spawnRarity];        $group.append($(' ').addClass('dot point ' + rarityClass) .css({left: Math.max(0, 100 * ((point.x - offsetLeft) / mapWidth - pointSize / (2 * mapWidth))).toFixed(1) + '%',                           top: Math.max(0, 100 * ((point.y - offsetTop) / mapHeight - pointSize / (2 * mapWidth))).toFixed(1) + '%'}) .prop('title', 'lat ' + point.y + ', lon ' + point.x + (spawn.u ? '\nuntameable' : '')));     }); spawn.l.forEach(function (location) {       var spawnRarity = Math.min(5, Math.round(1.5 * (Math.log(1 + 2 * spawnAmount * 16 / ((location.x2 - location.x1) * (location.y2 - location.y1))))));        var rarityClass = cssRarityClasses[spawnRarity];        var widthAdjust = (location.x2 - location.x1) / mapWidth < 0.01 ? 0.5 : 0;        var heightAdjust = (location.y2 - location.y1) / mapHeight < 0.01 ? 0.5 : 0;        $group.append($(' ').addClass('square ' + rarityClass + (spawn.u ? ' untameable' : '')) .css({left: Math.max(0, 100 * (location.x1 - offsetLeft) / mapWidth - widthAdjust).toFixed(1) + '%',           top: Math.max(0, 100 * (location.y1 - offsetTop) / mapHeight - heightAdjust).toFixed(1) + '%',            bottom: Math.min(100, 100 * (100 - location.y2 - (100 - offsetBottom)) / mapHeight - heightAdjust).toFixed(1) + '%',            right: Math.min(100, 100 * (100 - location.x2 - (100 - offsetRight)) / mapWidth - widthAdjust).toFixed(1) + '%'}) .prop('title', 'from lat ' + location.y1 + ', lon ' + location.x1 + '\nto lat ' + location.y2 + ', lon ' + location.x2 + (spawn.u ? '\nuntameable' : '')) );     });    });    $mapImg.before($group);  }); }; }]);

// polyfill for IE from https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/find if (!Array.prototype.find) { Object.defineProperty(Array.prototype, 'find', {   value: function(predicate) {      if (this == null) {        throw new TypeError('"this" is null or not defined');      }      var o = Object(this);      var len = o.length >>> 0;      if (typeof predicate !== 'function') {        throw new TypeError('predicate must be a function');      }      var thisArg = arguments[1];      var k = 0;      while (k < len) {        var kValue = o[k];        if (predicate.call(thisArg, kValue, k, o)) {          return kValue;        }        k++;      }      return undefined;    }  }); }