diff --git a/datasets/zones b/datasets/zones index 13f26c15..e6766d53 100644 --- a/datasets/zones +++ b/datasets/zones @@ -37,7 +37,6 @@ Mapper.multiLevelZones = { 4494: ['4494-1', '4494-2'], 4714: ['4714-1', '4714_1', '4714_2', '4714_3'], 4722: ['4722-1', '4722-2'], - 4723: ['4723-1', '4723-2'], 4812: ['4812-1', '4812-2', '4812-3', '4812-4', '4812-5', '4812-6', '4812-7', '4812-8'], }; diff --git a/includes/types/basetype.class.php b/includes/types/basetype.class.php index 9ff5aa22..fd83f47c 100644 --- a/includes/types/basetype.class.php +++ b/includes/types/basetype.class.php @@ -517,18 +517,28 @@ trait spawnHelper ); /* - todo (med): implement this alpha-map-check-virtual-map-transform-wahey! - note: map in tooltips is activated by either '#map' as anchor (will automatic open mapviewer, when clicking link) in the href or as parameterless rel-parameter e.g. rel="map" in the anchor + todo (med): map in tooltips is activated by either '#map' as anchor (will automatic open mapviewer, when hovering link) in the href or as parameterless rel-parameter e.g. rel="map" in the anchor */ - private function createShortSpawns() // [zoneId, [[x1, y1], [x2, y2], ..]] as tooltip2 if enabled by (one area, one floor, one craeture, no survivor) + private function createShortSpawns() // [zoneId, floor, [[x1, y1], [x2, y2], ..]] as tooltip2 if enabled by (one area, one floor, one creature, no survivor) { - $this->spawnResult[SPAWNINFO_SHORT] = null; // NYI + // first get zone/floor with the most spawns + if ($res = DB::Aowow()->selectRow('SELECT areaId, floor FROM ?_spawns WHERE type = ?d && typeId = ?d GROUP BY areaId, floor ORDER BY count(1) DESC LIMIT 1', self::$type, $this->id)) + { + // get relevant spawn points + $points = DB::Aowow()->select('SELECT posX, posY FROM ?_spawns WHERE type = ?d && typeId = ?d && areaId = ?d && floor = ?d', self::$type, $this->id, $res['areaId'], $res['floor']); + $spawns = []; + foreach ($points as $p) + $spawns[] = [$p['posX'], $p['posY']]; + + $this->spawnResult[SPAWNINFO_SHORT] = [$res['areaId'], $res['floor'], $spawns]; + } } private function createFullSpawns() // for display on map (objsct/npc detail page) { $data = []; + $wpSum = []; $wpIdx = 0; $spawns = DB::Aowow()->select("SELECT * FROM ?_spawns WHERE type = ?d AND typeId = ?d", self::$type, $this->id); if (!$spawns) @@ -556,6 +566,7 @@ trait spawnHelper $set['lines'] = [[$wPoints[$i - 1]['posX'], $wPoints[$i - 1]['posY']]]; $data[$s['areaId']][$s['floor']]['coords'][] = [$p['posX'], $p['posY'], $set]; + @$wpSum[$s['areaId']][$s['floor']]++; } $wpIdx++; } @@ -589,6 +600,9 @@ trait spawnHelper $data[$s['areaId']] [$s['floor']] ['coords'] [] = [$s['posX'], $s['posY'], ['label' => '$
'.implode('
', $label).'
']]; } + foreach ($data as $a => &$areas) + foreach ($areas as $f => &$floor) + $floor['count'] = count($floor['coords']) - (!empty($wpSum[$a][$f]) ? $wpSum[$a][$f] : 0); $this->spawnResult[SPAWNINFO_FULL] = $data; } @@ -609,7 +623,7 @@ trait spawnHelper public function getSpawns($mode) { // ony Creatures and GOs can be spawned - if (!self::$type && self::$type != TYPE_NPC && self::$type != TYPE_OBJECT) + if (!self::$type || (self::$type != TYPE_NPC && self::$type != TYPE_OBJECT)) return []; switch ($mode) @@ -833,15 +847,15 @@ abstract class Filter { case 'setCriteria': if ($data || $raw) - $form[$name] = $raw ? $data : 'fi_setCriteria('.json_encode($data['cr'], JSON_NUMERIC_CHECK).', '.json_encode($data['crs'], JSON_NUMERIC_CHECK).', '.json_encode($data['crv'], JSON_NUMERIC_CHECK).');'; + $form[$name] = $raw ? $data : 'fi_setCriteria('.Util::toJSON($data['cr']).', '.Util::toJSON($data['crs']).', '.Util::toJSON($data['crv']).');'; else $form[$name] = 'fi_setCriteria([], [], []);'; break; case 'extraCols': - $form[$name] = $raw ? $data : 'fi_extraCols = '.json_encode(array_unique($data), JSON_NUMERIC_CHECK).';'; + $form[$name] = $raw ? $data : 'fi_extraCols = '.Util::toJSON(array_unique($data)).';'; break; case 'setWeights': - $form[$name] = $raw ? $data : 'fi_setWeights('.json_encode($data, JSON_NUMERIC_CHECK).', 0, 1, 1);'; + $form[$name] = $raw ? $data : 'fi_setWeights('.Util::toJSON($data).', 0, 1, 1);'; break; case 'form': if ($key == $name) // only if explicitely specified diff --git a/includes/utilities.php b/includes/utilities.php index c239d8fd..db0c5261 100644 --- a/includes/utilities.php +++ b/includes/utilities.php @@ -927,8 +927,12 @@ class Util '

