protected function generateContent() { $this->addJS('?data=zones&locale=' . User::$localeId . '&t=' . $_SESSION['dataKey']); $conditions = []; if (!User::isInGroup(U_GROUP_EMPLOYEE)) { $conditions[] = [['cuFlags', CUSTOM_EXCLUDE_FOR_LISTVIEW, '&'], 0]; } if ($this->category) { $conditions[] = ['type', $this->category[0]]; $this->petFamPanel = $this->category[0] == 1; } else { $this->petFamPanel = false; } if ($_ = $this->filterObj->getConditions()) { $conditions[] = $_; } // beast subtypes are selected via filter $npcs = new CreatureList($conditions, ['extraOpts' => $this->filterObj->extraOpts]); // recreate form selection $this->filter = array_merge($this->filterObj->getForm('form'), $this->filter); $this->filter['query'] = isset($_GET['filter']) ? $_GET['filter'] : NULL; $this->filter['fi'] = $this->filterObj->getForm(); $repCols = $this->filterObj->getForm('reputationCols'); $tabData = array('data' => array_values($npcs->getListviewData($repCols ? NPCINFO_REP : 0x0))); if ($repCols) { $tabData['extraCols'] = '$fi_getReputationCols(' . Util::toJSON($repCols) . ')'; } else { if (!empty($this->filter['fi']['extraCols'])) { $tabData['extraCols'] = '$fi_getExtraCols(fi_extraCols, 0, 0)'; } } if ($this->category) { $tabData['hiddenCols'] = ['type']; } // create note if search limit was exceeded if ($npcs->getMatches() > CFG_SQL_LIMIT_DEFAULT) { $tabData['note'] = sprintf(Util::$tryFilteringString, 'LANG.lvnote_npcsfound', $npcs->getMatches(), CFG_SQL_LIMIT_DEFAULT); $tabData['_truncated'] = 1; } if ($this->filterObj->error) { $tabData['_errors'] = 1; } $this->lvTabs[] = ['creature', $tabData]; // sort for dropdown-menus Lang::sort('game', 'fa'); }
private function _searchCreature($cndBase) { $result = []; $cnd = array_merge($cndBase, array([['flagsExtra', 0x80], 0], $this->createLookup())); $npcs = new CreatureList($cnd); if ($data = $npcs->getListviewData()) { $result = array('type' => TYPE_NPC, 'appendix' => ' (NPC)', 'matches' => $npcs->getMatches(), 'file' => CreatureList::$brickFile, 'data' => $data, 'params' => ['id' => 'npcs', 'name' => '$LANG.tab_npcs']); if ($npcs->getMatches() > $this->maxResults) { $result['params']['note'] = sprintf(Util::$tryNarrowingString, 'LANG.lvnote_npcsfound', $npcs->getMatches(), $this->maxResults); $result['params']['_truncated'] = 1; } if (isset($result['params']['note'])) { $result['params']['note'] .= ' + LANG.dash + $WH.sprintf(LANG.lvnote_filterresults, \'?npcs&filter=na=' . urlencode($this->search) . '\')'; } else { $result['params']['note'] = '$$WH.sprintf(LANG.lvnote_filterresults, \'?npcs&filter=na=' . urlencode($this->search) . '\')'; } } return $result; }
private function _searchCreature($cndBase) { $cnd = array_merge($cndBase, array([['flagsExtra', 0x80], 0], $this->createLookup())); $npcs = new CreatureList($cnd); if ($data = $npcs->getListviewData()) { $osInfo = [TYPE_NPC, ' (NPC)', $npcs->getMatches()]; $result = array('data' => array_values($data), 'id' => 'npcs', 'name' => '$LANG.tab_npcs'); if ($npcs->getMatches() > $this->maxResults) { $result['note'] = sprintf(Util::$tryNarrowingString, 'LANG.lvnote_npcsfound', $npcs->getMatches(), $this->maxResults); $result['_truncated'] = 1; } if (isset($result['note'])) { $result['note'] .= ' + LANG.dash + $WH.sprintf(LANG.lvnote_filterresults, \'?npcs&filter=na=' . urlencode($this->search) . '\')'; } else { $result['note'] = '$$WH.sprintf(LANG.lvnote_filterresults, \'?npcs&filter=na=' . urlencode($this->search) . '\')'; } return ['creature', $result, null, $osInfo]; } return false; }
protected function generateContent() { $this->addJS('?data=zones&locale=' . User::$localeId . '&t=' . $_SESSION['dataKey']); /***********/ /* Infobox */ /***********/ $infobox = Lang::getInfoBoxForFlags($this->subject->getField('cuFlags')); // Quartermaster if any if ($ids = $this->subject->getField('qmNpcIds')) { $this->extendGlobalIds(TYPE_NPC, $ids); $qmStr = Lang::faction('quartermaster') . Lang::main('colon'); if (count($ids) == 1) { $qmStr .= '[npc=' . $ids[0] . ']'; } else { if (count($ids) > 1) { $qmStr .= '[ul]'; foreach ($ids as $id) { $qmStr .= '[li][npc=' . $id . '][/li]'; } $qmStr .= '[/ul]'; } } $infobox[] = $qmStr; } // side if any if ($_ = $this->subject->getField('side')) { $infobox[] = Lang::main('side') . Lang::main('colon') . '[span class=icon-' . ($_ == 1 ? 'alliance' : 'horde') . ']' . Lang::game('si', $_) . '[/span]'; } /****************/ /* Main Content */ /****************/ $this->extraText = ''; $this->infobox = $infobox ? '[ul][li]' . implode('[/li][li]', $infobox) . '[/li][/ul]' : null; $this->redButtons = array(BUTTON_WOWHEAD => true, BUTTON_LINKS => true); // Spillover Effects /* todo (low): also check on reputation_spillover_template (but its data is identical to calculation below $rst = DB::World()->selectRow('SELECT CONCAT_WS(" ", faction1, faction2, faction3, faction4) AS faction, CONCAT_WS(" ", rate_1, rate_2, rate_3, rate_4) AS rate, CONCAT_WS(" ", rank_1, rank_2, rank_3, rank_4) AS rank FROM reputation_spillover_template WHERE faction = ?d', $this->typeId); */ $conditions = array(['id', $this->typeId, '!'], ['repIdx', -1, '!']); if ($p = $this->subject->getField('parentFactionId')) { // linked via parent $conditions[] = ['OR', ['id', $p], ['parentFactionId', $p]]; } else { // self as parent $conditions[] = ['parentFactionId', $this->typeId]; } $spillover = new FactionList($conditions); $this->extendGlobalData($spillover->getJSGlobals()); $buff = ''; foreach ($spillover->iterate() as $spillId => $__) { if ($val = $spillover->getField('spilloverRateIn') * $this->subject->getField('spilloverRateOut') * 100) { $buff .= '[tr][td][faction=' . $spillId . '][/td][td][span class=q' . ($val > 0 ? '2]+' : '10]') . $val . '%[/span][/td][td]' . Lang::game('rep', $spillover->getField('spilloverMaxRank')) . '[/td][/tr]'; } } if ($buff) { $this->extraText .= '[h3 class=clear]' . Lang::faction('spillover') . '[/h3][div margin=15px]' . Lang::faction('spilloverDesc') . '[/div][table class=grid width=400px][tr][td width=150px][b]' . Util::ucFirst(Lang::game('faction')) . '[/b][/td][td width=100px][b]' . Lang::spell('_value') . '[/b][/td][td width=150px][b]' . Lang::faction('maxStanding') . '[/b][/td][/tr]' . $buff . '[/table]'; } // reward rates (ultimately this should be calculated into each reward display) if ($rates = DB::World()->selectRow('SELECT * FROM reputation_reward_rate WHERE faction = ?d', $this->typeId)) { $buff = ''; foreach ($rates as $k => $v) { if ($v == 1) { continue; } switch ($k) { case 'quest_rate': $buff .= '[tr][td]' . Lang::game('quests') . Lang::main('colon') . '[/td]'; break; case 'quest_daily_rate': $buff .= '[tr][td]' . Lang::game('quests') . ' (' . Lang::quest('daily') . ')' . Lang::main('colon') . '[/td]'; break; case 'quest_weekly_rate': $buff .= '[tr][td]' . Lang::game('quests') . ' (' . Lang::quest('weekly') . ')' . Lang::main('colon') . '[/td]'; break; case 'quest_monthly_rate': $buff .= '[tr][td]' . Lang::game('quests') . ' (' . Lang::quest('monthly') . ')' . Lang::main('colon') . '[/td]'; break; case 'creature_rate': $buff .= '[tr][td]' . Lang::game('npcs') . Lang::main('colon') . '[/td]'; break; case 'spell_rate': $buff .= '[tr][td]' . Lang::game('spells') . Lang::main('colon') . '[/td]'; break; } $buff .= '[td width=35px align=right][span class=q' . ($v < 1 ? '10]' : '2]+') . intVal(($v - 1) * 100) . '%[/span][/td][/tr]'; } if ($buff) { $this->extraText .= '[h3 class=clear]' . Lang::faction('customRewRate') . '[/h3][table]' . $buff . '[/table]'; } } // factionchange-equivalent if ($pendant = DB::World()->selectCell('SELECT IF(horde_id = ?d, alliance_id, -horde_id) FROM player_factionchange_reputations WHERE alliance_id = ?d OR horde_id = ?d', $this->typeId, $this->typeId, $this->typeId)) { $altFac = new FactionList(array(['id', abs($pendant)])); if (!$altFac->error) { $this->transfer = sprintf(Lang::faction('_transfer'), $altFac->id, $altFac->getField('name', true), $pendant > 0 ? 'alliance' : 'horde', $pendant > 0 ? Lang::game('si', 1) : Lang::game('si', 2)); } } /**************/ /* Extra Tabs */ /**************/ // tab: items $items = new ItemList(array(['requiredFaction', $this->typeId])); if (!$items->error) { $this->extendGlobalData($items->getJSGlobals(GLOBALINFO_SELF)); $tabData = array('data' => array_values($items->getListviewData()), 'extraCols' => '$_', 'sort' => ['standing', 'name']); if ($items->getMatches() > CFG_SQL_LIMIT_DEFAULT) { $tabData['note'] = sprintf(Util::$filterResultString, '?items&filter=cr=17;crs=' . $this->typeId . ';crv=0'); } $this->lvTabs[] = ['item', $tabData, 'itemStandingCol']; } // tab: creatures with onKill reputation if ($this->subject->getField('reputationIndex') != -1) { // inherit siblings/children from $spillover $cRep = DB::World()->selectCol('SELECT DISTINCT creature_id AS ARRAY_KEY, qty FROM ( SELECT creature_id, RewOnKillRepValue1 as qty FROM creature_onkill_reputation WHERE RewOnKillRepValue1 > 0 AND (RewOnKillRepFaction1 = ?d{ OR (RewOnKillRepFaction1 IN (?a) AND IsTeamAward1 <> 0)}) UNION SELECT creature_id, RewOnKillRepValue2 as qty FROM creature_onkill_reputation WHERE RewOnKillRepValue2 > 0 AND (RewOnKillRepFaction2 = ?d{ OR (RewOnKillRepFaction2 IN (?a) AND IsTeamAward2 <> 0)}) ) x', $this->typeId, $spillover->getFoundIDs() ?: DBSIMPLE_SKIP, $this->typeId, $spillover->getFoundIDs() ?: DBSIMPLE_SKIP); if ($cRep) { $killCreatures = new CreatureList(array(['id', array_keys($cRep)])); if (!$killCreatures->error) { $data = $killCreatures->getListviewData(); foreach ($data as $id => &$d) { $d['reputation'] = $cRep[$id]; } $tabData = array('data' => array_values($data), 'extraCols' => '$_', 'sort' => ['-reputation', 'name']); if ($killCreatures->getMatches() > CFG_SQL_LIMIT_DEFAULT) { $tabData['note'] = sprintf(Util::$filterResultString, '?npcs&filter=cr=42;crs=' . $this->typeId . ';crv=0'); } $this->lvTabs[] = ['creature', $tabData, 'npcRepCol']; } } } // tab: members if ($_ = $this->subject->getField('templateIds')) { $members = new CreatureList(array(['faction', $_])); if (!$members->error) { $tabData = array('data' => array_values($members->getListviewData()), 'id' => 'member', 'name' => '$LANG.tab_members'); if ($members->getMatches() > CFG_SQL_LIMIT_DEFAULT) { $tabData['note'] = sprintf(Util::$filterResultString, '?npcs&filter=cr=3;crs=' . $this->typeId . ';crv=0'); } $this->lvTabs[] = ['creature', $tabData]; } } // tab: objects if ($_ = $this->subject->getField('templateIds')) { $objects = new GameObjectList(array(['faction', $_])); if (!$objects->error) { $this->lvTabs[] = ['object', ['data' => array_values($objects->getListviewData())]]; } } // tab: quests $conditions = array(['AND', ['rewardFactionId1', $this->typeId], ['rewardFactionValue1', 0, '>']], ['AND', ['rewardFactionId2', $this->typeId], ['rewardFactionValue2', 0, '>']], ['AND', ['rewardFactionId3', $this->typeId], ['rewardFactionValue3', 0, '>']], ['AND', ['rewardFactionId4', $this->typeId], ['rewardFactionValue4', 0, '>']], ['AND', ['rewardFactionId5', $this->typeId], ['rewardFactionValue5', 0, '>']], 'OR'); $quests = new QuestList($conditions); if (!$quests->error) { $this->extendGlobalData($quests->getJSGlobals(GLOBALINFO_ANY)); $tabData = array('data' => array_values($quests->getListviewData($this->typeId)), 'extraCols' => '$_'); if ($quests->getMatches() > CFG_SQL_LIMIT_DEFAULT) { $tabData['note'] = sprintf(Util::$filterResultString, '?quests&filter=cr=1;crs=' . $this->typeId . ';crv=0'); } $this->lvTabs[] = ['quest', $tabData, 'questRepCol']; } // tab: achievements $conditions = array(['ac.type', ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION], ['ac.value1', $this->typeId]); $acvs = new AchievementList($conditions); if (!$acvs->error) { $this->extendGlobalData($acvs->getJSGlobals(GLOBALINFO_ANY)); $this->lvTabs[] = ['achievement', array('data' => array_values($acvs->getListviewData()), 'id' => 'criteria-of', 'name' => '$LANG.tab_criteriaof', 'visibleCols' => ['category'])]; } }
protected function generateContent() { $this->addJS('?data=zones&locale=' . User::$localeId . '&t=' . $_SESSION['dataKey']); /***********/ /* Infobox */ /***********/ $infobox = Lang::getInfoBoxForFlags($this->subject->getField('cuFlags')); // City if ($this->subject->getField('flags') & 0x8 && !$this->subject->getField('parentArea')) { $infobox[] = Lang::zone('city'); } // Auto repop if ($this->subject->getField('flags') & 0x1000 && !$this->subject->getField('parentArea')) { $infobox[] = Lang::zone('autoRez'); } // Level if ($_ = $this->subject->getField('levelMin')) { if ($_ < $this->subject->getField('levelMax')) { $_ .= ' - ' . $this->subject->getField('levelMax'); } $infobox[] = Lang::game('level') . Lang::main('colon') . $_; } // required Level if ($_ = $this->subject->getField('levelReq')) { if ($__ = $this->subject->getField('levelReqLFG')) { $buff = sprintf(Lang::zone('reqLevels'), $_, $__); } else { $buff = Lang::main('_reqLevel') . Lang::main('colon') . $_; } $infobox[] = $buff; } // Territory $_ = $this->subject->getField('faction'); $__ = '%s'; if ($_ == 0) { $__ = '[span class=icon-alliance]%s[/span]'; } else { if ($_ == 1) { $__ = '[span class=icon-horde]%s[/span]'; } else { if ($_ == 4) { $__ = '[span class=icon-ffa]%s[/span]'; } } } $infobox[] = Lang::zone('territory') . Lang::main('colon') . sprintf($__, Lang::zone('territories', $_)); // Instance Type $infobox[] = Lang::zone('instanceType') . Lang::main('colon') . '[span class=icon-instance' . $this->subject->getField('type') . ']' . Lang::zone('instanceTypes', $this->subject->getField('type')) . '[/span]'; // Heroic mode if ($_ = $this->subject->getField('levelHeroic')) { $infobox[] = '[icon preset=heroic]' . sprintf(Lang::zone('hcAvailable'), $_) . '[/icon]'; } // number of players if ($_ = $this->subject->getField('maxPlayer')) { $infobox[] = Lang::zone('numPlayers') . Lang::main('colon') . ($_ == -2 ? '10/25' : $_); } // Attunement Quest/Achievements & Keys if ($attmnt = $this->subject->getField('attunes')) { foreach ($attmnt as $type => $ids) { $this->extendGlobalIds($type, array_map('abs', $ids)); foreach ($ids as $id) { if ($type == TYPE_ITEM) { $infobox[] = Lang::zone('key', (int) ($id < 0)) . Lang::main('colon') . '[item=' . abs($id) . ']'; } else { $infobox[] = Lang::zone('attunement', (int) ($id < 0)) . Lang::main('colon') . '[' . Util::$typeStrings[$type] . '=' . abs($id) . ']'; } } } } // Instances if ($_ = DB::Aowow()->selectCol('SELECT id FROM ?_zones WHERE parentAreaId = ?d AND (flags & ?d) = 0', $this->typeId, CUSTOM_EXCLUDE_FOR_LISTVIEW)) { $this->extendGlobalIds(TYPE_ZONE, $_); $infobox[] = Lang::maps('Instances') . Lang::main('colon') . "\n[zone=" . implode("], \n[zone=", $_) . ']'; } // location (if instance) if ($pa = $this->subject->getField('parentAreaId')) { $paO = new ZoneList(array(['id', $pa])); if (!$paO->error) { $pins = str_pad($this->subject->getField('parentX') * 10, 3, '0', STR_PAD_LEFT) . str_pad($this->subject->getField('parentY') * 10, 3, '0', STR_PAD_LEFT); $infobox[] = Lang::zone('location') . Lang::main('colon') . '[lightbox=map zone=' . $pa . ' pins=' . $pins . ']' . $paO->getField('name', true) . '[/lightbox]'; } } /* has to be defined in an article, i think // faction(s) / Reputation Hub / Raid Faction // [li]Raid faction: [faction=1156][/li] || [li]Factions: [faction=1156]/[faction=1156][/li] // final boss // [li]Final boss: [icon preset=boss][npc=37226][/icon][/li] */ /****************/ /* Main Content */ /****************/ $addToMap = function ($what, $entry) use(&$som) { // entry always contains: type, id, name, level, coords[] if (!isset($som[$what][$entry['name']])) { // not found yet $som[$what][$entry['name']][] = $entry; } else { // check for identical floors foreach ($som[$what][$entry['name']] as &$byFloor) { if ($byFloor['level'] != $entry['level']) { continue; } // found existing floor, ammending coords $byFloor['coords'][] = $entry['coords'][0]; break; } // floor not used yet, create it $som[$what][$entry['name']][] = $entry; } }; if ($_ = $this->subject->getField('parentArea')) { $this->extraText = sprintf(Lang::zone('zonePartOf'), $_); $this->extendGlobalIds(TYPE_ZONE, $_); } // we cannot fetch spawns via lists. lists are grouped by entry $oSpawns = DB::Aowow()->select('SELECT * FROM ?_spawns WHERE areaId = ?d AND type = ?d', $this->typeId, TYPE_OBJECT); $cSpawns = DB::Aowow()->select('SELECT * FROM ?_spawns WHERE areaId = ?d AND type = ?d', $this->typeId, TYPE_NPC); $conditions = [CFG_SQL_LIMIT_NONE, ['s.areaId', $this->typeId]]; if (!User::isInGroup(U_GROUP_STAFF)) { $conditions[] = [['cuFlags', CUSTOM_EXCLUDE_FOR_LISTVIEW, '&'], 0]; } $objectSpawns = new GameObjectList($conditions); $creatureSpawns = new CreatureList($conditions); $questsLV = $rewardsLV = []; // see if we can actually display a map $hasMap = file_exists('static/images/wow/maps/' . Util::$localeStrings[User::$localeId] . '/normal/' . $this->typeId . '.jpg'); if (!$hasMap) { // try multilayered $hasMap = file_exists('static/images/wow/maps/' . Util::$localeStrings[User::$localeId] . '/normal/' . $this->typeId . '-1.jpg'); } if (!$hasMap) { // try english fallback $hasMap = file_exists('static/images/wow/maps/enus/normal/' . $this->typeId . '.jpg'); } if (!$hasMap) { // try english fallback, multilayered $hasMap = file_exists('static/images/wow/maps/enus/normal/' . $this->typeId . '-1.jpg'); } if ($hasMap) { $som = []; foreach ($oSpawns as $spawn) { $tpl = $objectSpawns->getEntry($spawn['typeId']); if (!$tpl) { continue; } $n = Util::localizedString($tpl, 'name'); $what = ''; switch ($tpl['typeCat']) { case -3: $what = 'herb'; break; case -4: $what = 'vein'; break; case 9: $what = 'book'; break; case -6: if ($tpl['spellFocusId'] == 1) { $what = 'anvil'; } else { if ($tpl['spellFocusId'] == 3) { $what = 'forge'; } } break; } if ($what) { $addToMap($what, array('coords' => [[$spawn['posX'], $spawn['posY']]], 'level' => $spawn['floor'], 'name' => $n, 'type' => TYPE_OBJECT, 'id' => $tpl['id'])); } if ($tpl['startsQuests']) { $started = new QuestList(array(['qse.method', 1, '&'], ['qse.type', TYPE_OBJECT], ['qse.typeId', $tpl['id']])); if ($started->error) { continue; } // store data for misc tabs foreach ($started->getListviewData() as $id => $data) { if (!empty($started->rewards[$id][TYPE_ITEM])) { $rewardsLV = array_merge($rewardsLV, array_keys($started->rewards[$id][TYPE_ITEM])); } if (!empty($started->choices[$id][TYPE_ITEM])) { $rewardsLV = array_merge($rewardsLV, array_keys($started->choices[$id][TYPE_ITEM])); } $questsLV[$id] = $data; } $this->extendGlobalData($started->getJSGlobals(GLOBALINFO_SELF | GLOBALINFO_REWARDS)); if ($tpl['A'] != -1 & ($_ = $started->getSOMData(SIDE_ALLIANCE))) { $addToMap('alliancequests', array('coords' => [[$spawn['posX'], $spawn['posY']]], 'level' => $spawn['floor'], 'name' => $n, 'type' => TYPE_OBJECT, 'id' => $tpl['id'], 'side' => ($tpl['A'] < 0 ? 0 : 0x1) | ($tpl['H'] < 0 ? 0 : 0x2), 'quests' => array_values($_))); } if ($tpl['H'] != -1 & ($_ = $started->getSOMData(SIDE_HORDE))) { $addToMap('hordequests', array('coords' => [[$spawn['posX'], $spawn['posY']]], 'level' => $spawn['floor'], 'name' => $n, 'type' => TYPE_OBJECT, 'id' => $tpl['id'], 'side' => ($tpl['A'] < 0 ? 0 : 0x1) | ($tpl['H'] < 0 ? 0 : 0x2), 'quests' => array_values($_))); } } } $flightNodes = []; foreach ($cSpawns as $spawn) { $tpl = $creatureSpawns->getEntry($spawn['typeId']); if (!$tpl) { continue; } $n = Util::localizedString($tpl, 'name'); $sn = Util::localizedString($tpl, 'subname'); $what = ''; if ($tpl['npcflag'] & NPC_FLAG_REPAIRER) { $what = 'repair'; } else { if ($tpl['npcflag'] & NPC_FLAG_AUCTIONEER) { $what = 'auctioneer'; } else { if ($tpl['npcflag'] & NPC_FLAG_BANKER) { $what = 'banker'; } else { if ($tpl['npcflag'] & NPC_FLAG_BATTLEMASTER) { $what = 'battlemaster'; } else { if ($tpl['npcflag'] & NPC_FLAG_INNKEEPER) { $what = 'innkeeper'; } else { if ($tpl['npcflag'] & NPC_FLAG_TRAINER) { $what = 'trainer'; } else { if ($tpl['npcflag'] & NPC_FLAG_VENDOR) { $what = 'vendor'; } else { if ($tpl['npcflag'] & NPC_FLAG_FLIGHT_MASTER) { $flightNodes[$tpl['id']] = [$spawn['posX'], $spawn['posY']]; $what = 'flightmaster'; } else { if ($tpl['npcflag'] & NPC_FLAG_STABLE_MASTER) { $what = 'stablemaster'; } else { if ($tpl['npcflag'] & NPC_FLAG_GUILD_MASTER) { $what = 'guildmaster'; } else { if ($tpl['npcflag'] & (NPC_FLAG_SPIRIT_HEALER | NPC_FLAG_SPIRIT_GUIDE)) { $what = 'spirithealer'; } else { if ($creatureSpawns->isBoss()) { $what = 'boss'; } else { if ($tpl['rank'] == 2 || $tpl['rank'] == 4) { $what = 'rare'; } } } } } } } } } } } } } if ($what) { $addToMap($what, array('coords' => [[$spawn['posX'], $spawn['posY']]], 'level' => $spawn['floor'], 'name' => $n, 'type' => TYPE_NPC, 'id' => $tpl['id'], 'reacthorde' => $tpl['H'] ?: 1, 'reactalliance' => $tpl['A'] ?: 1, 'description' => $sn)); } if ($tpl['startsQuests']) { $started = new QuestList(array(['qse.method', 1, '&'], ['qse.type', TYPE_NPC], ['qse.typeId', $tpl['id']])); if ($started->error) { continue; } // store data for misc tabs foreach ($started->getListviewData() as $id => $data) { if (!empty($started->rewards[$id][TYPE_ITEM])) { $rewardsLV = array_merge($rewardsLV, array_keys($started->rewards[$id][TYPE_ITEM])); } if (!empty($started->choices[$id][TYPE_ITEM])) { $rewardsLV = array_merge($rewardsLV, array_keys($started->choices[$id][TYPE_ITEM])); } $questsLV[$id] = $data; } if ($tpl['A'] != -1 & ($_ = $started->getSOMData(SIDE_ALLIANCE))) { $addToMap('alliancequests', array('coords' => [[$spawn['posX'], $spawn['posY']]], 'level' => $spawn['floor'], 'name' => $n, 'type' => TYPE_NPC, 'id' => $tpl['id'], 'reacthorde' => $tpl['H'], 'reactalliance' => $tpl['A'], 'side' => ($tpl['A'] < 0 ? 0 : SIDE_ALLIANCE) | ($tpl['H'] < 0 ? 0 : SIDE_HORDE), 'quests' => array_values($_))); } if ($tpl['H'] != -1 & ($_ = $started->getSOMData(SIDE_HORDE))) { $addToMap('hordequests', array('coords' => [[$spawn['posX'], $spawn['posY']]], 'level' => $spawn['floor'], 'name' => $n, 'type' => TYPE_NPC, 'id' => $tpl['id'], 'reacthorde' => $tpl['H'], 'reactalliance' => $tpl['A'], 'side' => ($tpl['A'] < 0 ? 0 : SIDE_ALLIANCE) | ($tpl['H'] < 0 ? 0 : SIDE_HORDE), 'quests' => array_values($_))); } } } // remove unwanted indizes foreach ($som as $what => &$dataz) { if (empty($som[$what])) { continue; } foreach ($dataz as &$data) { $data = array_values($data); } if (!in_array($what, ['vein', 'herb', 'rare'])) { $foo = []; foreach ($dataz as $d) { foreach ($d as $_) { $foo[] = $_; } } $dataz = $foo; } } // append paths between nodes if ($flightNodes) { // neutral nodes come last as the line is colored by the node it's attached to usort($som['flightmaster'], function ($a, $b) { $n1 = $a['reactalliance'] == $a['reacthorde']; $n2 = $b['reactalliance'] == $b['reacthorde']; if ($n1 && !$n2) { return 1; } if (!$n1 && $n2) { return -1; } return 0; }); $paths = DB::Aowow()->select('SELECT n1.typeId AS "0", n2.typeId AS "1" FROM ?_taxipath p JOIN ?_taxinodes n1 ON n1.id = p.startNodeId JOIN ?_taxinodes n2 ON n2.id = p.endNodeId WHERE n1.typeId IN (?a) AND n2.typeId IN (?a)', array_keys($flightNodes), array_keys($flightNodes)); foreach ($paths as $k => $path) { foreach ($som['flightmaster'] as &$fm) { if ($fm['id'] != $path[0] && $fm['id'] != $path[1]) { continue; } if ($fm['id'] == $path[0]) { $fm['paths'][] = $flightNodes[$path[1]]; } if ($fm['id'] == $path[1]) { $fm['paths'][] = $flightNodes[$path[0]]; } unset($paths[$k]); break; } } } // preselect bosses for raids/dungeons if (in_array($this->subject->getField('type'), [2, 3, 4, 5, 7, 8])) { $som['instance'] = true; } $this->map = array('data' => ['parent' => 'mapper-generic', 'zone' => $this->typeId], 'som' => $som); } else { $this->map = false; } $this->infobox = $infobox ? '[ul][li]' . implode('[/li][li]', $infobox) . '[/li][/ul]' : null; $this->expansion = Util::$expansionString[$this->subject->getField('expansion')]; $this->redButtons = array(BUTTON_WOWHEAD => true, BUTTON_LINKS => true); /* - associated with holiday? */ /**************/ /* Extra Tabs */ /**************/ // tab: NPCs if ($cSpawns && !$creatureSpawns->error) { $lvData = array('file' => 'creature', 'data' => $creatureSpawns->getListviewData(), 'params' => ['note' => sprintf(Util::$filterResultString, '?npcs&filter=cr=6;crs=' . $this->typeId . ';crv=0')]); if ($creatureSpawns->getMatches() > CFG_SQL_LIMIT_DEFAULT) { $lvData['params']['_truncated'] = 1; } $this->extendGlobalData($creatureSpawns->getJSGlobals(GLOBALINFO_SELF)); $this->lvTabs[] = $lvData; } // tab: Objects if ($oSpawns && !$objectSpawns->error) { $lvData = array('file' => 'object', 'data' => $objectSpawns->getListviewData(), 'params' => ['note' => sprintf(Util::$filterResultString, '?objects&filter=cr=1;crs=' . $this->typeId . ';crv=0')]); if ($objectSpawns->getMatches() > CFG_SQL_LIMIT_DEFAULT) { $lvData['params']['_truncated'] = 1; } $this->extendGlobalData($objectSpawns->getJSGlobals(GLOBALINFO_SELF)); $this->lvTabs[] = $lvData; } // tab: Quests [data collected by SOM-routine] if ($questsLV) { $this->lvTabs[] = array('file' => 'quest', 'data' => $questsLV, 'params' => ['note' => '$$WH.sprintf(LANG.lvnote_zonequests, ' . $this->subject->getField('mapId') . ', ' . $this->typeId . ', \'' . Util::jsEscape($this->subject->getField('name', true)) . '\', ' . $this->typeId . ')']); } // tab: item-quest starter // select every quest starter, that is a drop $questStartItem = DB::Aowow()->select(' SELECT qse.typeId AS ARRAY_KEY, moreType, moreTypeId, moreZoneId FROM ?_quests_startend qse JOIN ?_source src ON src.type = qse.type AND src.typeId = qse.typeId WHERE src.src2 IS NOT NULL AND qse.type = ?d AND (moreZoneId = ?d OR (moreType = ?d AND moreTypeId IN (?a)) OR (moreType = ?d AND moreTypeId IN (?a)))', TYPE_ITEM, $this->typeId, TYPE_NPC, array_unique(array_column($cSpawns, 'typeId')) ?: [0], TYPE_OBJECT, array_unique(array_column($oSpawns, 'typeId')) ?: [0]); if ($questStartItem) { $qsiList = new ItemList(array(['id', array_keys($questStartItem)])); if (!$qsiList->error) { $this->lvTabs[] = array('file' => 'item', 'data' => $qsiList->getListviewData(), 'params' => ['name' => '$LANG.tab_startsquest', 'id' => 'starts-quest']); $this->extendGlobalData($qsiList->getJSGlobals(GLOBALINFO_SELF)); } } // tab: Quest Rewards [ids collected by SOM-routine] if ($rewardsLV) { $rewards = new ItemList(array(['id', array_unique($rewardsLV)])); if (!$rewards->error) { $this->lvTabs[] = array('file' => 'item', 'data' => $rewards->getListviewData(), 'params' => ['name' => '$LANG.tab_questrewards', 'id' => 'quest-rewards', 'note' => sprintf(Util::$filterResultString, '?items&filter=cr=126;crs=' . $this->typeId . ';crv=0')]); $this->extendGlobalData($rewards->getJSGlobals(GLOBALINFO_SELF)); } } // tab: achievements // tab: fished in zone $fish = new Loot(); if ($fish->getByContainer(LOOT_FISHING, $this->typeId)) { $this->extendGlobalData($fish->jsGlobals); $xCols = array_merge(['Listview.extraCols.percent'], $fish->extraCols); foreach ($fish->iterate() as $lv) { if (!$lv['quest']) { continue; } $xCols = array_merge($xCols, ['Listview.extraCols.condition']); $reqQuest[$lv['id']] = 0; $lv['condition'][0][$this->typeId][] = [[CND_QUESTTAKEN, &$reqQuest[$lv['id']]]]; } $this->lvTabs[] = array('file' => 'item', 'data' => $fish->getResult(), 'params' => ['name' => '$LANG.tab_fishing', 'id' => 'fishing', 'extraCols' => $xCols ? "\$[" . implode(', ', array_unique($xCols)) . "]" : null, 'hiddenCols' => "\$['side']"]); } // tab: spells if ($saData = DB::World()->select('SELECT * FROM spell_area WHERE area = ?d', $this->typeId)) { $spells = new SpellList(array(['id', array_column($saData, 'spell')])); if (!$spells->error) { $lvSpells = $spells->getListviewData(); $this->extendGlobalData($spells->getJSGlobals()); $extra = false; foreach ($saData as $a) { if (empty($lvSpells[$a['spell']])) { continue; } $condition = []; if ($a['aura_spell']) { $this->extendGlobalIds(TYPE_SPELL, abs($a['aura_spell'])); $condition[0][$this->typeId][] = [[$a['aura_spell'] > 0 ? CND_AURA : -CND_AURA, abs($a['aura_spell'])]]; } if ($a['quest_start']) { $this->extendGlobalIds(TYPE_QUEST, $a['quest_start']); $group = []; for ($i = 0; $i < 7; $i++) { if (!($a['quest_start_status'] & 1 << $i)) { continue; } if ($i == 0) { $group[] = [CND_QUEST_NONE, $a['quest_start']]; } else { if ($i == 1) { $group[] = [CND_QUEST_COMPLETE, $a['quest_start']]; } else { if ($i == 3) { $group[] = [CND_QUESTTAKEN, $a['quest_start']]; } else { if ($i == 6) { $group[] = [CND_QUESTREWARDED, $a['quest_start']]; } } } } } if ($group) { $condition[0][$this->typeId][] = $group; } } if ($a['quest_end'] && $a['quest_end'] != $a['quest_start']) { $this->extendGlobalIds(TYPE_QUEST, $a['quest_end']); $group = []; for ($i = 0; $i < 7; $i++) { if (!($a['quest_end_status'] & 1 << $i)) { continue; } if ($i == 0) { $group[] = [-CND_QUEST_NONE, $a['quest_end']]; } else { if ($i == 1) { $group[] = [-CND_QUEST_COMPLETE, $a['quest_end']]; } else { if ($i == 3) { $group[] = [-CND_QUESTTAKEN, $a['quest_end']]; } else { if ($i == 6) { $group[] = [-CND_QUESTREWARDED, $a['quest_end']]; } } } } } if ($group) { $condition[0][$this->typeId][] = $group; } } if ($a['racemask']) { $foo = []; for ($i = 0; $i < 11; $i++) { if ($a['racemask'] & 1 << $i) { $foo[] = $i + 1; } } $this->extendGlobalIds(TYPE_RACE, $foo); $condition[0][$this->typeId][] = [[CND_RACE, $a['racemask']]]; } if ($a['gender'] != 2) { // 2: both $condition[0][$this->typeId][] = [[CND_GENDER, $a['gender'] + 1]]; } if ($condition) { $extra = true; $lvSpells[$a['spell']] = array_merge($lvSpells[$a['spell']], ['condition' => $condition]); } } $this->lvTabs[] = array('file' => 'spell', 'data' => $lvSpells, 'params' => array('extraCols' => $extra ? '$[Listview.extraCols.condition]' : null, 'hiddenCols' => "\$['skill']")); } } // tab: subzones $subZones = new ZoneList(array(['parentArea', $this->typeId])); if (!$subZones->error) { $this->lvTabs[] = array('file' => 'zone', 'data' => $subZones->getListviewData(), 'params' => ['name' => '$LANG.tab_zones', 'id' => 'subzones', 'hiddenCols' => "\$['territory', 'instancetype']"]); $this->extendGlobalData($subZones->getJSGlobals(GLOBALINFO_SELF)); } }