function Mapper(opt, noScroll) { $WH.cO(this, opt); if (this.parent && !this.parent.nodeName) this.parent = $WH.ge(this.parent); else if (!this.parent) return; var _; this.mouseX = this.mouseY = 0; this.editable = this.editable || false; this.overlay = this.overlay || false; if (this.editable) { this.zoomable = this.toggle = false; this.show = this.mouse = true; } else { this.zoomable = (this.zoomable == null ? true : this.zoomable); this.toggle = (this.toggle == null ? true : this.toggle); this.show = (this.show == null ? true : this.show); this.mouse = (this.mouse == null ? false : this.mouse); } this.buttons = (this.buttons == null ? true : this.buttons); this.zoneLink = (this.zoneLink == null ? true : this.zoneLink); /* aowow - disabled * if (location.href.indexOf('zone=') != -1) * this.zoneLink = false; */ this.zoom = (this.zoom == null ? 0 : this.zoom); this.zone = (this.zone == null ? 0 : this.zone); this.level = (this.level == null ? (Mapper.zoneDefaultLevel[this.zone] ? Mapper.zoneDefaultLevel[this.zone] : 0) : this.level); this.pins = []; this.nCoords = 0; this.tempWidth = null; this.tempHeight = null; this.parent.className = 'mapper'; this.parent.appendChild(this.span = $WH.ce('span')); _ = this.span.style; _.display = 'block'; _.position = 'relative'; $WH.ns(this.span); this.overlaySpan = _ = $WH.ce('div'); _.style.display = 'block'; _.style.width = '100%'; _.style.height = '100%'; this.span.appendChild(_); this.buttonDiv = _ = $WH.ce('div'); _.style.position = 'absolute'; _.style.top = _.style.right = '3px'; if (this.buttons) this.parent.appendChild(_); if (this.editable) { this.span.onmouseup = this.addPin.bind(this); _ = g_createGlow(LANG.mapper_tippin); _.style.fontSize = '11px'; _.style.position = 'absolute'; _.style.bottom = _.style.right = '0'; $WH.ns(_); this.parent.appendChild(_); } else { this.sToggle = _ = RedButton.create(LANG.mapper_hidepins, true, this.toggleShow.bind(this)); _.style['float'] = 'right'; _.style.display = 'none'; $WH.ns(_); this.buttonDiv.appendChild(_); } if (this.zoomable) { this.span.onclick = this.toggleZoom.bind(this); this.span.id = 'sjdhfkljawelis' + (this.unique !== undefined ? this.unique : ''); this.sZoom = _ = g_createGlow(LANG.mapper_tipzoom); _.style.fontSize = '11px'; _.style.position = 'absolute'; _.style.bottom = _.style.right = '0'; $WH.ns(_); this.span.appendChild(_); } this.sZoneLink = _ = g_createGlow(''); _.style.display = 'none'; _.style.position = 'absolute'; _.style.top = _.style.left = '0'; this.parent.appendChild(_); if (this.mouse) { this.parent.onmouseout = (function() { this.timeout = setTimeout((function() { this.sMouse.style.display = 'none'; }).bind(this), 1); }).bind(this); this.parent.onmouseover = (function() { clearTimeout(this.timeout); this.sMouse.style.display = ''; }).bind(this); this.span.onmousemove = this.span.onmousedown = this.getMousePos.bind(this); this.sMouse = _ = g_createGlow('(0.0, 0.0)'); _.style.display = 'none'; _.style.position = 'absolute'; _.style.bottom = _.style.left = '0'; _.onmouseup = $WH.sp; $WH.ns(_); this.span.appendChild(_); } this.floorPins = {}; if (opt.coords != null) this.setCoords(opt.coords); else if (opt.link != null) this.setLink(opt.link); if (opt.objectives) this.setObjectives(opt.objectives); if (opt.zoneparent && opt.zones) this.setZones(opt.zoneparent, opt.zones); this.updateMap(noScroll); }; Mapper.sizes = [ [ 488, 325, 'normal'], [ 772, 515, 'zoom'], [1002, 668, 'original'], [ 224, 149, 'small'] ]; Mapper.onlyOneFloor = { 4265: true, // Nexus 4264: true, // Halls of Stone 4416: true, // Gundrak 4415: true, // Violet Hold 4493: true, // Obsidian Sanctum 4500: true, // Eye of Eternity 4603: true, // Vault of Archavon 4723: true, // Trial of the Champion 4809: true, // The Forge of Souls 4813: true, // Pit of Saron 4820: true // Halls of Reflection }; Mapper.zoneLevelOffset = { // 4273: 0 // Ulduar // aowow - removed. why did this exist. what did i miss..? }; Mapper.zoneDefaultLevel = { 3456: 4, // Naxxramas 4812: 4 // Icecrown Citadel }; Mapper.remappedLevels = { 4273: { 6: 5 } }; Mapper.multiLevelZones = {}; Mapper.prototype = { getMap: function() { return this.parent }, update: function(opt, noScroll) { if (opt.zoom != null) this.zoom = opt.zoom; if (opt.zone != null) this.zone = opt.zone; if (opt.show != null) this.show = opt.show; this.pins = []; this.nCoords = 0; for (var i in this.floorPins) if (this.floorPins[i].parentNode) $WH.de(this.floorPins[i]); this.floorPins = {}; if (this.floorButton) { $WH.de(this.floorButton); this.floorButton = null; } var level = (opt.level === undefined ? 0 : this.fixLevel(parseInt(opt.level))); if (!opt.preservelevel) this.level = 0; else level = this.level; var mapperData = false; if ($WH.isset('g_mapperData')) mapperData = g_mapperData; else if ($WH.isset('g_mapper_data')) mapperData = g_mapper_data; if (mapperData && mapperData[this.zone] && !opt.coords) { var zone = mapperData[this.zone]; var maxCount = -1; for (var i in zone) { i = parseInt(i); var iLevel = this.fixLevel(i); if (opt.level === undefined && zone[i].count > maxCount) { level = parseInt(iLevel); maxCount = zone[i].count; } if (zone[i].coords) this.setCoords(zone[i].coords, iLevel); } this.level = level; if (this.floorPins[this.level]) $WH.ae(this.span, this.floorPins[this.level]); } else if (opt.coords != null) { var lowestLevel = 999; for (var i in opt.coords) { i = parseInt(i); var iLevel = this.fixLevel(i); this.setCoords(opt.coords[i], iLevel); if (iLevel < lowestLevel) lowestLevel = iLevel; } if (lowestLevel != 999 && !opt.preservelevel) this.level = lowestLevel; if (this.floorPins[this.level]) $WH.ae(this.span, this.floorPins[this.level]); } // this.setCoords(opt.coords); else if (opt.link != null) this.setLink(opt.link); this.updateMap(noScroll); }, fixLevel: function(level) { if (Mapper.zoneLevelOffset[this.zone] !== undefined) level += Mapper.zoneLevelOffset[this.zone]; else if (Mapper.multiLevelZones[this.zone] && level > 0) level += -1; else if (Mapper.multiLevelZones[this.zone] == undefined) level = 0; if (Mapper.remappedLevels[this.zone] && Mapper.remappedLevels[this.zone][level] !== undefined) level = Mapper.remappedLevels[this.zone][level]; return level; }, getZone: function() { return this.zone; }, setZone: function(zone, level, noScroll) { this.pins = []; this.nCoords = 0; if (this.floorPins[this.level]) $WH.de(this.floorPins[this.level]); this.floorPins = {}; if (this.floorButton) { $WH.de(this.floorButton); this.floorButton = null; } this.zone = zone; this.level = level | 0; this.updateMap(noScroll); return true; }, showFloors: function(event) { if (!Mapper.multiLevelZones[this.zone]) return; var menu = []; var _ = Mapper.multiLevelZones[this.zone]; var src = g_zone_areas; for (var i = 0; i < _.length; ++i) { var menuItem; if (!src[this.zone]) menuItem = [i, '[Level ' + (i + 1) + ']', this.setMap.bind(this, _[i], i, true)]; else menuItem = [i, src[this.zone][i], this.setMap.bind(this, _[i], i, true)]; if (i == this.level || (this.level === undefined && i == 0)) menuItem.checked = true; menu.push(menuItem); } Menu.showAtCursor(menu, event); }, setMap: function(map, level, forceUpdate) { if (level != this.level) { if (this.floorPins[this.level]) $WH.de(this.floorPins[this.level]); if (this.floorPins[level]) $WH.ae(this.span, this.floorPins[level]); this.level = level; } var type = Locale.getName(); this.span.style.background = 'url(' + g_staticUrl + '/images/wow/maps/' + type + '/' + Mapper.sizes[this.zoom][2] + '/' + map + '.jpg)'; if (this.overlay) this.overlaySpan.style.background = 'url(' + g_staticUrl + '/images/wow/maps/overlay/' + Mapper.sizes[this.zoom][2] + '/' + map + '.png)'; if (this.sZoneLink) { var zoneText = ''; var zoneId = parseInt(this.zone); var found = g_zones[zoneId] != null; var src = g_zone_areas; if (found) { if (this.zoneLink) zoneText += '' + g_zones[zoneId] + ''; if (Mapper.multiLevelZones[zoneId]) { if (this.zoneLink) zoneText += ': '; zoneText += (src[zoneId] ? src[zoneId][this.level] : 'Level ' + (this.level+1)); } g_setInnerHtml(this.sZoneLink, zoneText, 'div'); if (this.zoneLink) { for (var i = 0; i < 9; ++i) { if (i == 4) continue; this.sZoneLink.childNodes[i].firstChild.style.color = 'black'; } } } this.sZoneLink.style.display = found ? '' : 'none'; } if (forceUpdate) this.onMapUpdate && this.onMapUpdate(this); }, setObjectives: function(obj) { var startEnd = { start: 1, end: 1, startend: 1, sourcestart: 1, sourceend: 1 }; for (var z in obj) { var zone = obj[z]; if (g_mapperData[z] === undefined) g_mapperData[z] = {}; var objectiveIndex = {}; var nextIndex = 0; for (var l in zone.levels) { var level = zone.levels[l]; var results = ShowOnMap.combinePins(level); var pins = results[0]; g_mapperData[z][l] = { count: pins.length, coords: [] }; for (var i = 0; i < pins.length; ++i) { var tooltip = ShowOnMap.buildTooltip(pins[i].list); g_mapperData[z][l].coords.push([pins[i].coord[0], pins[i].coord[1], { type: tooltip[1], url: tooltip[2], menu: tooltip[3], label: tooltip[0] }]); } } } }, setZones: function(div, zones) { div = $('#' + div); if (!div || !zones || zones.length == 0 || !this.objectives) return; var zoneLinks = function(self, container, zoneList, zoneTypes) { var maxIdx = [false, -1]; for (var i = 0; i < zoneList.length; ++i) { if (i > 0) span.append(i == zoneList.length-1 ? LANG.and : LANG.comma); var entry = null; if (self.objectives[zoneList[i][0]].mappable > 0) { entry = $('', { href: 'javascript:;', text: self.objectives[zoneList[i][0]].zone }); entry.click(function(link, zone) { self.update({ zone: zone }); g_setSelectedLink(link, 'mapper'); }.bind(self, entry[0], zoneList[i][0])); entry.isLink = true; } else { entry = $('', { href: '?zone=' + zoneList[i][0], text: self.objectives[zoneList[i][0]].zone }); g_addTooltip(entry[0], LANG.tooltip_zonelink); } if (zones.length > 1) { var types = zoneTypes[zoneList[i][0]]; if (types.start && types.end) { entry.addClass('icontiny'); entry.css('background-image', 'url(' + g_staticUrl + '/images/wow/icons/tiny/quest_startend.gif)'); entry.css('padding-left', '20px'); } else if (types.start) { entry.addClass('icontiny'); entry.css('background-image', 'url(' + g_staticUrl + '/images/wow/icons/tiny/quest_start.gif)'); entry.css('padding-left', '14px'); } else if (types.end) { entry.addClass('icontiny'); entry.css('background-image', 'url(' + g_staticUrl + '/images/wow/icons/tiny/quest_end.gif)'); entry.css('padding-left', '16px'); } } container.append(entry); if (zoneList[i][1] > maxIdx[1]) maxIdx = [entry, zoneList[i][1]]; } return maxIdx[0]; }; var getZoneList = function(zoneList, zoneTypes, type) { var ret = []; for (var i = 0; i < zoneList.length; ++i) { if (zoneTypes[zoneList[i][0]][type]) ret.push(zoneList[i]); } return ret; }; var typesByZone = {}; var types = { start: [], end: [], objective: [] }; for (var zoneId in this.objectives) { if (typesByZone[zoneId] === undefined) typesByZone[zoneId] = {}; var zone = this.objectives[zoneId]; for (var levelNum in zone.levels) { var level = zone.levels[levelNum]; for (var i = 0; i < level.length; ++i) { if (level[i].point == 'start' || level[i].point == 'sourcestart') { types.start.push(zoneId); typesByZone[zoneId].start = true; } else if (level[i].point == 'end' || level[i].point == 'sourceend') { types.end.push(zoneId); typesByZone[zoneId].end = true; } else if (level[i].point == 'requirement' || level[i].point == 'sourcerequirement') { types.objective.push(zoneId); typesByZone[zoneId].objective = true; } } } } var h3 = $('
', { text: LANG.mapper_relevantlocs }); div.append(h3); if (zones.length == 1 && this.missing == 0) { var span = $('', { html: LANG.mapper_entiretyinzone.replace('$$', '' + this.objectives[zones[0][0]].zone + '.') }); div.append(span); this.update({ zone: zones[0][0] }); } else if (this.missing > 0) { var span = $(''); var primaryLink = false, secondaryLink = false, tertiaryLink = false; types.objective = $WH.array_unique(types.objective); types.start = $WH.array_unique(types.start); types.end = $WH.array_unique(types.end); var startEnd = types.start.length > 0 && $WH.array_compare(types.start, types.end); var startObj = types.start.length > 0 && $WH.array_compare(types.start, types.objective); var endObj = types.end.length > 0 && $WH.array_compare(types.end, types.objective); var objZones = getZoneList(zones, typesByZone, 'objective'); var startZones = getZoneList(zones, typesByZone, 'start'); var endZones = getZoneList(zones, typesByZone, 'end'); if (startEnd && startObj) // everything in the same zones { var parts = LANG.mapper_happensin.split('$$'); span.text(parts[0]); primaryLink = zoneLinks(this, span, zones, typesByZone); span.append(parts[1]); } else if (startEnd && types.objective.length == 0) // starts and ends in x { var parts = LANG.mapper_objectives.sex.split('$$'); span.text(parts[0]); primaryLink = zoneLinks(this, span, zones, typesByZone); span.append(parts[1]); } else if (startEnd) // objectives in x, starts and ends in y { var parts = LANG.mapper_objectives.ox_sey.split('$$'); span.text(parts[0]); primaryLink = zoneLinks(this, span, startZones, typesByZone); span.append(parts[1]); secondaryLink = zoneLinks(this, span, objZones, typesByZone); span.append(parts[2]); } else if (startObj && types.end.length == 0) // objectives and starts in x { var parts = LANG.mapper_objectives.osx.split('$$'); span.text(parts[0]); primaryLink = zoneLinks(this, span, zones, typesByZone); span.append(parts[1]); } else if (startObj) // objectives and starts in x, ends in y { var parts = LANG.mapper_objectives.osx_ey.split('$$'); span.text(parts[0]); primaryLink = zoneLinks(this, span, objZones, typesByZone); span.append(parts[1]); secondaryLink = zoneLinks(this, span, endZones, typesByZone); span.append(parts[2]); } else if (endObj && types.start.length == 0) // objectives and ends in x { var parts = LANG.mapper_objectives.oex.split('$$'); span.text(parts[0]); primaryLink = zoneLinks(this, span, zones, typesByZone); span.append(parts[1]); } else if (endObj) // objectives and ends in x, starts in y { var parts = LANG.mapper_objectives.oex_sy.split('$$'); span.text(parts[0]); primaryLink = zoneLinks(this, span, objZones, typesByZone); span.append(parts[1]); secondaryLink = zoneLinks(this, span, startZones, typesByZone); span.append(parts[2]); } else if (types.start.length > 0 && types.end.length > 0 && types.objective.length > 0) // objectives in x, starts in y, ends in z { var parts = LANG.mapper_objectives.ox_sy_ez.split('$$'); span.text(parts[0]); primaryLink = zoneLinks(this, span, startZones, typesByZone); span.append(parts[1]); secondaryLink = zoneLinks(this, span, objZones, typesByZone); span.append(parts[2]); tertiaryLink = zoneLinks(this, span, endZones, typesByZone); span.append(parts[3]); } else if (types.start.length > 0 && types.end.length > 0) // starts in x, ends in y { var parts = LANG.mapper_objectives.sx_ey.split('$$'); span.text(parts[0]); primaryLink = zoneLinks(this, span, startZones, typesByZone); span.append(parts[1]); secondaryLink = zoneLinks(this, span, endZones, typesByZone); span.append(parts[2]); } else if (types.start.length > 0 && types.objective.length > 0) // objectives in x, starts in y { var parts = LANG.mapper_objectives.ox_sy.split('$$'); span.text(parts[0]); primaryLink = zoneLinks(this, span, startZones, typesByZone); span.append(parts[1]); secondaryLink = zoneLinks(this, span, objZones, typesByZone); span.append(parts[2]); } else if (types.end.length > 0 && types.objective.length > 0) // objectives in x, ends in y { var parts = LANG.mapper_objectives.ox_ey.split('$$'); span.text(parts[0]); primaryLink = zoneLinks(this, span, objZones, typesByZone); span.append(parts[1]); secondaryLink = zoneLinks(this, span, endZones, typesByZone); span.append(parts[2]); } else if (types.start.length > 0) // starts in x { var parts = LANG.mapper_objectives.sx.split('$$'); span.text(parts[0]); primaryLink = zoneLinks(this, span, zones, typesByZone); span.append(parts[1]); } else if (types.end.length > 0) // ends in x { var parts = LANG.mapper_objectives.ex.split('$$'); span.text(parts[0]); primaryLink = zoneLinks(this, span, zones, typesByZone); span.append(parts[1]); } else if (types.objective.length > 0) // objectives in x { var parts = LANG.mapper_objectives.ox.split('$$'); span.text(parts[0]); primaryLink = zoneLinks(this, span, zones, typesByZone); span.append(parts[1]); } else // wat? { var parts = LANG.mapper_happensin.split('$$'); span.text(parts[0]); primaryLink = zoneLinks(this, span, zones, typesByZone); span.append(parts[1]); } div.append(span); if (primaryLink && primaryLink.isLink) primaryLink.click(); else if (secondaryLink && secondaryLink.isLink) secondaryLink.click(); else if (tertiaryLink && tertiaryLink.isLink) tertiaryLink.click(); } else { var parts = LANG.mapper_happensin.split('$$'); var span = $('', { text: parts[0] }); var primaryLink = zoneLinks(this, span, zones, typesByZone); span.append(parts[1]); div.append(span); if (primaryLink && primaryLink.isLink) primaryLink.click(); } }, setSize: function(w, h) { this.tempWidth = w; this.tempHeight = h; this.updateMap(true); }, getZoom: function() { return this.zoom; }, setZoom: function(zoom, noScroll) { this.zoom = zoom; this.tempWidth = this.tempHeight = null; this.updateMap(noScroll); }, toggleZoom: function(e) { this.zoom = 1 - this.zoom; this.updateMap(true); if (e) this.getMousePos(e); if (this.sZoom) { if (this.sZoom.style.display == 'none') this.sZoom.style.display = ''; else this.sZoom.style.display = 'none'; } /* aowow: check for e is custom as it should only affect the lightbox */ if (this.zoom && e === undefined) MapViewer.show({ mapper: this }); }, getShow: function() { return this.show; }, setShow: function(show) { this.show = show; var d = this.show ? '' : 'none'; for (var i in this.floorPins) this.floorPins[i].style.display = d; RedButton.setText(this.sToggle, (this.show ? LANG.mapper_hidepins : LANG.mapper_showpins)); }, toggleShow: function() { this.setShow(!this.show); }, getCoords: function() { var a = []; for (var i in this.pins) if (!this.pins[i].free) a.push([this.pins[i].x, this.pins[i].y]); return a; }, clearPins: function() { for (var i in this.pins) { this.pins[i].style.display = 'none'; this.pins[i].free = true; } }, setCoords: function(coords, coordsLevel) { var _; var level, noLevel; if (coordsLevel === undefined) { this.clearPins(); if (coords.length) // Backward compatibility { noLevel = true; level = 0; } else { for (var i in coords) { level = i; break; } if (level == null) return; coords = coords[level]; } level = parseInt(level); if (!noLevel) { level = this.fixLevel(level); this.level = level; } } else { level = coordsLevel; } this.nCoords = coords.length; for (var i in coords) { var coord = coords[i], opt = coord[2]; if (coord[0] === undefined || coord[1] === undefined) continue; _ = this.getPin(level); _.x = coord[0]; _.y = coord[1]; _.style.left = _.x + '%'; _.style.top = _.y + '%'; if (this.editable) _.a.onmouseup = this.delPin.bind(this, _); else if (opt && opt.url) { _.a.href = Markup._fixUrl(opt.url); _.a.rel = "np"; _.a.style.cursor = 'pointer'; } if (opt && opt.tooltip) { _.a.tt = ''; var printedFooter = false; for (var name in opt.tooltip) { if (_.a.tt != '') _.a.tt += '