' => '
' ); - // html may contain 'Pictures' - $text = preg_replace('/"Interface\\\Pictures\\\([\w_\-]+)"/i', '"images/wow/interface/Pictures/\1.jpg"', strtr($text, $pairs)); + // html may contain 'Pictures' and FlavorImages and "stuff" + $text = preg_replace_callback( + '/src="([^"]+)"/i', + function ($m) { return 'src="'.STATIC_URL.'/images/wow/'.strtr($m[1], ['\\' => '/']).'.png"'; }, + strtr($text, $pairs) + ); } else $text = strtr($text, ["\n" => '
', "\r" => '']); @@ -1724,6 +1728,19 @@ class Util header('Cache-Control: post-check=0, pre-check=0', false); header('Pragma: no-cache'); } + + public static function toJSON($data) + { + $flags = JSON_NUMERIC_CHECK | JSON_UNESCAPED_UNICODE; + + if (CFG_DEBUG) + $flags |= JSON_PRETTY_PRINT; + + // just a thought: .. about prefixing variables with $ to mark them as function code and retroactively stripping escapes from them + // like it's done already in with listviews for example + + return json_encode($data, $flags); + } } ?> diff --git a/pages/currency.php b/pages/currency.php index 7a3077c5..10e8f8da 100644 --- a/pages/currency.php +++ b/pages/currency.php @@ -90,7 +90,7 @@ class CurrencyPage extends GenericPage 'id' => $tab[3], 'extraCols' => $tab[4] ? '$['.implode(', ', array_unique($tab[4])).']' : null, 'hiddenCols' => $tab[5] ? '$['.implode(', ', array_unique($tab[5])).']' : null, - 'visibleCols' => $tab[6] ? '$'. json_encode( array_unique($tab[6])) : null + 'visibleCols' => $tab[6] ? '$'. Util::toJSON( array_unique($tab[6])) : null ] ); } @@ -173,7 +173,7 @@ class CurrencyPage extends GenericPage 'params' => [ 'name' => '$LANG.tab_createdby', 'id' => 'created-by', - 'visibleCols' => isset($visCols) ? '$'.json_encode($visCols) : null + 'visibleCols' => isset($visCols) ? '$'.Util::toJSON($visCols) : null ] ); } diff --git a/pages/genericPage.class.php b/pages/genericPage.class.php index 1b25d762..aacc197c 100644 --- a/pages/genericPage.class.php +++ b/pages/genericPage.class.php @@ -450,7 +450,7 @@ class GenericPage } } - $buff .= ' _['.(is_numeric($key) ? $key : "'".$key."'")."]=".json_encode($data, JSON_NUMERIC_CHECK).';'; + $buff .= ' _['.(is_numeric($key) ? $key : "'".$key."'")."]=".Util::toJSON($data).';'; } $buff .= "\n"; @@ -461,13 +461,13 @@ class GenericPage // spell if (!empty($x['tooltip'])) // spell + item - $buff .= "\n _[".$x['id'].'].tooltip_'.User::$localeString.' = '.json_encode($x['tooltip']).";\n"; + $buff .= "\n _[".$x['id'].'].tooltip_'.User::$localeString.' = '.Util::toJSON($x['tooltip']).";\n"; if (!empty($x['buff'])) // spell - $buff .= " _[".$x['id'].'].buff_'.User::$localeString.' = '.json_encode($x['buff']).";\n"; + $buff .= " _[".$x['id'].'].buff_'.User::$localeString.' = '.Util::toJSON($x['buff']).";\n"; if (!empty($x['spells'])) // spell + item - $buff .= " _[".$x['id'].'].spells_'.User::$localeString.' = '.json_encode($x['spells'], JSON_NUMERIC_CHECK).";\n"; + $buff .= " _[".$x['id'].'].spells_'.User::$localeString.' = '.Util::toJSON($x['spells']).";\n"; if (!empty($x['buffspells'])) // spell - $buff .= " _[".$x['id'].'].buffspells_'.User::$localeString.' = '.json_encode($x['buffspells'], JSON_NUMERIC_CHECK).";\n"; + $buff .= " _[".$x['id'].'].buffspells_'.User::$localeString.' = '.Util::toJSON($x['buffspells']).";\n"; $buff .= "\n"; } diff --git a/pages/item.php b/pages/item.php index c897fa6f..296b56b0 100644 --- a/pages/item.php +++ b/pages/item.php @@ -419,7 +419,7 @@ class ItemPage extends genericPage 'id' => $tab[3], 'extraCols' => $tab[4] ? '$['.implode(', ', array_unique($tab[4])).']' : null, 'hiddenCols' => $tab[5] ? '$['.implode(', ', array_unique($tab[5])).']' : null, - 'visibleCols' => $tab[6] ? '$'. json_encode( array_unique($tab[6])) : null + 'visibleCols' => $tab[6] ? '$'. Util::toJSON( array_unique($tab[6])) : null ] ); } @@ -478,8 +478,8 @@ class ItemPage extends genericPage 'name' => $sf[2], 'id' => $sf[3], 'extraCols' => $sf[4] ? "$[".implode(', ', array_unique($sf[4]))."]" : null, - 'hiddenCols' => $sf[5] ? "$".json_encode($sf[5]) : null, - 'visibleCols' => $sf[6] ? '$'.json_encode($sf[6]) : null + 'hiddenCols' => $sf[5] ? "$".Util::toJSON($sf[5]) : null, + 'visibleCols' => $sf[6] ? '$'.Util::toJSON($sf[6]) : null ] ); } @@ -527,7 +527,7 @@ class ItemPage extends genericPage 'params' => [ 'name' => '$LANG.tab_cancontain', 'id' => 'can-contain', - 'hiddenCols' => '$'.json_encode($hCols) + 'hiddenCols' => '$'.Util::toJSON($hCols) ] ); } @@ -575,7 +575,7 @@ class ItemPage extends genericPage 'name' => '$LANG.tab_criteriaof', 'id' => 'criteria-of', 'visibleCols' => "$['category']", - 'hiddenCols' => '$'.json_encode($hCols) + 'hiddenCols' => '$'.Util::toJSON($hCols) ] ); } @@ -909,7 +909,7 @@ class ItemPage extends genericPage 'params' => [ 'name' => '$LANG.tab_teaches', 'id' => 'teaches', - 'visibleCols' => '$'.json_encode($visCols) + 'visibleCols' => '$'.Util::toJSON($visCols) ] ); } diff --git a/pages/items.php b/pages/items.php index 008a9c2e..771e5b33 100644 --- a/pages/items.php +++ b/pages/items.php @@ -325,12 +325,12 @@ class ItemsPage extends GenericPage $tab['data'][$uId] = $upgItemData[$uId]; if ($upg) - $tab['params']['_upgradeIds'] = '$'.json_encode($upg, JSON_NUMERIC_CHECK); + $tab['params']['_upgradeIds'] = '$'.Util::toJSON($upg); } else if ($grouping) { $upg = array_keys($this->filter['upg']); - $tab['params']['_upgradeIds'] = '$'.json_encode($upg, JSON_NUMERIC_CHECK); + $tab['params']['_upgradeIds'] = '$'.Util::toJSON($upg); foreach ($upgItemData as $uId => $data) // using numeric keys => cant use array_merge $tab['data'][$uId] = $data; } @@ -400,10 +400,10 @@ class ItemsPage extends GenericPage } if (!empty($tab['params']['hiddenCols'])) - $tab['params']['hiddenCols'] = '$'.json_encode($tab['params']['hiddenCols']); + $tab['params']['hiddenCols'] = '$'.Util::toJSON($tab['params']['hiddenCols']); if (!empty($tab['params']['visibleCols'])) - $tab['params']['visibleCols'] = '$'.json_encode($tab['params']['visibleCols']); + $tab['params']['visibleCols'] = '$'.Util::toJSON($tab['params']['visibleCols']); foreach ($tab['params'] as $k => $p) if (!$p) diff --git a/pages/itemset.php b/pages/itemset.php index 14ca4290..0192b339 100644 --- a/pages/itemset.php +++ b/pages/itemset.php @@ -72,7 +72,7 @@ class ItemsetPage extends GenericPage if ($h = $this->subject->getField('holidayId')) { $infobox[] = Lang::$game['eventShort'].Lang::$main['colon'].'[event='.$h.']'; - $this->extendGlobalIds(TYPE_GAMEVENT, $h); + $this->extendGlobalIds(TYPE_WORLDEVENT, $h); } // itemLevel diff --git a/pages/maps.php b/pages/maps.php index 74ffee2d..c2d11ea6 100644 --- a/pages/maps.php +++ b/pages/maps.php @@ -11,14 +11,8 @@ class MapsPage extends GenericPage protected $tabId = 1; protected $path = [1, 1]; protected $mode = CACHE_TYPE_NONE; - protected $js = array( - 'maps.js', - 'Mapper.js' - ); - protected $css = array( - ['string' => 'zone-picker { margin-left: 4px }'], - ['path' => 'Mapper.css'] - ); + protected $js = ['maps.js']; + protected $css = [['string' => 'zone-picker { margin-left: 4px }']]; public function __construct($pageCall, $__) { diff --git a/pages/npc.php b/pages/npc.php index 5155e6ad..5e21277c 100644 --- a/pages/npc.php +++ b/pages/npc.php @@ -16,13 +16,7 @@ class NpcPage extends GenericPage protected $path = [0, 4]; protected $tabId = 0; protected $mode = CACHE_TYPE_PAGE; - protected $js = array( - 'swfobject.js', - 'Mapper.js' - ); - protected $css = array( - ['path' => 'Mapper.css'] - ); + protected $js = ['swfobject.js']; public function __construct($pageCall, $id) { @@ -264,13 +258,8 @@ class NpcPage extends GenericPage if ($spawns = $this->subject->getSpawns(SPAWNINFO_FULL)) { $map = ['data' => ['parent' => 'mapper-generic'], 'mapperData' => &$spawns]; - foreach ($spawns as $areaId => &$areaData) - { $map['extra'][$areaId] = ZoneList::getName($areaId); - foreach ($areaData as &$floor) - $floor['count'] = count($floor['coords']); - } } // consider pooled spawns @@ -585,8 +574,8 @@ class NpcPage extends GenericPage 'name' => $sf[2], 'id' => $sf[3], 'extraCols' => $sf[4] ? "$[".implode(', ', array_unique($sf[4]))."]" : null, - 'hiddenCols' => $sf[5] ? "$".json_encode($sf[5]) : null, - 'visibleCols' => $sf[6] ? '$'.json_encode($sf[6]) : null, + 'hiddenCols' => $sf[5] ? "$".Util::toJSON($sf[5]) : null, + 'visibleCols' => $sf[6] ? '$'.Util::toJSON($sf[6]) : null, 'sort' => "$['-percent', 'name']", ) ); @@ -741,12 +730,12 @@ class NpcPage extends GenericPage if ($asError) return '$WowheadPower.registerNpc('.$this->typeId.', '.User::$localeId.', {})'; - $s = $this->subject->getSpawns(true); + $s = $this->subject->getSpawns(SPAWNINFO_SHORT); $x = '$WowheadPower.registerNpc('.$this->typeId.', '.User::$localeId.", {\n"; $x .= "\tname_".User::$localeString.": '".Util::jsEscape($this->subject->getField('name', true))."',\n"; $x .= "\ttooltip_".User::$localeString.": '".Util::jsEscape($this->subject->renderTooltip())."',\n"; - // $x .= "\tmap: ".($s ? '{zone: '.$s[0].', coords: {0:'.json_encode($s[1], JSON_NUMERIC_CHECK).'}}' : '{}')."\n"; + $x .= "\tmap: ".($s ? Util::toJSON(['zone' => $s[0], 'coords' => [$s[1] => $s[2]]]) : '{}')."\n"; $x .= "});"; return $x; diff --git a/pages/object.php b/pages/object.php index 18a2b94a..14f3dd81 100644 --- a/pages/object.php +++ b/pages/object.php @@ -16,13 +16,7 @@ class ObjectPage extends GenericPage protected $path = [0, 5]; protected $tabId = 0; protected $mode = CACHE_TYPE_PAGE; - protected $js = array( - 'swfobject.js', - 'Mapper.js' - ); - protected $css = array( - ['path' => 'Mapper.css'] - ); + protected $js = ['swfobject.js']; /* NOTE @@ -226,13 +220,8 @@ class ObjectPage extends GenericPage if ($spawns = $this->subject->getSpawns(SPAWNINFO_FULL)) { $map = ['data' => ['parent' => 'mapper-generic'], 'mapperData' => &$spawns]; - foreach ($spawns as $areaId => &$areaData) - { $map['extra'][$areaId] = ZoneList::getName($areaId); - foreach ($areaData as &$floor) - $floor['count'] = count($floor['coords']); - } } // consider pooled spawns @@ -415,7 +404,7 @@ class ObjectPage extends GenericPage 'name' => '$LANG.tab_contains', 'id' => 'contains', 'extraCols' => "$[".implode(', ', array_unique($extraCols))."]", - 'hiddenCols' => $hiddenCols ? '$'.json_encode(array_values($hiddenCols)) : null + 'hiddenCols' => $hiddenCols ? '$'.Util::toJSON(array_values($hiddenCols)) : null ) ); } @@ -467,12 +456,12 @@ class ObjectPage extends GenericPage if ($asError) return '$WowheadPower.registerObject('.$this->typeId.', '.User::$localeId.', {});'; - $s = $this->subject->getSpawns(true); + $s = $this->subject->getSpawns(SPAWNINFO_SHORT); $x = '$WowheadPower.registerObject('.$this->typeId.', '.User::$localeId.", {\n"; $x .= "\tname_".User::$localeString.": '".Util::jsEscape($this->subject->getField('name', true))."',\n"; $x .= "\ttooltip_".User::$localeString.": '".Util::jsEscape($this->subject->renderTooltip())."'\n"; - // $x .= "\tmap: ".($s ? '{zone: '.$s[0].', coords: {0:'.json_encode($s[1], JSON_NUMERIC_CHECK).'}' : '{}')."\n"; + $x .= "\tmap: ".($s ? Util::toJSON(['zone' => $s[0], 'coords' => [$s[1] => $s[2]]]) : '{}')."\n"; $x .= "});"; return $x; diff --git a/pages/quest.php b/pages/quest.php index bfb56e42..0f49b146 100644 --- a/pages/quest.php +++ b/pages/quest.php @@ -16,11 +16,7 @@ class QuestPage extends GenericPage protected $path = [0, 3]; protected $tabId = 0; protected $mode = CACHE_TYPE_PAGE; - protected $js = ['Mapper.js']; - protected $css = array( - ['path' => 'Book.css'], - ['path' => 'Mapper.css'] - ); + protected $css = [['path' => 'Book.css']]; public function __construct($pageCall, $id) { @@ -525,7 +521,7 @@ class QuestPage extends GenericPage $this->map = null; // array( // 'data' => ['zone' => $this->typeId], - // 'som' => json_encode($som, JSON_NUMERIC_CHECK) + // 'som' => Util::toJSON($som) // ); /****************/ @@ -622,7 +618,7 @@ class QuestPage extends GenericPage if ($cnd) { $tab = ""; diff --git a/pages/search.php b/pages/search.php index 24b061ac..ab1827e8 100644 --- a/pages/search.php +++ b/pages/search.php @@ -253,7 +253,7 @@ class SearchPage extends GenericPage { $items = []; foreach ($itemData as $k => $v) - $items[] = json_encode($v, JSON_NUMERIC_CHECK); + $items[] = Util::toJSON($v); $outItems = "\t".implode(",\n\t", $items)."\n"; } @@ -267,7 +267,7 @@ class SearchPage extends GenericPage if (!$v['heroic']) unset($v['heroic']); - $sets[] = json_encode($v, JSON_NUMERIC_CHECK); + $sets[] = Util::toJSON($v); } $outSets = "\t".implode(",\n\t", $sets)."\n"; @@ -322,7 +322,7 @@ class SearchPage extends GenericPage break; } - return json_encode($result, JSON_NUMERIC_CHECK); + return Util::toJSON($result); } private function createLookup(array $fields = []) @@ -688,7 +688,7 @@ class SearchPage extends GenericPage 'params' => [ 'id' => 'abilities', 'name' => '$LANG.tab_abilities', - 'visibleCols' => '$'.json_encode($vis) + 'visibleCols' => '$'.Util::toJSON($vis) ] ); @@ -743,7 +743,7 @@ class SearchPage extends GenericPage 'params' => [ 'id' => 'talents', 'name' => '$LANG.tab_talents', - 'visibleCols' => '$'.json_encode($vis) + 'visibleCols' => '$'.Util::toJSON($vis) ] ); diff --git a/pages/spells.php b/pages/spells.php index 84be74d0..b7b3d006 100644 --- a/pages/spells.php +++ b/pages/spells.php @@ -394,10 +394,10 @@ class SpellsPage extends GenericPage $visibleCols[] = 'trainingcost'; if ($visibleCols) - $tab['params']['visibleCols'] = '$'.json_encode($visibleCols); + $tab['params']['visibleCols'] = '$'.Util::toJSON($visibleCols); if ($hiddenCols) - $tab['params']['hiddenCols'] = '$'.json_encode($hiddenCols); + $tab['params']['hiddenCols'] = '$'.Util::toJSON($hiddenCols); $this->lvTabs[] = $tab; diff --git a/pages/zone.php b/pages/zone.php index 196014ce..e3864280 100644 --- a/pages/zone.php +++ b/pages/zone.php @@ -14,10 +14,7 @@ class ZonePage extends GenericPage protected $tabId = 0; protected $type = TYPE_ZONE; protected $tpl = 'detail-page-generic'; - protected $js = ['Mapper.js', 'ShowOnMap.js']; - protected $css = array( - ['path' => 'Mapper.css'] - ); + protected $js = ['ShowOnMap.js']; public function __construct($pageCall, $id) { diff --git a/pages/zones.php b/pages/zones.php index f4c83dbb..f274def8 100644 --- a/pages/zones.php +++ b/pages/zones.php @@ -16,13 +16,7 @@ class ZonesPage extends GenericPage protected $tabId = 0; protected $mode = CACHE_TYPE_PAGE; protected $validCats = [true, true, [0, 1, 2], [0, 1, 2], true, true, true, true, true]; - protected $css = array( - ['path' => 'Mapper.css'] - ); - protected $js = array( - 'Mapper.js', - 'ShowOnMap.js' - ); + protected $js = ['ShowOnMap.js']; public function __construct($pageCall, $pageParam) { diff --git a/static/js/Mapper.js b/static/js/Mapper.js deleted file mode 100644 index 1c970be9..00000000 --- a/static/js/Mapper.js +++ /dev/null @@ -1,1105 +0,0 @@ -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); - 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 = { - 4120: 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 -}; - -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(); - - if($WH.isset('g_ptr') && g_ptr) - type = 'ptr'; - else if($WH.isset('g_beta') && g_beta) - type = 'beta'; - else if($WH.isset('g_old') && g_old) - type = 'old'; - - 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 = $WH.ge(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) $WH.ae(span, (i == zoneList.length-1 ? LANG.and : LANG.comma)); - var entry = null; - if(self.objectives[zoneList[i][0]].mappable > 0) - { - entry = $WH.ce('a'); - entry.href = 'javascript:;'; - $WH.ae(entry, $WH.ct(self.objectives[zoneList[i][0]].zone)); - entry.onClick = function(link, zone) { - self.update({ zone: zone }); - g_setSelectedLink(link, 'mapper'); - }.bind(self, entry, zoneList[i][0]); - entry.isLink = true; - } - else - { - entry = $WH.ce('a'); - entry.href = '?zone=' + zoneList[i][0]; - $WH.ae(entry, $WH.ct(self.objectives[zoneList[i][0]].zone)); - g_addTooltip(entry, LANG.tooltip_zonelink); - } - - if(zones.length > 1) - { - var types = zoneTypes[zoneList[i][0]]; - if(types.start && types.end) - { - entry.className += ' icontiny'; - entry.style += ' background-image', 'url(' + g_staticUrl + '/images/wow/icons/tiny/quest_startend.gif)'; - entry.style += ' padding-left', '20px'; - } - else if(types.start) - { - entry.className += ' icontiny'; - entry.style += ' background-image', 'url(' + g_staticUrl + '/images/wow/icons/tiny/quest_start.gif)'; - entry.style += ' padding-left', '14px'; - } - else if(types.end) - { - entry.className += ' icontiny'; - entry.style += ' background-image', 'url(' + g_staticUrl + '/images/wow/icons/tiny/quest_end.gif)'; - entry.style += ' padding-left', '16px'; - } - } - $WH.ae(container, 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 = $WH.ce('h3'); - $WH.ae(h3, $WH.ct(LANG.mapper_relevantlocs)); - $WH.ae(div, h3); - if(zones.length == 1 && this.missing == 0) - { - var span = $WH.ce('span'); - span.innerHTML = LANG.mapper_entiretyinzone.replace('$$', '' + this.objectives[zones[0][0]].zone + '.'); - $WH.ae(div, span); - this.update({ zone: zones[0][0] }); - } - else if(this.missing > 0) - { - var span = $WH.ce('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('$$'); - $WH.ae(span, $WH.ct(parts[0])); - primaryLink = zoneLinks(this, span, zones, typesByZone); - $WH.ae(span, parts[1]); - } - else if(startEnd && types.objective.length == 0) // starts and ends in x - { - var parts = LANG.mapper_objectives.sex.split('$$'); - $WH.ae(span, $WH.ct(parts[0])); - primaryLink = zoneLinks(this, span, zones, typesByZone); - $WH.ae(span, parts[1]); - } - else if(startEnd) // objectives in x, starts and ends in y - { - var parts = LANG.mapper_objectives.ox_sey.split('$$'); - $WH.ae(span, $WH.ct(parts[0])); - primaryLink = zoneLinks(this, span, startZones, typesByZone); - $WH.ae(span, parts[1]); - secondaryLink = zoneLinks(this, span, objZones, typesByZone); - $WH.ae(span, parts[2]); - } - else if(startObj && types.end.length == 0) // objectives and starts in x - { - var parts = LANG.mapper_objectives.osx.split('$$'); - $WH.ae(span, $WH.ct(parts[0])); - primaryLink = zoneLinks(this, span, zones, typesByZone); - $WH.ae(span, parts[1]); - } - else if(startObj) // objectives and starts in x, ends in y - { - var parts = LANG.mapper_objectives.osx_ey.split('$$'); - $WH.ae(span, $WH.ct(parts[0])); - primaryLink = zoneLinks(this, span, objZones, typesByZone); - $WH.ae(span, parts[1]); - secondaryLink = zoneLinks(this, span, endZones, typesByZone); - $WH.ae(span, parts[2]); - } - else if(endObj && types.start.length == 0) // objectives and ends in x - { - var parts = LANG.mapper_objectives.oex.split('$$'); - $WH.ae(span, $WH.ct(parts[0])); - primaryLink = zoneLinks(this, span, zones, typesByZone); - $WH.ae(span, parts[1]); - } - else if(endObj) // objectives and ends in x, starts in y - { - var parts = LANG.mapper_objectives.oex_sy.split('$$'); - $WH.ae(span, $WH.ct(parts[0])); - primaryLink = zoneLinks(this, span, startZones, typesByZone); - $WH.ae(span, parts[1]); - secondaryLink = zoneLinks(this, span, objZones, typesByZone); - $WH.ae(span, parts[1]); - } - 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('$$'); - $WH.ae(span, $WH.ct(parts[0])); - primaryLink = zoneLinks(this, span, startZones, typesByZone); - $WH.ae(span, parts[1]); - secondaryLink = zoneLinks(this, span, objZones, typesByZone); - $WH.ae(span, parts[1]); - tertiaryLink = zoneLinks(this, span, endZones, typesByZone); - $WH.ae(span, 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('$$'); - $WH.ae(span, $WH.ct(parts[0])); - primaryLink = zoneLinks(this, span, startZones, typesByZone); - $WH.ae(span, parts[1]); - secondaryLink = zoneLinks(this, span, endZones, typesByZone); - $WH.ae(span, 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('$$'); - $WH.ae(span, $WH.ct(parts[0])); - primaryLink = zoneLinks(this, span, startZones, typesByZone); - $WH.ae(span, parts[1]); - secondaryLink = zoneLinks(this, span, objZones, typesByZone); - $WH.ae(span, 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('$$'); - $WH.ae(span, $WH.ct(parts[0])); - primaryLink = zoneLinks(this, span, objZones, typesByZone); - $WH.ae(span, parts[1]); - secondaryLink = zoneLinks(this, span, endZones, typesByZone); - $WH.ae(span, parts[2]); - } - else if(types.start.length > 0) // starts in x - { - var parts = LANG.mapper_objectives.sx.split('$$'); - $WH.ae(span, $WH.ct(parts[0])); - primaryLink = zoneLinks(this, span, zones, typesByZone); - $WH.ae(span, parts[1]); - } - else if(types.end.length > 0) // ends in x - { - var parts = LANG.mapper_objectives.ex.split('$$'); - $WH.ae(span, $WH.ct(parts[0])); - primaryLink = zoneLinks(this, span, zones, typesByZone); - $WH.ae(span, parts[1]); - } - else if(types.objective.length > 0) // objectives in x - { - var parts = LANG.mapper_objectives.ox.split('$$'); - $WH.ae(span, $WH.ct(parts[0])); - primaryLink = zoneLinks(this, span, zones, typesByZone); - $WH.ae(span, parts[1]); - } - else // wat? - { - var parts = LANG.mapper_happensin.split('$$'); - $WH.ae(span, $WH.ct(parts[0])); - primaryLink = zoneLinks(this, span, zones, typesByZone); - $WH.ae(span, parts[1]); - } - $WH.ae(div, 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 = $WH.ce('span'); - $WH.ae(span, $WH.ct(parts[0])); - var primaryLink = zoneLinks(this, span, zones, typesByZone); - $WH.ae(span, parts[1]); - $WH.ae(div, 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'; - } - -/* sarjuuk: thats one feature i never understood. the inflatable map is superior to the popup in every way possible - if(this.zoom) - 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 += '
'; - _.a.tt += '' + name + ' ($)
'; - for(var line in opt.tooltip[name].info) - _.a.tt += '
' + opt.tooltip[name].info[line] + '
'; - if(!printedFooter && opt.tooltip[name].footer) - { - _.a.tt += opt.tooltip[name].footer + '
'; - printedFooter = true; - } - } - } - else if(opt && opt.label) - _.a.tt = opt.label; - else - _.a.tt = '$'; - - if(opt && opt.menu) - { - _.a.menu = opt.menu; - Menu.add(_.a, _.a.menu, { showAtCursor: true }); - // _.a.onclick = function() { - // (Menu.show.bind(this))(); - // $WH.Tooltip.hide(); - // this.onmouseout = function() { - // Menu.hide(); - // this.onmouseout = $WH.Tooltip.hide(); - // }.bind(this); - // $WH.sp(); - // return false; - // }.bind(_.a); - } - - if(opt && opt.type) - _.className += ' pin-' + opt.type; - - _.a.tt = $WH.str_replace(_.a.tt, '$', _.x.toFixed(1) + ', ' + _.y.toFixed(1)); - - if(opt && opt.lines) - { - for(var p = 0, nPaths = opt.lines.length; p < nPaths; ++p) - { - if(coord[0] == opt.lines[p][0] && coord[1] == opt.lines[p][1]) - continue; - - for(var s = 0, nSizes = Mapper.sizes.length; s < nSizes; ++s) - { - var size = Mapper.sizes[s]; - _ = Line(coord[0] * size[0] / 100, coord[1] * size[1] / 100, opt.lines[p][0] * size[0] / 100, opt.lines[p][1] * size[1] / 100, opt.type); - _.className += ' ' + size[2]; - $WH.ae(this.floorPins[level], _); - } - } - } - } - - this.onPinUpdate && this.onPinUpdate(this); - }, - - getLink: function() - { - var s = ''; - - for(var i in this.pins) - if(!this.pins[i].free && this.pins[i].floor == this.level) - s += (this.pins[i].x < 10 ? '0' : '') + (this.pins[i].x < 1 ? '0' : '') + (this.pins[i].x * 10).toFixed(0) + (this.pins[i].y < 10 ? '0' : '') + (this.pins[i].y < 1 ? '0' : '') + (this.pins[i].y * 10).toFixed(0); - - return (this.zone ? this.zone : '') + (Mapper.multiLevelZones[this.zone] && this.level != 0 ? '.' + this.level : '') + (s ? ':' + s : ''); - }, - - setLink: function(link, noScroll) - { - var a = []; - - link = link.split(':'); - - var zone = link[0]; - var level = 0; - if(zone.indexOf('.') != -1) - { - var zoneLevel = zone.split('.'); - zone = zoneLevel[0]; - level = parseInt(zoneLevel[1]); - } - - if(!this.setZone(zone, level, noScroll)) - return false; - - if(link.length == 2) - { - for(var i = 0; i < link[1].length; i += 6) - { - var x = link[1].substr(i, 3) / 10; - var y = link[1].substr(i + 3, 3) / 10; - if(isNaN(x) || isNaN(y)) break; - a.push([x, y]); - } - } - - this.setCoords(a, level); - - return true; - }, - - updateMap: function(noScroll) - { - this.parent.style.width = this.span.style.width = (this.tempWidth ? this.tempWidth : Mapper.sizes[this.zoom][0]) + 'px'; - this.parent.style.height = this.span.style.height = (this.tempHeight ? this.tempHeight : Mapper.sizes[this.zoom][1]) + 'px'; - if(!this.editable) - this.parent.style.cssFloat = this.parent.style.styleFloat = 'left'; - - if(this.zone == '0') - this.span.style.background = 'black'; - else - { - var level = this.level; - - if(level == 1 && Mapper.onlyOneFloor[this.zone]) - level = 0; - - var map = this.zone + (level ? '-' + level : ''); - if(Mapper.multiLevelZones[this.zone]) - { - map = Mapper.multiLevelZones[this.zone][level]; - } - this.setMap(map, level); - - if(!this.floorButton && Mapper.multiLevelZones[this.zone]) - { - this.floorButton = _ = RedButton.create(LANG.mapper_floor, true, this.showFloors.bind(this)); - - _.style['float'] = 'right'; - - $WH.ns(_); - this.buttonDiv.appendChild(_); - } - else if(this.floorButton) - this.floorButton.style.display = Mapper.multiLevelZones[this.zone] ? '' : 'none'; - } - - if(this.sToggle) - this.sToggle.style.display = (this.toggle && this.nCoords ? '' : 'none'); - - if(!noScroll) - $WH.g_scrollTo(this.parent, 3); - - // replacement start - // $('.line', this.floorPins[level]).hide(); - // $('.line.' + Mapper.sizes[this.zoom][2], this.floorPins[level]).show(); - if (this.floorPins[level]) { - var lines = this.floorPins[level].getElementsByClassName('line'); - for (i in lines) { - if (i < lines.length) { - lines[i].style.display = 'none'; - } - } - - lines = this.floorPins[level].getElementsByClassName('line ' + Mapper.sizes[this.zoom][2]); - for (i in lines) { - if (i < lines.length) { - lines[i].style.display = 'block'; - } - } - } - // end of replacement - - this.onMapUpdate && this.onMapUpdate(this); - }, - - cleanPin: function(i, floor) - { - var _ = this.pins[i]; - _.style.display = ''; - _.free = false; - _.className = 'pin'; - - _.a.onmousedown = $WH.rf; - _.a.onmouseup = $WH.rf; - _.a.href = 'javascript:;'; - _.a.style.cursor = 'default'; - _.floor = floor; - - return _; - }, - - getPin: function(floor) - { - for(var i = 0; i < this.pins.length; ++i) - if(this.pins[i].free) - return this.cleanPin(i, floor); - - var _ = $WH.ce('div'), a = $WH.ce('a'); - _.className = 'pin'; - _.appendChild(a); - _.a = a; - _.floor = floor; - a.onmouseover = this.pinOver; - a.onmouseout = $WH.Tooltip.hide; - a.onclick = $WH.sp; - - this.pins.push(_); - this.cleanPin(this.pins.length - 1, floor); - - if(!this.floorPins[floor]) - { - this.floorPins[floor] = $WH.ce('div'); - this.floorPins[floor].style.display = this.show ? '' : 'none'; - if(floor == this.level) - $WH.ae(this.span, this.floorPins[floor]); - } - $WH.ae(this.floorPins[floor], _); - return _; - }, - - addPin: function(e) - { - e = $WH.$E(e); - if(e._button >= 2) return; - - this.getMousePos(e); - var p = this.getPin(this.level); - - p.x = this.mouseX; - p.y = this.mouseY; - - p.style.left = p.x.toFixed(1) + '%'; - p.style.top = p.y.toFixed(1) + '%'; - - p.a.onmouseup = this.delPin.bind(this, p); - p.a.tt = p.x.toFixed(1) + ', ' + p.y.toFixed(1); - - this.onPinUpdate && this.onPinUpdate(this); - - return false; - }, - - delPin: function(pin, e) - { - e = $WH.$E(e); - - pin.style.display = 'none'; - pin.free = true; - $WH.sp(e); - - this.onPinUpdate && this.onPinUpdate(this); - - return; - }, - - pinOver: function() - { - $WH.Tooltip.show(this, this.tt, 4, 0); - }, - - getMousePos: function(e) - { - e = $WH.$E(e); - - var c = $WH.ac(this.parent); - - var scroll = $WH.g_getScroll(); - - this.mouseX = Math.floor((e.clientX + scroll.x - c[0] - 3) / Mapper.sizes[this.zoom][0] * 1000) / 10; - this.mouseY = Math.floor((e.clientY + scroll.y - c[1] - 3) / Mapper.sizes[this.zoom][1] * 1000) / 10; - - if(this.mouseX < 0) this.mouseX = 0; - else if(this.mouseX > 100) this.mouseX = 100; - - if(this.mouseY < 0) this.mouseY = 0; - else if(this.mouseY > 100) this.mouseY = 100; - - if(this.mouse) - g_setTextNodes(this.sMouse, '(' + this.mouseX.toFixed(1) + ', ' + this.mouseY.toFixed(1) + ')'); - } -}; diff --git a/static/js/global.js b/static/js/global.js index 2cdd3449..95865701 100644 --- a/static/js/global.js +++ b/static/js/global.js @@ -2809,15 +2809,15 @@ Global video-related functions */ var vi_thumbnails = { - 1: 'http://i3.ytimg.com/vi/$1/default.jpg' // YouTube + 1: 'https://i3.ytimg.com/vi/$1/default.jpg' // YouTube }; var vi_siteurls = { - 1: 'http://www.youtube.com/watch?v=$1' // YouTube + 1: 'https://www.youtube.com/watch?v=$1' // YouTube }; var vi_sitevalidation = { - 1: /^http:\/\/www\.youtube\.com\/watch\?v=([^& ]{11})/ // YouTube + 1: /^https?:\/\/www\.youtube\.com\/watch\?v=([^& ]{11})/ // YouTube }; function vi_submitAVideo() { @@ -17577,6 +17577,1112 @@ var Lightbox = new function() { Locale class moved to own file */ +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); + 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 +}; + +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(); + + if($WH.isset('g_ptr') && g_ptr) + type = 'ptr'; + else if($WH.isset('g_beta') && g_beta) + type = 'beta'; + else if($WH.isset('g_old') && g_old) + type = 'old'; + + 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 = $WH.ge(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) $WH.ae(span, (i == zoneList.length-1 ? LANG.and : LANG.comma)); + var entry = null; + if(self.objectives[zoneList[i][0]].mappable > 0) + { + entry = $WH.ce('a'); + entry.href = 'javascript:;'; + $WH.ae(entry, $WH.ct(self.objectives[zoneList[i][0]].zone)); + entry.onClick = function(link, zone) { + self.update({ zone: zone }); + g_setSelectedLink(link, 'mapper'); + }.bind(self, entry, zoneList[i][0]); + entry.isLink = true; + } + else + { + entry = $WH.ce('a'); + entry.href = '?zone=' + zoneList[i][0]; + $WH.ae(entry, $WH.ct(self.objectives[zoneList[i][0]].zone)); + g_addTooltip(entry, LANG.tooltip_zonelink); + } + + if(zones.length > 1) + { + var types = zoneTypes[zoneList[i][0]]; + if(types.start && types.end) + { + entry.className += ' icontiny'; + entry.style += ' background-image', 'url(' + g_staticUrl + '/images/wow/icons/tiny/quest_startend.gif)'; + entry.style += ' padding-left', '20px'; + } + else if(types.start) + { + entry.className += ' icontiny'; + entry.style += ' background-image', 'url(' + g_staticUrl + '/images/wow/icons/tiny/quest_start.gif)'; + entry.style += ' padding-left', '14px'; + } + else if(types.end) + { + entry.className += ' icontiny'; + entry.style += ' background-image', 'url(' + g_staticUrl + '/images/wow/icons/tiny/quest_end.gif)'; + entry.style += ' padding-left', '16px'; + } + } + $WH.ae(container, 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 = $WH.ce('h3'); + $WH.ae(h3, $WH.ct(LANG.mapper_relevantlocs)); + $WH.ae(div, h3); + if(zones.length == 1 && this.missing == 0) + { + var span = $WH.ce('span'); + span.innerHTML = LANG.mapper_entiretyinzone.replace('$$', '' + this.objectives[zones[0][0]].zone + '.'); + $WH.ae(div, span); + this.update({ zone: zones[0][0] }); + } + else if(this.missing > 0) + { + var span = $WH.ce('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('$$'); + $WH.ae(span, $WH.ct(parts[0])); + primaryLink = zoneLinks(this, span, zones, typesByZone); + $WH.ae(span, parts[1]); + } + else if(startEnd && types.objective.length == 0) // starts and ends in x + { + var parts = LANG.mapper_objectives.sex.split('$$'); + $WH.ae(span, $WH.ct(parts[0])); + primaryLink = zoneLinks(this, span, zones, typesByZone); + $WH.ae(span, parts[1]); + } + else if(startEnd) // objectives in x, starts and ends in y + { + var parts = LANG.mapper_objectives.ox_sey.split('$$'); + $WH.ae(span, $WH.ct(parts[0])); + primaryLink = zoneLinks(this, span, startZones, typesByZone); + $WH.ae(span, parts[1]); + secondaryLink = zoneLinks(this, span, objZones, typesByZone); + $WH.ae(span, parts[2]); + } + else if(startObj && types.end.length == 0) // objectives and starts in x + { + var parts = LANG.mapper_objectives.osx.split('$$'); + $WH.ae(span, $WH.ct(parts[0])); + primaryLink = zoneLinks(this, span, zones, typesByZone); + $WH.ae(span, parts[1]); + } + else if(startObj) // objectives and starts in x, ends in y + { + var parts = LANG.mapper_objectives.osx_ey.split('$$'); + $WH.ae(span, $WH.ct(parts[0])); + primaryLink = zoneLinks(this, span, objZones, typesByZone); + $WH.ae(span, parts[1]); + secondaryLink = zoneLinks(this, span, endZones, typesByZone); + $WH.ae(span, parts[2]); + } + else if(endObj && types.start.length == 0) // objectives and ends in x + { + var parts = LANG.mapper_objectives.oex.split('$$'); + $WH.ae(span, $WH.ct(parts[0])); + primaryLink = zoneLinks(this, span, zones, typesByZone); + $WH.ae(span, parts[1]); + } + else if(endObj) // objectives and ends in x, starts in y + { + var parts = LANG.mapper_objectives.oex_sy.split('$$'); + $WH.ae(span, $WH.ct(parts[0])); + primaryLink = zoneLinks(this, span, startZones, typesByZone); + $WH.ae(span, parts[1]); + secondaryLink = zoneLinks(this, span, objZones, typesByZone); + $WH.ae(span, parts[1]); + } + 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('$$'); + $WH.ae(span, $WH.ct(parts[0])); + primaryLink = zoneLinks(this, span, startZones, typesByZone); + $WH.ae(span, parts[1]); + secondaryLink = zoneLinks(this, span, objZones, typesByZone); + $WH.ae(span, parts[1]); + tertiaryLink = zoneLinks(this, span, endZones, typesByZone); + $WH.ae(span, 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('$$'); + $WH.ae(span, $WH.ct(parts[0])); + primaryLink = zoneLinks(this, span, startZones, typesByZone); + $WH.ae(span, parts[1]); + secondaryLink = zoneLinks(this, span, endZones, typesByZone); + $WH.ae(span, 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('$$'); + $WH.ae(span, $WH.ct(parts[0])); + primaryLink = zoneLinks(this, span, startZones, typesByZone); + $WH.ae(span, parts[1]); + secondaryLink = zoneLinks(this, span, objZones, typesByZone); + $WH.ae(span, 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('$$'); + $WH.ae(span, $WH.ct(parts[0])); + primaryLink = zoneLinks(this, span, objZones, typesByZone); + $WH.ae(span, parts[1]); + secondaryLink = zoneLinks(this, span, endZones, typesByZone); + $WH.ae(span, parts[2]); + } + else if(types.start.length > 0) // starts in x + { + var parts = LANG.mapper_objectives.sx.split('$$'); + $WH.ae(span, $WH.ct(parts[0])); + primaryLink = zoneLinks(this, span, zones, typesByZone); + $WH.ae(span, parts[1]); + } + else if(types.end.length > 0) // ends in x + { + var parts = LANG.mapper_objectives.ex.split('$$'); + $WH.ae(span, $WH.ct(parts[0])); + primaryLink = zoneLinks(this, span, zones, typesByZone); + $WH.ae(span, parts[1]); + } + else if(types.objective.length > 0) // objectives in x + { + var parts = LANG.mapper_objectives.ox.split('$$'); + $WH.ae(span, $WH.ct(parts[0])); + primaryLink = zoneLinks(this, span, zones, typesByZone); + $WH.ae(span, parts[1]); + } + else // wat? + { + var parts = LANG.mapper_happensin.split('$$'); + $WH.ae(span, $WH.ct(parts[0])); + primaryLink = zoneLinks(this, span, zones, typesByZone); + $WH.ae(span, parts[1]); + } + $WH.ae(div, 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 = $WH.ce('span'); + $WH.ae(span, $WH.ct(parts[0])); + var primaryLink = zoneLinks(this, span, zones, typesByZone); + $WH.ae(span, parts[1]); + $WH.ae(div, 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'; + } + +/* sarjuuk: thats one feature i never understood. the inflatable map is superior to the popup in every way possible + if(this.zoom) + 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 += '
'; + _.a.tt += '' + name + ' ($)
'; + for(var line in opt.tooltip[name].info) + _.a.tt += '
' + opt.tooltip[name].info[line] + '
'; + if(!printedFooter && opt.tooltip[name].footer) + { + _.a.tt += opt.tooltip[name].footer + '
'; + printedFooter = true; + } + } + } + else if(opt && opt.label) + _.a.tt = opt.label; + else + _.a.tt = '$'; + + if(opt && opt.menu) + { + _.a.menu = opt.menu; + Menu.add(_.a, _.a.menu, { showAtCursor: true }); + // _.a.onclick = function() { + // (Menu.show.bind(this))(); + // $WH.Tooltip.hide(); + // this.onmouseout = function() { + // Menu.hide(); + // this.onmouseout = $WH.Tooltip.hide(); + // }.bind(this); + // $WH.sp(); + // return false; + // }.bind(_.a); + } + + if(opt && opt.type) + _.className += ' pin-' + opt.type; + + _.a.tt = $WH.str_replace(_.a.tt, '$', _.x.toFixed(1) + ', ' + _.y.toFixed(1)); + + if(opt && opt.lines) + { + for(var p = 0, nPaths = opt.lines.length; p < nPaths; ++p) + { + if(coord[0] == opt.lines[p][0] && coord[1] == opt.lines[p][1]) + continue; + + for(var s = 0, nSizes = Mapper.sizes.length; s < nSizes; ++s) + { + var size = Mapper.sizes[s]; + _ = Line(coord[0] * size[0] / 100, coord[1] * size[1] / 100, opt.lines[p][0] * size[0] / 100, opt.lines[p][1] * size[1] / 100, opt.type); + _.className += ' ' + size[2]; + $WH.ae(this.floorPins[level], _); + } + } + } + } + + this.onPinUpdate && this.onPinUpdate(this); + }, + + getLink: function() + { + var s = ''; + + for(var i in this.pins) + if(!this.pins[i].free && this.pins[i].floor == this.level) + s += (this.pins[i].x < 10 ? '0' : '') + (this.pins[i].x < 1 ? '0' : '') + (this.pins[i].x * 10).toFixed(0) + (this.pins[i].y < 10 ? '0' : '') + (this.pins[i].y < 1 ? '0' : '') + (this.pins[i].y * 10).toFixed(0); + + return (this.zone ? this.zone : '') + (Mapper.multiLevelZones[this.zone] && this.level != 0 ? '.' + this.level : '') + (s ? ':' + s : ''); + }, + + setLink: function(link, noScroll) + { + var a = []; + + link = link.split(':'); + + var zone = link[0]; + var level = 0; + if(zone.indexOf('.') != -1) + { + var zoneLevel = zone.split('.'); + zone = zoneLevel[0]; + level = parseInt(zoneLevel[1]); + } + + if(!this.setZone(zone, level, noScroll)) + return false; + + if(link.length == 2) + { + for(var i = 0; i < link[1].length; i += 6) + { + var x = link[1].substr(i, 3) / 10; + var y = link[1].substr(i + 3, 3) / 10; + if(isNaN(x) || isNaN(y)) break; + a.push([x, y]); + } + } + + this.setCoords(a, level); + + return true; + }, + + updateMap: function(noScroll) + { + this.parent.style.width = this.span.style.width = (this.tempWidth ? this.tempWidth : Mapper.sizes[this.zoom][0]) + 'px'; + this.parent.style.height = this.span.style.height = (this.tempHeight ? this.tempHeight : Mapper.sizes[this.zoom][1]) + 'px'; + if(!this.editable) + this.parent.style.cssFloat = this.parent.style.styleFloat = 'left'; + + if(this.zone == '0') + this.span.style.background = 'black'; + else + { + var level = this.level; + + if(level == 1 && Mapper.onlyOneFloor[this.zone]) + level = 0; + + var map = this.zone + (level ? '-' + level : ''); + if(Mapper.multiLevelZones[this.zone]) + { + map = Mapper.multiLevelZones[this.zone][level]; + } + this.setMap(map, level); + + if(!this.floorButton && Mapper.multiLevelZones[this.zone]) + { + this.floorButton = _ = RedButton.create(LANG.mapper_floor, true, this.showFloors.bind(this)); + + _.style['float'] = 'right'; + + $WH.ns(_); + this.buttonDiv.appendChild(_); + } + else if(this.floorButton) + this.floorButton.style.display = Mapper.multiLevelZones[this.zone] ? '' : 'none'; + } + + if(this.sToggle) + this.sToggle.style.display = (this.toggle && this.nCoords ? '' : 'none'); + + if(!noScroll) + $WH.g_scrollTo(this.parent, 3); + + // replacement start + // $('.line', this.floorPins[level]).hide(); + // $('.line.' + Mapper.sizes[this.zoom][2], this.floorPins[level]).show(); + if (this.floorPins[level]) { + var lines = this.floorPins[level].getElementsByClassName('line'); + for (i in lines) { + if (i < lines.length) { + lines[i].style.display = 'none'; + } + } + + lines = this.floorPins[level].getElementsByClassName('line ' + Mapper.sizes[this.zoom][2]); + for (i in lines) { + if (i < lines.length) { + lines[i].style.display = 'block'; + } + } + } + // end of replacement + + this.onMapUpdate && this.onMapUpdate(this); + }, + + cleanPin: function(i, floor) + { + var _ = this.pins[i]; + _.style.display = ''; + _.free = false; + _.className = 'pin'; + + _.a.onmousedown = $WH.rf; + _.a.onmouseup = $WH.rf; + _.a.href = 'javascript:;'; + _.a.style.cursor = 'default'; + _.floor = floor; + + return _; + }, + + getPin: function(floor) + { + for(var i = 0; i < this.pins.length; ++i) + if(this.pins[i].free) + return this.cleanPin(i, floor); + + var _ = $WH.ce('div'), a = $WH.ce('a'); + _.className = 'pin'; + _.appendChild(a); + _.a = a; + _.floor = floor; + a.onmouseover = this.pinOver; + a.onmouseout = $WH.Tooltip.hide; + a.onclick = $WH.sp; + + this.pins.push(_); + this.cleanPin(this.pins.length - 1, floor); + + if(!this.floorPins[floor]) + { + this.floorPins[floor] = $WH.ce('div'); + this.floorPins[floor].style.display = this.show ? '' : 'none'; + if(floor == this.level) + $WH.ae(this.span, this.floorPins[floor]); + } + $WH.ae(this.floorPins[floor], _); + return _; + }, + + addPin: function(e) + { + e = $WH.$E(e); + if(e._button >= 2) return; + + this.getMousePos(e); + var p = this.getPin(this.level); + + p.x = this.mouseX; + p.y = this.mouseY; + + p.style.left = p.x.toFixed(1) + '%'; + p.style.top = p.y.toFixed(1) + '%'; + + p.a.onmouseup = this.delPin.bind(this, p); + p.a.tt = p.x.toFixed(1) + ', ' + p.y.toFixed(1); + + this.onPinUpdate && this.onPinUpdate(this); + + return false; + }, + + delPin: function(pin, e) + { + e = $WH.$E(e); + + pin.style.display = 'none'; + pin.free = true; + $WH.sp(e); + + this.onPinUpdate && this.onPinUpdate(this); + + return; + }, + + pinOver: function() + { + $WH.Tooltip.show(this, this.tt, 4, 0); + }, + + getMousePos: function(e) + { + e = $WH.$E(e); + + var c = $WH.ac(this.parent); + + var scroll = $WH.g_getScroll(); + + this.mouseX = Math.floor((e.clientX + scroll.x - c[0] - 3) / Mapper.sizes[this.zoom][0] * 1000) / 10; + this.mouseY = Math.floor((e.clientY + scroll.y - c[1] - 3) / Mapper.sizes[this.zoom][1] * 1000) / 10; + + if(this.mouseX < 0) this.mouseX = 0; + else if(this.mouseX > 100) this.mouseX = 100; + + if(this.mouseY < 0) this.mouseY = 0; + else if(this.mouseY > 100) this.mouseY = 100; + + if(this.mouse) + g_setTextNodes(this.sMouse, '(' + this.mouseX.toFixed(1) + ', ' + this.mouseY.toFixed(1) + ')'); + } +}; + var ModelViewer = new function() { this.validSlots = [1,3,4,5,6,7,8,9,10,13,14,15,16,17,19,20,21,22,23,25,26]; this.slotMap = {1: 1, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9, 10: 10, 13: 21, 14: 22, 15: 22, 16: 16, 17: 21, 19: 19, 20: 5, 21: 21, 22: 22, 23: 22, 25: 21, 26: 21}; diff --git a/static/js/locale_dede.js b/static/js/locale_dede.js index d04b9719..0e84cfe0 100644 --- a/static/js/locale_dede.js +++ b/static/js/locale_dede.js @@ -2013,7 +2013,6 @@ var g_zone_areas = { 4395: ['Dalaran', 'Die Schattenseite'], 4494: ['Ahn\'kahet', '2. Stockwerk'], 4722: ['Kolosseum der Kreuzfahrer', 'Die eisigen Tiefen'], - 4723: ['Kolosseum der Kreuzfahrer', 'Die eisigen Tiefen'], 4812: ['Die untere Zitadelle', 'Das Schädelbollwerk', 'Dom des Todbringers', 'Hort der Frostkönigin', 'Der obere Bereich', 'Königliche Quartiere', 'Der Frostthron', 'Frostgram'] }; diff --git a/static/js/locale_enus.js b/static/js/locale_enus.js index 7903b8fd..3698749a 100644 --- a/static/js/locale_enus.js +++ b/static/js/locale_enus.js @@ -2059,7 +2059,6 @@ var g_zone_areas = { 4395: ['Dalaran City', 'The Underbelly'], 4494: ['Ahn\'Kahet', 'Level 2'], 4722: ['Crusaders\' Coliseum', 'The Icy Depths'], - 4723: ['Crusaders\' Coliseum', 'The Icy Depths'], 4812: ['The Lower Citadel', 'The Rampart of Skulls', 'Deathbringer\'s Rise', 'The Frost Queen\'s Lair', 'The Upper Reaches', 'Royal Quarters', 'The Frozen Throne', 'Frostmourne'] }; diff --git a/static/js/locale_eses.js b/static/js/locale_eses.js index 010ded87..01e4f1b8 100644 --- a/static/js/locale_eses.js +++ b/static/js/locale_eses.js @@ -2015,7 +2015,6 @@ var g_zone_areas = { 4395: ['Ciudad de Dalaran', 'Los Bajos Fondos'], 4494: ['Ahn\'kahet', 'Nivel 2'], 4722: ['El Coliseo Argenta', 'Las profundidades heladas'], - 4723: ['El Coliseo Argenta', 'Las profundidades heladas'], 4812: ['La ciudadela inferior', 'La Muralla de las Calaveras', 'Ascenso del Libramorte', 'La guarida de la Reina de Escarcha', 'Los Confines superiores', 'Cuarteles Reales', 'El Trono Helado', 'Agonía de Escarcha'] }; diff --git a/static/js/locale_frfr.js b/static/js/locale_frfr.js index 7f209e85..39b7b861 100644 --- a/static/js/locale_frfr.js +++ b/static/js/locale_frfr.js @@ -2002,7 +2002,6 @@ var g_zone_areas = { 4395: ['Dalaran', 'Les Entrailles'], 4494: ['Ahn\'kahet', 'Plancher 2'], 4722: ['L\'colisée d\'Argent', 'Les Profondeurs Glacées'], - 4723: ['L\'colisée d\'Argent', 'Les Profondeurs Glacées'], 4812: ['La Citadelle Inférieure', 'Le Rempart des Cranes', 'Ascension de Porte-mort', 'Le repaire de la reine du Givre', 'Les étages supérieurs', 'Quartiers Royaux', 'Le Trône Gelé', 'Deuillegivre'] }; diff --git a/static/js/locale_ruru.js b/static/js/locale_ruru.js index 75b7c894..998d3225 100644 --- a/static/js/locale_ruru.js +++ b/static/js/locale_ruru.js @@ -2002,7 +2002,6 @@ var g_zone_areas = { 4395: ['Даларан', 'Клоака'], 4494: ['Ан\'кахет', 'Уровень 2'], 4722: ['Колизей Серебряного Авангарда', 'Ледяные глубины'], - 4723: ['Колизей Серебряного Авангарда', 'Ледяные глубины'], 4812: ['Нижний ярус', 'Черепной вал', 'Подъем Смертоносного', 'Логово Королевы Льда', 'Верхний ярус', 'Королевские палаты', 'Ледяной Трон', 'Ледяная Скорбь'] };