[ Disclaimer, Create new user --- Wiki markup help, Install P99 ]
MediaWiki:LocMaps.js
From Project 1999 Wiki
Note: After saving, 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)
- Internet Explorer: Hold Ctrl while clicking Refresh, or press Ctrl-F5
- Opera: Clear the cache in Tools → Preferences
(function() {
var zones = {
'Ak\'Anon': {
height: 614,
image: 'Akanon.jpg',
interval: 250,
maxX: 250,
maxY: 2250,
minX: 1250,
minY: 250,
width: 384,
zeroX: 62,
zeroY: 567,
zoomX: 0.25,
zoomY: 0.25
},
// TODO: This duplicates the "Gorge of King Xorbb" entry; make an aliases array or something
'Beholder's Maze': {
height: 357,
image: 'Map_gxorbb.jpg',
maxX: 1000,
maxY: 1500,
minX: -2000,
minY: -1500,
interval: 500,
width: 400,
zeroX: 112.5,
zeroY: 173.5,
zoomX: 0.12545,
zoomY: 0.12545
},
'Butcherblock Mountains': {
height: 480,
image: 'Butcherblock-v3.jpg',
interval: 1000,
maxX: 3000,
maxY: 3000,
minX: 3000,
minY: 3000,
width: 500,
zeroX: 251,
zeroY: 240,
zoomX: .073,
zoomY: .0727
},
'East Commonlands': {
height: 279,
image: 'Map_eastcommons.jpg',
interval: 1000,
maxX: 5000,
maxY: 2000,
minX: 2000,
minY: 2000,
width: 642,
zeroX: 469.3,
zeroY: 133,
zoomX: 0.0887,
zoomY: 0.0887
},
'Eastern Plains of Karana': {
height: 554,
image: 'Map_ekarana.jpg',
interval: 1000,
maxX: 2000,
maxY: 2000,
minX: 4000,
minY: 5000,
width: 450,
zeroX: 119.5,
zeroY: 193,
zoomX: 0.0793,
zoomY: 0.0788
},
'Eastern Wastes': {
height: 452,
image: 'Map_eastern_wastes.jpg',
interval: 1000,
maxX: 7000,
maxY: 1000,
minX: 6000,
minY: 9000,
width: 550,
zeroX: 284,
zeroY: 62,
zoomX: 0.038,
zoomY: 0.038
},
'Erudin': {
height: 663,
image: 'Erudin.jpg',
interval: 100,
maxX: 0,
maxY: -600,
minX: -500,
minY: -1500,
width: 370,
zeroX: 29,
zeroY: -336,
zoomX: 0.63,
zoomY: 0.624
},
'Firiona Vie': {
height: 555,
image: 'Map_firionavie.jpg',
interval: 1000,
maxX: 6000,
maxY: 5000,
minX: 4000,
minY: 5000,
width: 540,
zeroX: 324,
zeroY: 282,
zoomX: 0.053,
zoomY: 0.0525
},
'Gorge of King Xorbb': {
height: 357,
image: 'Map_gxorbb.jpg',
maxX: 1000,
maxY: 1500,
minX: -2000,
minY: -1500,
interval: 500,
width: 400,
zeroX: 112.5,
zeroY: 173.5,
zoomX: 0.12545,
zoomY: 0.12545
},
'Greater Faydark': {
height: 532,
image: 'Greaterfaydark.jpg',
interval: 1000,
maxX: 3000,
maxY: 2000,
minX: 3000,
minY: 2000,
width: 550,
zeroX: 269,
zeroY: 255,
zoomX: .089,
zoomY: .089
},
'Grobb': {
height: 456,
image: 'Grobb.jpg',
interval: 200,
maxX: 200,
maxY: 600,
minX: 800,
minY: 200,
width: 550,
zeroX: 109,
zeroY: 341,
zoomX: 0.442,
zoomY: 0.439
},
'Halas': {
height: 434,
image: 'Zone_halas.jpg',
interval: 200,
maxX: 600,
maxY: 800,
minX: 600,
minY: 200,
width: 550,
zeroX: 252.2,
zeroY: 346,
zoomX: 0.458,
zoomY: 0.46
},
'Kerra Island': {
height: 504,
image: 'Kerra.jpg',
interval: 500,
maxX: 1000,
maxY: 1500,
minX: 1000,
minY: 1000,
width: 415,
zeroX: 146.5,
zeroY: 277,
zoomX: 0.238,
zoomY: 0.238
},
'Kithicor Forest': {
height: 333,
image: 'Map_kithicor.jpg',
interval: 1000,
maxX: 5000,
maxY: 3000,
minX: 1000,
minY: 2000,
width: 560,
zeroX: 449.5,
zeroY: 198,
zoomX: 0.0875,
zoomY: 0.089
},
'Lake Rathetear': {
height: 450,
image: 'Map_lakerathetear.jpg',
interval: 1000,
maxX: 3000,
maxY: 5000,
minX: 3000,
minY: 2000,
width: 450,
zeroX: 247.3,
zeroY: 342.4,
zoomX: 0.0755,
zoomY: 0.0755
},
'Nektulos Forest': {
height: 519,
image: 'Map_nektulos.jpg',
interval: 1000,
maxX: 2000,
maxY: 3000,
minX: 2000,
minY: 3000,
width: 271,
zeroX: 137.4,
zeroY: 264.8,
zoomX: 0.091,
zoomY: 0.091
},
'Northern Felwithe': {
height: 385,
image: 'Nfelwithe.jpg',
interval: 100,
maxX: 100,
maxY: 400,
minX: 800,
minY: 300,
width: 589,
zeroX: 109,
zeroY: 217,
zoomX: 0.547,
zoomY: 0.55
},
'Northern Karana': {
height: 476,
image: 'Map_nkarana.jpg',
interval: 1000,
maxX: 4000,
maxY: 2000,
minX: 3000,
minY: 5000,
width: 500,
zeroX: 263.3,
zeroY: 135.5,
zoomX: 0.071,
zoomY: 0.0705
},
'North Qeynos': {
height: 319,
image: 'Zone_nqeynos.jpg',
interval: 200,
maxX: 400,
maxY: 400,
minX: 600,
minY: 200,
width: 458,
zeroX: 204,
zeroY: 189,
zoomX: .39,
zoomY: .39
},
'Oggok': {
height: 440,
image: 'Oggok.jpg',
interval: 200,
maxX: 1000,
maxY: 800,
minX: 400,
minY: 400,
width: 536,
zeroX: 361,
zeroY: 305,
zoomX: .3155,
zoomY: .315
},
'Paineel': {
height: 520,
image: 'Paineelin.jpg',
interval: 100,
maxX: 1000,
maxY: 1400,
minX: 0,
minY: 400,
width: 492,
zeroX: 507,
zeroY: 716,
zoomX: 0.5215,
zoomY: 0.5212
},
'Qeynos Hills': {
height: 575,
image: 'Qeynoshills.jpg',
interval: 1000,
maxX: 2000,
maxY: 6000,
minX: 2000,
minY: 1000,
width: 324,
zeroX: 136,
zeroY: 516.3,
zoomX: 0.0945,
zoomY: 0.094
},
'Rathe Mountains': {
height: 660,
image: 'Zone_rathemtns.jpg',
interval: 1500,
maxX: 3000,
maxY: 7500,
minX: 4500,
minY: 3000,
width: 490,
zeroX: 219.5,
zeroY: 453.5,
zoomX: 0.0707,
zoomY: 0.0702
},
'Rivervale': {
height: 540,
image: 'Rivervale.jpg',
interval: 200,
maxX: 200,
maxY: 600,
minX: 800,
minY: 400,
width: 484,
zeroX: 85,
zeroY: 287,
zoomX: 0.522,
zoomY: 0.517
},
'South Kaladim': {
height: 341,
image: 'Skaladim.jpg',
interval: 100,
maxX: 600,
maxY: 500,
minX: -500,
minY: -200,
width: 550,
zeroX: 291,
zeroY: 238,
zoomX: 0.51,
zoomY: 0.52
},
'South Qeynos': {
height: 426,
image: 'Zone_sqeynos.jpg',
interval: 200,
maxX: 200,
maxY: 600,
minX: -600,
minY: -400,
width: 423,
zeroX: 107,
zeroY: 259,
zoomX: .395,
zoomY: .39,
},
'Southern Felwithe': {
height: 377,
image: 'Sfelwithe.jpg',
interval: 100,
maxX: 0,
maxY: 800,
minX: 900,
minY: 0,
width: 400,
zeroX: 155,
zeroY: 473,
zoomX: 0.58,
zoomY: 0.584
},
'Stonebrunt Mountains': {
height: 619,
image: 'Map_stonebrunt_mountains.jpg',
interval: 1000,
maxX: 4000,
maxY: 5000,
minX: 4000,
minY: 6000,
width: 529,
zeroX: 253.3,
zeroY: 285.5,
zoomX: 0.0578,
zoomY: 0.0576
},
'Surefall Glade': {
height: 539,
image: 'Surefallglade.jpg',
interval: 200,
maxX: 400,
maxY: 1000,
minX: 800,
minY: 800,
width: 330,
zeroX: 97,
zeroY: 306,
zoomX: 0.323,
zoomY: 0.32
},
'The Hole': {
height: 465,
image: 'Map_thehole.jpg',
interval: 200,
maxX: 1200,
maxY: 1200,
minX: 1200,
minY: 600,
width: 600,
zeroX: 292,
zeroY: 292,
zoomX: 0.261,
zoomY: 0.261
},
'The Overthere': {
height: 644,
image: 'Map_overthere.jpg',
interval: 1000,
maxX: 4000,
maxY: 4000,
minX: 4000,
minY: 4000,
width: 600,
zeroX: 284.5,
zeroY: 318,
zoomX: 0.0628,
zoomY: 0.0628
},
'The Warrens': {
height: 314,
image: 'Warrens.jpg',
interval: 200,
maxX: 1200,
maxY: 1200,
minX: 1200,
minY: 400,
width: 550,
zeroX: 263.9,
zeroY: 222.5,
zoomX: 0.2185,
zoomY: 0.22
},
'Toxxulia Forest': {
height: 537,
image: 'Toxxulia.jpg',
interval: 1000,
maxX: 3000,
maxY: 3000,
minX: 2000,
minY: 3000,
width: 441,
zeroX: 262.3,
zeroY: 261.5,
zoomX: 0.0915,
zoomY: 0.091
},
'Upper Guk': {
height: 644,
image: 'Upperguk.jpg',
interval: 250,
maxX: 750,
maxY: 1500,
minX: 500,
minY: 0,
width: 450,
zeroX: 234,
zeroY: 564,
zoomX: 0.324,
zoomY: 0.323
},
'West Commonlands': {
height: 284,
image: 'Zone_westcommons.jpg',
interval: 1000,
maxX: 5000,
maxY: 2000,
minX: 2000,
minY: 2000,
width: 649,
zeroX: 435.5,
zeroY: 126.5,
zoomX: 0.096,
zoomY: 0.096
},
'Western Plains of Karana': {
height: 422,
image: 'Zone_westkarana.jpg',
interval: 1000,
maxX: 0,
maxY: 2000,
minX: 17000,
minY: 5000,
width: 1058,
zeroX: 21.5,
zeroY: 107,
zoomX: 0.06375,
zoomY: 0.0641
}
};
/**
* This is the data for the alternate maps for zones. The code checks their min/max X/Y
* properties to see if the loc(s) fit within them, and if so the alternate map will be used
* instead.
*
* Since a zone can have multiple alternate maps each value in this object is an array.
*/
var alternates = {
'Erudin':{
height: 564,
image: 'Erudindocks.jpg',
interval: 100,
maxX: 300,
maxY: 200,
minX: -400,
minY: -400,
width: 450,
zeroX: 122,
zeroY: 223,
zoomX: 0.731,
zoomY: 0.731
},
'Greater Faydark': {
height: 519,
image: 'Kelethin.jpg',
interval: 200,
maxX: 1000,
minX: -700,
maxY: 1200,
minY: -800,
width: 442,
zeroX: 237,
zeroY: 312,
zoomX: 0.264,
zoomY: 0.264
}
}
var locIsWithinAlternateData = function(loc, alternateData) {
return loc.x < alternateData.maxX &&
loc.x > alternateData.minX &&
loc.y < alternateData.maxY &&
loc.y > alternateData.minY;
}
var getZoneData = function(zoneName, locs) {
var zoneData = zones[zoneName];
var zoneAlternates = alternates[zoneName];
if (!zoneAlternates) return zoneData;
// Handle no array case
if (!zoneAlternates.length) zoneAlternates = [zoneAlternates];
for (var i = 0; i < zoneAlternates.length; i++) {
var alternateData = zoneAlternates[i];
var allLocsAreWithin = true;
// wish I had ES6 [].every
$.each(locs, function(i, loc) {
allLocsAreWithin = allLocsAreWithin && locIsWithinAlternateData(loc, alternateData);
});
if (allLocsAreWithin) return alternateData;
};
return zoneData;
};
// Regex to separate out multiple locs from a single string
var locSeperationRegex = /(\(? *\+?\-?\d+, *\+?\-?\d+(?: ?, ?\+?\-?\d+)?\)?)/g;
// Regex to parse the individual y/x dimensions from a single loc string
var locParseRegex = /\(? *(\+?\-?\d+), *(\+?\-?\d+)\)?/;
/**
* Helper function for distinguishing locs (from other bits of text near locs)
*/
var isALoc = function(bit) {
// Changed criteria because http://wiki.project1999.com/Faelin_Bloodbriar had the loc text:
// Spawn point: 1515, 558
// no need for the code to be picky about parens
//return bit.includes('(') &&
// bit.includes(')') &&
// bit.includes(',')
return bit.includes(',');
};
/**
* Draws a red "X" on the map at the provided coordinate
*/
var makeX = function(x, y, zone) {
$('img[alt="' + zone.image + '"]')
.parent()
.css({position: 'absolute'})
.append(
$('<div class="x">x</div>')
.css({
color: 'red',
fontSize: '2em',
fontWeight: 'bold',
left: (zone.zeroX || 0) + x * -1 * (zone.zoomX || 0.1),
position: 'absolute',
top: (zone.zeroY || 0) + y * -1 * (zone.zoomY || 0.1)
}));
};
/**
* Adds a loc map to the page (presumably in response to a user
* mousing over a loc map link)
*/
var addMap = function($locTd, imageName, width, height) {
if ($('.map-wrapper').length) return;
$locTd.append(
'<div class="map-wrapper" style="position:relative">'+
'<img alt="' + imageName + '" ' +
'src="/images/'+ imageName + '" ' +
'width="' + width + '" ' +
'height="'+ height + '" ' +
'class="thumbborder" ' +
'title="' + imageName + '">' +
'</div>'
);
}
// Define two helper functions for building new zone definitions
// 1) Use this function to find the correct 0,0 point
window.testZeroZero = function(zone) {
var $locTd = $('b:contains("Location:")').parent();
$('.x').remove();
$('img[alt="' + zone.image + '"]').show()
addMap($locTd, zone.image, zone.width, zone.height);
makeX(0, 0, zone);
};
// 2) Use this function to generate a grid of alignment of X's
window.testGrid = function(zone) {
var $locTd = $('b:contains("Location:")').parent();
$('.x').remove();
for (var x = zone.maxX; x >= zone.minX; x -= zone.interval) {
for (var y = zone.maxY; y >= zone.minY; y -= zone.interval) {
addMap($locTd, zone.image, zone.width, zone.height);
makeX(x, y, zone);
}
};
}
try {
// Get the mob's loc(s)
var $locTd = $('b:contains("Location:")').parent();
var locs = $locTd.text()
.split(locSeperationRegex)
.filter(isALoc);
if (!locs.length) return;
var parsedLocs = [];
$.each(locs, function(i, locText) {
var match = locText.match(locParseRegex);
parsedLocs.push({x: parseFloat(match[2]), y: parseFloat(match[1]) });
});
// Find the zone name
var $zoneTd = $('b:contains("Zone:")').parent().text();
var zoneName = $zoneTd.split('Zone:')[1].trim();
// Do we have data for that zone's map?
var zone = getZoneData(zoneName, parsedLocs);
if (!zone) return; // If not, stop here
// Add the mouseover link
var $link = $(' <a href="#">(Show on Map)</a>');
// When it's moused-over, show the map
$link
.on('mouseover', function(e) {
addMap($locTd, zone.image, zone.width, zone.height);
$.each(parsedLocs, function(i, loc) {
makeX(loc.x, loc.y, zone);
});
})
.on('mouseleave', function(e) {
if (this.wasClicked) {
this.wasClicked = false;
} else {
$('.map-wrapper').remove();
}
return false;
})
.on('click', function(e) {
if ($(e.target).text() === '(Hide Map)') {
$(e.target).text('(Show on Map)')
$('.map-wrapper').remove();
} else {
$(e.target).text('(Hide Map)')
addMap($locTd, zone.image, zone.width, zone.height);
$.each(parsedLocs, function(i, loc) {
makeX(loc.x, loc.y, zone);
});
this.wasClicked = true;
}
return false;
});
$locTd.append($link)
} catch (err) {/* Didn't work, move on */}
})();