예제 #1
0
파일: search.php 프로젝트: Niknox/aowow
 private function _searchAchievement($cndBase)
 {
     $result = [];
     $cnd = array_merge($cndBase, array([['flags', ACHIEVEMENT_FLAG_COUNTER, '&'], 0], $this->createLookup()));
     $acvs = new AchievementList($cnd);
     if ($data = $acvs->getListviewData()) {
         if ($this->searchMask & SEARCH_TYPE_REGULAR) {
             $this->extendGlobalData($acvs->getJSGlobals());
         }
         if ($this->searchMask & SEARCH_TYPE_OPEN) {
             foreach ($acvs->iterate() as $__) {
                 $data[$acvs->id]['param1'] = strToLower($acvs->getField('iconString'));
             }
         }
         $result = array('type' => TYPE_ACHIEVEMENT, 'appendix' => ' (Achievement)', 'matches' => $acvs->getMatches(), 'file' => AchievementList::$brickFile, 'data' => $data, 'params' => ['visibleCols' => "\$['category']"]);
         if ($acvs->getMatches() > $this->maxResults) {
             $result['params']['note'] = sprintf(Util::$tryNarrowingString, 'LANG.lvnote_achievementsfound', $acvs->getMatches(), $this->maxResults);
             $result['params']['_truncated'] = 1;
         }
         if (isset($result['params']['note'])) {
             $result['params']['note'] .= ' + LANG.dash + $WH.sprintf(LANG.lvnote_filterresults, \'?achieveemnts&filter=na=' . urlencode($this->search) . '\')';
         } else {
             $result['params']['note'] = '$$WH.sprintf(LANG.lvnote_filterresults, \'?achievements&filter=na=' . urlencode($this->search) . '\')';
         }
     }
     return $result;
 }
예제 #2
0
파일: quest.php 프로젝트: Niknox/aowow
 protected function generateContent()
 {
     $_level = $this->subject->getField('level');
     $_minLevel = $this->subject->getField('minLevel');
     $_flags = $this->subject->getField('flags');
     $_specialFlags = $this->subject->getField('specialFlags');
     $_side = Util::sideByRaceMask($this->subject->getField('reqRaceMask'));
     /***********/
     /* Infobox */
     /***********/
     $infobox = Lang::getInfoBoxForFlags($this->subject->getField('cuFlags'));
     // event (todo: assign eventData)
     if ($_ = $this->subject->getField('eventId')) {
         $this->extendGlobalIds(TYPE_WORLDEVENT, $_);
         $infobox[] = Lang::game('eventShort') . Lang::main('colon') . '[event=' . $_ . ']';
     }
     // level
     if ($_level > 0) {
         $infobox[] = Lang::game('level') . Lang::main('colon') . $_level;
     }
     // reqlevel
     if ($_minLevel) {
         $lvl = $_minLevel;
         if ($_ = $this->subject->getField('maxLevel')) {
             $lvl .= ' - ' . $_;
         }
         $infobox[] = sprintf(Lang::game('reqLevel'), $lvl);
     }
     // loremaster (i dearly hope those flags cover every case...)
     if ($this->subject->getField('zoneOrSortBak') > 0 && !$this->subject->isRepeatable()) {
         $conditions = array(['ac.type', ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_IN_ZONE], ['ac.value1', $this->subject->getField('zoneOrSortBak')], ['a.faction', $_side, '&']);
         $loremaster = new AchievementList($conditions);
         $this->extendGlobalData($loremaster->getJSGlobals(GLOBALINFO_SELF));
         switch ($loremaster->getMatches()) {
             case 0:
                 break;
             case 1:
                 $infobox[] = Lang::quest('loremaster') . Lang::main('colon') . '[achievement=' . $loremaster->id . ']';
                 break;
             default:
                 $lm = Lang::quest('loremaster') . Lang::main('colon') . '[ul]';
                 foreach ($loremaster->iterate() as $id => $__) {
                     $lm .= '[li][achievement=' . $id . '][/li]';
                 }
                 $infobox[] = $lm . '[/ul]';
                 break;
         }
     }
     // type (maybe expand uppon?)
     $_ = [];
     if ($_flags & QUEST_FLAG_DAILY) {
         $_[] = Lang::quest('daily');
     } else {
         if ($_flags & QUEST_FLAG_WEEKLY) {
             $_[] = Lang::quest('weekly');
         } else {
             if ($_specialFlags & QUEST_FLAG_SPECIAL_MONTHLY) {
                 $_[] = Lang::quest('monthly');
             }
         }
     }
     if ($t = $this->subject->getField('type')) {
         $_[] = Lang::quest('questInfo', $t);
     }
     if ($_) {
         $infobox[] = Lang::game('type') . Lang::main('colon') . implode(' ', $_);
     }
     // side
     $_ = Lang::main('side') . Lang::main('colon');
     switch ($_side) {
         case 3:
             $infobox[] = $_ . Lang::game('si', 3);
             break;
         case 2:
             $infobox[] = $_ . '[span class=icon-horde]' . Lang::game('si', 2) . '[/span]';
             break;
         case 1:
             $infobox[] = $_ . '[span class=icon-alliance]' . Lang::game('si', 1) . '[/span]';
             break;
     }
     // races
     if ($_ = Lang::getRaceString($this->subject->getField('reqRaceMask'), $__, $jsg, $n, false)) {
         $this->extendGlobalIds(TYPE_RACE, $jsg);
         $t = $n == 1 ? Lang::game('race') : Lang::game('races');
         $infobox[] = Util::ucFirst($t) . Lang::main('colon') . $_;
     }
     // classes
     if ($_ = Lang::getClassString($this->subject->getField('reqClassMask'), $jsg, $n, false)) {
         $this->extendGlobalIds(TYPE_CLASS, $jsg);
         $t = $n == 1 ? Lang::game('class') : Lang::game('classes');
         $infobox[] = Util::ucFirst($t) . Lang::main('colon') . $_;
     }
     // profession / skill
     if ($_ = $this->subject->getField('reqSkillId')) {
         $this->extendGlobalIds(TYPE_SKILL, $_);
         $sk = '[skill=' . $_ . ']';
         if ($_ = $this->subject->getField('reqSkillPoints')) {
             $sk .= ' (' . $_ . ')';
         }
         $infobox[] = Lang::quest('profession') . Lang::main('colon') . $sk;
     }
     // timer
     if ($_ = $this->subject->getField('timeLimit')) {
         $infobox[] = Lang::quest('timer') . Lang::main('colon') . Util::formatTime($_ * 1000);
     }
     $startEnd = DB::Aowow()->select('SELECT * FROM ?_quests_startend WHERE questId = ?d', $this->typeId);
     // start
     $start = '[icon name=quest_start' . ($this->subject->isDaily() ? '_daily' : '') . ']' . Lang::event('start') . Lang::main('colon') . '[/icon]';
     $s = [];
     foreach ($startEnd as $se) {
         if ($se['method'] & 0x1) {
             $this->extendGlobalIds($se['type'], $se['typeId']);
             $s[] = ($s ? '[span=invisible]' . $start . '[/span] ' : $start . ' ') . '[' . Util::$typeStrings[$se['type']] . '=' . $se['typeId'] . ']';
         }
     }
     if ($s) {
         $infobox[] = implode('[br]', $s);
     }
     // end
     $end = '[icon name=quest_end' . ($this->subject->isDaily() ? '_daily' : '') . ']' . Lang::event('end') . Lang::main('colon') . '[/icon]';
     $e = [];
     foreach ($startEnd as $se) {
         if ($se['method'] & 0x2) {
             $this->extendGlobalIds($se['type'], $se['typeId']);
             $e[] = ($e ? '[span=invisible]' . $end . '[/span] ' : $end . ' ') . '[' . Util::$typeStrings[$se['type']] . '=' . $se['typeId'] . ']';
         }
     }
     if ($e) {
         $infobox[] = implode('[br]', $e);
     }
     // Repeatable
     if ($_flags & QUEST_FLAG_REPEATABLE || $_specialFlags & QUEST_FLAG_SPECIAL_REPEATABLE) {
         $infobox[] = Lang::quest('repeatable');
     }
     // sharable | not sharable
     $infobox[] = $_flags & QUEST_FLAG_SHARABLE ? Lang::quest('sharable') : Lang::quest('notSharable');
     // Keeps you PvP flagged
     if ($this->subject->isPvPEnabled()) {
         $infobox[] = Lang::quest('keepsPvpFlag');
     }
     // difficulty (todo (low): formula unclear. seems to be [minLevel,] -4, -2, (level), +3, +(9 to 15))
     if ($_level > 0) {
         $_ = [];
         // red
         if ($_minLevel && $_minLevel < $_level - 4) {
             $_[] = '[color=q10]' . $_minLevel . '[/color]';
         }
         // orange
         if (!$_minLevel || $_minLevel < $_level - 2) {
             $_[] = '[color=r1]' . (!$_ && $_minLevel > $_level - 4 ? $_minLevel : $_level - 4) . '[/color]';
         }
         // yellow
         $_[] = '[color=r2]' . (!$_ && $_minLevel > $_level - 2 ? $_minLevel : $_level - 2) . '[/color]';
         // green
         $_[] = '[color=r3]' . ($_level + 3) . '[/color]';
         // grey (is about +/-1 level off)
         $_[] = '[color=r4]' . ($_level + 3 + ceil(12 * $_level / MAX_LEVEL)) . '[/color]';
         if ($_) {
             $infobox[] = Lang::game('difficulty') . Lang::main('colon') . implode('[small] &nbsp;[/small]', $_);
         }
     }
     $this->infobox = '[ul][li]' . implode('[/li][li]', $infobox) . '[/li][/ul]';
     /**********/
     /* Series */
     /**********/
     // Quest Chain (are there cases where quests go in parallel?)
     $chain = array(array(array('side' => $_side, 'typeStr' => Util::$typeStrings[TYPE_QUEST], 'typeId' => $this->typeId, 'name' => $this->name, '_next' => $this->subject->getField('nextQuestIdChain'))));
     $_ = $chain[0][0];
     while ($_) {
         if ($_ = DB::Aowow()->selectRow('SELECT id AS typeId, name_loc0, name_loc2, name_loc3, name_loc6, name_loc8, reqRaceMask FROM ?_quests WHERE nextQuestIdChain = ?d', $_['typeId'])) {
             $n = Util::localizedString($_, 'name');
             array_unshift($chain, array(array('side' => Util::sideByRaceMask($_['reqRaceMask']), 'typeStr' => Util::$typeStrings[TYPE_QUEST], 'typeId' => $_['typeId'], 'name' => strlen($n) > 40 ? substr($n, 0, 40) . '…' : $n)));
         }
     }
     $_ = end($chain)[0];
     while ($_) {
         if ($_ = DB::Aowow()->selectRow('SELECT id AS typeId, name_loc0, name_loc2, name_loc3, name_loc6, name_loc8, reqRaceMask, nextQuestIdChain AS _next FROM ?_quests WHERE id = ?d', $_['_next'])) {
             $n = Util::localizedString($_, 'name');
             array_push($chain, array(array('side' => Util::sideByRaceMask($_['reqRaceMask']), 'typeStr' => Util::$typeStrings[TYPE_QUEST], 'typeId' => $_['typeId'], 'name' => strlen($n) > 40 ? substr($n, 0, 40) . '…' : $n, '_next' => $_['_next'])));
         }
     }
     if (count($chain) > 1) {
         $this->series[] = [$chain, null];
     }
     // todo (low): sensibly merge the following lists into 'series'
     $listGen = function ($cnd) {
         $chain = [];
         $list = new QuestList($cnd);
         if ($list->error) {
             return null;
         }
         foreach ($list->iterate() as $id => $__) {
             $n = $list->getField('name', true);
             $chain[] = array(array('side' => Util::sideByRaceMask($list->getField('reqRaceMask')), 'typeStr' => Util::$typeStrings[TYPE_QUEST], 'typeId' => $id, 'name' => strlen($n) > 40 ? substr($n, 0, 40) . '…' : $n));
         }
         return $chain;
     };
     $extraLists = array(['reqQ', array('OR', ['AND', ['nextQuestId', $this->typeId], ['exclusiveGroup', 0, '<']], ['AND', ['id', $this->subject->getField('prevQuestId')], ['nextQuestIdChain', $this->typeId, '!']])], ['reqOneQ', array(['exclusiveGroup', 0, '>'], ['nextQuestId', $this->typeId])], ['opensQ', array('OR', ['AND', ['prevQuestId', $this->typeId], ['id', $this->subject->getField('nextQuestIdChain'), '!']], ['id', $this->subject->getField('nextQuestId')])], ['closesQ', array(['exclusiveGroup', 0, '!'], ['exclusiveGroup', $this->subject->getField('exclusiveGroup')], ['id', $this->typeId, '!'])], ['enablesQ', array(['prevQuestId', -$this->typeId])], ['enabledByQ', array(['id', -$this->subject->getField('prevQuestId')])]);
     foreach ($extraLists as $el) {
         if ($_ = $listGen($el[1])) {
             $this->series[] = [$_, sprintf(Util::$dfnString, Lang::quest($el[0] . 'Desc'), Lang::quest($el[0]))];
         }
     }
     /*******************/
     /* Objectives List */
     /*******************/
     $this->objectiveList = [];
     $this->providedItem = [];
     // gather ids for lookup
     $olItems = $olNPCs = $olGOs = $olFactions = [];
     // items
     $olItems[0] = array($this->subject->getField('sourceItemId'), $this->subject->getField('sourceItemCount'), false);
     for ($i = 1; $i < 7; $i++) {
         $id = $this->subject->getField('reqItemId' . $i);
         $qty = $this->subject->getField('reqItemCount' . $i);
         if (!$id || !$qty) {
             continue;
         }
         $olItems[$i] = [$id, $qty, $id == $olItems[0][0]];
     }
     if ($ids = array_column($olItems, 0)) {
         $olItemData = new ItemList(array(['id', $ids]));
         $this->extendGlobalData($olItemData->getJSGlobals(GLOBALINFO_SELF));
         $providedRequired = false;
         foreach ($olItems as $i => list($itemId, $qty, $provided)) {
             if (!$i || !$itemId || !in_array($itemId, $olItemData->getFoundIDs())) {
                 continue;
             }
             if ($provided) {
                 $providedRequired = true;
             }
             $this->objectiveList[] = array('typeStr' => Util::$typeStrings[TYPE_ITEM], 'id' => $itemId, 'name' => $olItemData->json[$itemId]['name'], 'qty' => $qty > 1 ? $qty : 0, 'quality' => 7 - $olItemData->json[$itemId]['quality'], 'extraText' => $provided ? '&nbsp;(' . Lang::quest('provided') . ')' : '');
         }
         // if providd item is not required by quest, list it below other requirements
         if (!$providedRequired && $olItems[0][0] && in_array($olItems[0][0], $olItemData->getFoundIDs())) {
             $this->providedItem = array('id' => $olItems[0][0], 'name' => $olItemData->json[$olItems[0][0]]['name'], 'qty' => $olItems[0][1] > 1 ? $olItems[0][1] : 0, 'quality' => 7 - $olItemData->json[$olItems[0][0]]['quality']);
         }
     }
     // creature or GO...
     for ($i = 1; $i < 5; $i++) {
         $id = $this->subject->getField('reqNpcOrGo' . $i);
         $qty = $this->subject->getField('reqNpcOrGoCount' . $i);
         $altTxt = $this->subject->getField('objectiveText' . $i, true);
         if ($id > 0 && $qty) {
             $olNPCs[$id] = [$qty, $altTxt, []];
         } else {
             if ($id < 0 && $qty) {
                 $olGOs[-$id] = [$qty, $altTxt];
             }
         }
     }
     // .. creature kills
     if ($ids = array_keys($olNPCs)) {
         $olNPCData = new CreatureList(array('OR', ['id', $ids], ['killCredit1', $ids], ['killCredit2', $ids]));
         $this->extendGlobalData($olNPCData->getJSGlobals(GLOBALINFO_SELF));
         // create proxy-references
         foreach ($olNPCData->iterate() as $id => $__) {
             if ($p = $olNPCData->getField('KillCredit1')) {
                 if (isset($olNPCs[$p])) {
                     $olNPCs[$p][2][$id] = $olNPCData->getField('name', true);
                 }
             }
             if ($p = $olNPCData->getField('KillCredit2')) {
                 if (isset($olNPCs[$p])) {
                     $olNPCs[$p][2][$id] = $olNPCData->getField('name', true);
                 }
             }
         }
         foreach ($olNPCs as $i => $pair) {
             if (!$i || !in_array($i, $olNPCData->getFoundIDs())) {
                 continue;
             }
             $ol = array('typeStr' => Util::$typeStrings[TYPE_NPC], 'id' => $i, 'name' => $pair[1] ?: Util::localizedString($olNPCData->getEntry($i), 'name'), 'qty' => $pair[0] > 1 ? $pair[0] : 0, 'extraText' => $_specialFlags & QUEST_FLAG_SPECIAL_SPELLCAST || $pair[1] ? '' : ' ' . Lang::achievement('slain'), 'proxy' => $pair[2]);
             if ($pair[2]) {
                 // has proxies assigned, add yourself as another proxy
                 $ol['proxy'][$i] = Util::localizedString($olNPCData->getEntry($i), 'name');
             }
             $this->objectiveList[] = $ol;
         }
     }
     // .. GO interactions
     if ($ids = array_keys($olGOs)) {
         $olGOData = new GameObjectList(array(['id', $ids]));
         $this->extendGlobalData($olGOData->getJSGlobals(GLOBALINFO_SELF));
         foreach ($olNPCs as $i => $pair) {
             if (!$i || !in_array($i, $olGOData->getFoundIDs())) {
                 continue;
             }
             $this->objectiveList[] = array('typeStr' => Util::$typeStrings[TYPE_OBJECT], 'id' => $i, 'name' => $pair[1] ?: Util::localizedString($olGOData->getEntry($i), 'name'), 'qty' => $pair[0] > 1 ? $pair[0] : 0);
         }
     }
     // reputation required
     for ($i = 1; $i < 3; $i++) {
         $id = $this->subject->getField('reqFactionId' . $i);
         $val = $this->subject->getField('reqFactionValue' . $i);
         if (!$id) {
             continue;
         }
         $olFactions[$id] = $val;
     }
     if ($ids = array_keys($olFactions)) {
         $olFactionsData = new FactionList(array(['id', $ids]));
         $this->extendGlobalData($olFactionsData->getJSGlobals(GLOBALINFO_SELF));
         foreach ($olFactions as $i => $val) {
             if (!$i || !in_array($i, $olFactionsData->getFoundIDs())) {
                 continue;
             }
             $this->objectiveList[] = array('typeStr' => Util::$typeStrings[TYPE_FACTION], 'id' => $i, 'name' => Util::localizedString($olFactionsData->getEntry($i), 'name'), 'qty' => sprintf(Util::$dfnString, $val . ' ' . Lang::achievement('points'), Lang::getReputationLevelForPoints($val)), 'extraText' => '');
         }
     }
     // granted spell
     if ($_ = $this->subject->getField('sourceSpellId')) {
         $this->extendGlobalIds(TYPE_SPELL, $_);
         $this->objectiveList[] = array('typeStr' => Util::$typeStrings[TYPE_SPELL], 'id' => $_, 'name' => SpellList::getName($_), 'qty' => 0, 'extraText' => '&nbsp;(' . Lang::quest('provided') . ')');
     }
     // required money
     if ($this->subject->getField('rewardOrReqMoney') < 0) {
         $this->objectiveList[] = ['text' => Lang::quest('reqMoney') . Lang::main('colon') . Util::formatMoney(abs($this->subject->getField('rewardOrReqMoney')))];
     }
     // required pvp kills
     if ($_ = $this->subject->getField('reqPlayerKills')) {
         $this->objectiveList[] = ['text' => Lang::quest('playerSlain') . '&nbsp;(' . $_ . ')'];
     }
     /**********/
     /* Mapper */
     /**********/
     $this->addJS('?data=zones&locale=' . User::$localeId . '&t=' . $_SESSION['dataKey']);
     /*
         TODO (GODDAMNIT): jeez..
     */
     // $startend + reqNpcOrGo[1-4]
     $this->map = null;
     // array(
     // 'data' => ['zone' => $this->typeId],
     // 'som'  => Util::toJSON($som)
     // );
     /****************/
     /* Main Content */
     /****************/
     $this->gains = $this->createGains();
     $this->mail = $this->createMail($maTab, $startEnd);
     $this->rewards = $this->createRewards();
     $this->objectives = $this->subject->parseText('objectives', false);
     $this->details = $this->subject->parseText('details', false);
     $this->offerReward = $this->subject->parseText('offerReward', false);
     $this->requestItems = $this->subject->parseText('requestItems', false);
     $this->completed = $this->subject->parseText('completed', false);
     $this->end = $this->subject->parseText('end', false);
     $this->suggestedPl = $this->subject->getField('suggestedPlayers');
     $this->unavailable = $_flags & QUEST_FLAG_UNAVAILABLE || $this->subject->getField('cuFlags') & CUSTOM_EXCLUDE_FOR_LISTVIEW;
     $this->redButtons = array(BUTTON_LINKS => ['color' => 'ffffff00', 'linkId' => 'quest:' . $this->typeId . ':' . $_level . ''], BUTTON_WOWHEAD => true);
     if ($maTab) {
         $this->lvTabs[] = $maTab;
     }
     // factionchange-equivalent
     if ($pendant = DB::World()->selectCell('SELECT IF(horde_id = ?d, alliance_id, -horde_id) FROM player_factionchange_quests WHERE alliance_id = ?d OR horde_id = ?d', $this->typeId, $this->typeId, $this->typeId)) {
         $altQuest = new QuestList(array(['id', abs($pendant)]));
         if (!$altQuest->error) {
             $this->transfer = sprintf(Lang::quest('_transfer'), $altQuest->id, $altQuest->getField('name', true), $pendant > 0 ? 'alliance' : 'horde', $pendant > 0 ? Lang::game('si', 1) : Lang::game('si', 2));
         }
     }
     /**************/
     /* Extra Tabs */
     /**************/
     // tab: see also
     $seeAlso = new QuestList(array(['name_loc' . User::$localeId, '%' . $this->name . '%'], ['id', $this->typeId, '!']));
     if (!$seeAlso->error) {
         $this->extendGlobalData($seeAlso->getJSGlobals());
         $this->lvTabs[] = array('file' => 'quest', 'data' => $seeAlso->getListviewData(), 'params' => array('name' => '$LANG.tab_seealso', 'id' => 'see-also'));
     }
     // tab: criteria of
     $criteriaOf = new AchievementList(array(['ac.type', ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST], ['ac.value1', $this->typeId]));
     if (!$criteriaOf->error) {
         $this->extendGlobalData($criteriaOf->getJSGlobals());
         $this->lvTabs[] = array('file' => 'achievement', 'data' => $criteriaOf->getListviewData(), 'params' => array('name' => '$LANG.tab_criteriaof', 'id' => 'criteria-of'));
     }
     // tab: conditions
     $cnd = [];
     if ($_ = $this->subject->getField('reqMinRepFaction')) {
         $cnd[CND_SRC_QUEST_ACCEPT][$this->typeId][0][] = [CND_REPUTATION_RANK, $_, 1 << Util::getReputationLevelForPoints($this->subject->getField('reqMinRepValue'))];
         $this->extendGlobalIds(TYPE_FACTION, $_);
     }
     if ($_ = $this->subject->getField('reqMaxRepFaction')) {
         $cnd[CND_SRC_QUEST_ACCEPT][$this->typeId][0][] = [-CND_REPUTATION_RANK, $_, 1 << Util::getReputationLevelForPoints($this->subject->getField('reqMaxRepValue'))];
         $this->extendGlobalIds(TYPE_FACTION, $_);
     }
     $_ = Util::getServerConditions([CND_SRC_QUEST_ACCEPT, CND_SRC_QUEST_SHOW_MARK], null, $this->typeId);
     if (!empty($_[0])) {
         // awkward merger
         if (isset($_[0][CND_SRC_QUEST_ACCEPT][$this->typeId][0])) {
             if (isset($cnd[CND_SRC_QUEST_ACCEPT][$this->typeId][0])) {
                 $cnd[CND_SRC_QUEST_ACCEPT][$this->typeId][0] = array_merge($cnd[CND_SRC_QUEST_ACCEPT][$this->typeId][0], $_[0][CND_SRC_QUEST_ACCEPT][$this->typeId][0]);
             } else {
                 $cnd[CND_SRC_QUEST_ACCEPT] = $_[0][CND_SRC_QUEST_ACCEPT];
             }
         }
         if (isset($_[0][CND_SRC_QUEST_SHOW_MARK])) {
             $cnd[CND_SRC_QUEST_SHOW_MARK] = $_[0][CND_SRC_QUEST_SHOW_MARK];
         }
         $this->extendGlobalData($_[1]);
     }
     if ($cnd) {
         $tab = "<script type=\"text/javascript\">\n" . "var markup = ConditionList.createTab(" . Util::toJSON($cnd) . ");\n" . "Markup.printHtml(markup, 'tab-conditions', { allow: Markup.CLASS_STAFF })" . "</script>";
         $this->lvTabs[] = array('file' => null, 'data' => $tab, 'params' => array('id' => 'conditions', 'name' => '$LANG.requires'));
     }
 }
예제 #3
0
 private function _searchAchievement($cndBase)
 {
     $cnd = array_merge($cndBase, array([['flags', ACHIEVEMENT_FLAG_COUNTER, '&'], 0], $this->createLookup()));
     $acvs = new AchievementList($cnd);
     if ($data = $acvs->getListviewData()) {
         if ($this->searchMask & SEARCH_TYPE_REGULAR) {
             $this->extendGlobalData($acvs->getJSGlobals());
         }
         $osInfo = [TYPE_ACHIEVEMENT, ' (Achievement)', $acvs->getMatches(), []];
         $result = array('data' => array_values($data), 'visibleCols' => ['category']);
         if ($this->searchMask & SEARCH_TYPE_OPEN) {
             foreach ($acvs->iterate() as $id => $__) {
                 $osInfo[3][$id] = strToLower($acvs->getField('iconString'));
             }
         }
         if ($acvs->getMatches() > $this->maxResults) {
             $result['note'] = sprintf(Util::$tryNarrowingString, 'LANG.lvnote_achievementsfound', $acvs->getMatches(), $this->maxResults);
             $result['_truncated'] = 1;
         }
         if (isset($result['note'])) {
             $result['note'] .= ' + LANG.dash + $WH.sprintf(LANG.lvnote_filterresults, \'?achieveemnts&filter=na=' . urlencode($this->search) . '\')';
         } else {
             $result['note'] = '$$WH.sprintf(LANG.lvnote_filterresults, \'?achievements&filter=na=' . urlencode($this->search) . '\')';
         }
         return ['achievement', $result, null, $osInfo];
     }
     return false;
 }
예제 #4
0
 protected function generateContent()
 {
     /***********/
     /* Infobox */
     /***********/
     $infobox = Lang::getInfoBoxForFlags($this->subject->getField('cuFlags'));
     // points
     if ($_ = $this->subject->getField('points')) {
         $infobox[] = Lang::achievement('points') . Lang::main('colon') . '[achievementpoints=' . $_ . ']';
     }
     // location
     // todo (low)
     // faction
     switch ($this->subject->getField('faction')) {
         case 1:
             $infobox[] = Lang::main('side') . Lang::main('colon') . '[span class=icon-alliance]' . Lang::game('si', SIDE_ALLIANCE) . '[/span]';
             break;
         case 2:
             $infobox[] = Lang::main('side') . Lang::main('colon') . '[span class=icon-horde]' . Lang::game('si', SIDE_HORDE) . '[/span]';
             break;
         default:
             // case 3
             $infobox[] = Lang::main('side') . Lang::main('colon') . Lang::game('si', SIDE_BOTH);
     }
     // realm first available?
     if ($this->subject->getField('flags') & 0x100 && DB::isConnectable(DB_AUTH)) {
         $avlb = [];
         foreach (DB::Auth()->selectCol('SELECT id AS ARRAY_KEY, name FROM realmlist WHERE allowedSecurityLevel = 0 AND gamebuild = ?d', WOW_VERSION) as $rId => $name) {
             if (!DB::isConnectable(DB_CHARACTERS . $rId)) {
                 continue;
             }
             if (!DB::Characters($rId)->selectCell('SELECT 1 FROM character_achievement WHERE achievement = ?d LIMIT 1', $this->typeId)) {
                 $avlb[] = $name;
             }
         }
         if ($avlb) {
             $infobox[] = Lang::achievement('rfAvailable') . implode(', ', $avlb);
         }
     }
     /**********/
     /* Series */
     /**********/
     $series = [];
     if ($c = $this->subject->getField('chainId')) {
         $chainAcv = new AchievementList(array(['chainId', $c]));
         foreach ($chainAcv->iterate() as $aId => $__) {
             $pos = $chainAcv->getField('chainPos');
             if (!isset($series[$pos])) {
                 $series[$pos] = [];
             }
             $series[$pos][] = array('side' => $chainAcv->getField('faction'), 'typeStr' => Util::$typeStrings[TYPE_ACHIEVEMENT], 'typeId' => $aId, 'name' => $chainAcv->getField('name', true));
         }
     }
     /****************/
     /* Main Content */
     /****************/
     $this->mail = $this->createMail($reqBook);
     $this->headIcons = [$this->subject->getField('iconString')];
     $this->infobox = $infobox ? '[ul][li]' . implode('[/li][li]', $infobox) . '[/li][/ul]' : null;
     $this->series = $series ? [[$series, null]] : null;
     $this->description = $this->subject->getField('description', true);
     $this->redButtons = array(BUTTON_LINKS => ['color' => 'ffffff00', 'linkId' => Util::$typeStrings[TYPE_ACHIEVEMENT] . ':' . $this->typeId . ':&quot;..UnitGUID(&quot;player&quot;)..&quot;:0:0:0:0:0:0:0:0'], BUTTON_WOWHEAD => !($this->subject->getField('cuFlags') & CUSTOM_SERVERSIDE));
     $this->criteria = array('reqQty' => $this->subject->getField('reqCriteriaCount'), 'icons' => [], 'data' => []);
     if ($reqBook) {
         $this->addCss(['path' => 'Book.css']);
     }
     // create rewards
     if ($foo = $this->subject->getField('rewards')) {
         array_walk($foo, function (&$item) {
             $item = $item[0] != TYPE_ITEM ? null : $item[1];
         });
         $bar = new ItemList(array(['i.id', $foo]));
         foreach ($bar->iterate() as $id => $__) {
             $this->rewards['item'][] = array('name' => $bar->getField('name', true), 'quality' => $bar->getField('quality'), 'typeStr' => Util::$typeStrings[TYPE_ITEM], 'id' => $id, 'globalStr' => 'g_items');
         }
     }
     if ($foo = $this->subject->getField('rewards')) {
         array_walk($foo, function (&$item) {
             $item = $item[0] != TYPE_TITLE ? null : $item[1];
         });
         $bar = new TitleList(array(['id', $foo]));
         foreach ($bar->iterate() as $__) {
             $this->rewards['title'][] = sprintf(Lang::achievement('titleReward'), $bar->id, trim(str_replace('%s', '', $bar->getField('male', true))));
         }
     }
     $this->rewards['text'] = $this->subject->getField('reward', true);
     // factionchange-equivalent
     if ($pendant = DB::World()->selectCell('SELECT IF(horde_id = ?d, alliance_id, -horde_id) FROM player_factionchange_achievement WHERE alliance_id = ?d OR horde_id = ?d', $this->typeId, $this->typeId, $this->typeId)) {
         $altAcv = new AchievementList(array(['id', abs($pendant)]));
         if (!$altAcv->error) {
             $this->transfer = sprintf(Lang::achievement('_transfer'), $altAcv->id, 1, $altAcv->getField('iconString'), $altAcv->getField('name', true), $pendant > 0 ? 'alliance' : 'horde', $pendant > 0 ? Lang::game('si', 1) : Lang::game('si', 2));
         }
     }
     /**************/
     /* Extra Tabs */
     /**************/
     // tab: see also
     $conditions = array(['name_loc' . User::$localeId, $this->subject->getField('name', true)], ['id', $this->typeId, '!']);
     $saList = new AchievementList($conditions);
     $this->lvTabs[] = array('file' => 'achievement', 'data' => $saList->getListviewData(), 'params' => array('id' => 'see-also', 'name' => '$LANG.tab_seealso', 'visibleCols' => "\$['category']"));
     $this->extendGlobalData($saList->getJSGlobals());
     // tab: criteria of
     $refs = DB::Aowow()->SelectCol('SELECT refAchievementId FROM ?_achievementcriteria WHERE Type = ?d AND value1 = ?d', ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT, $this->typeId);
     if (!empty($refs)) {
         $coList = new AchievementList(array(['id', $refs]));
         $this->lvTabs[] = array('file' => 'achievement', 'data' => $coList->getListviewData(), 'params' => array('id' => 'criteria-of', 'name' => '$LANG.tab_criteriaof', 'visibleCols' => "\$['category']"));
         $this->extendGlobalData($coList->getJSGlobals());
     }
     /*****************/
     /* Criteria List */
     /*****************/
     $iconId = 1;
     $rightCol = [];
     foreach ($this->subject->getCriteria() as $i => $crt) {
         // hide hidden criteria for regular users (really do..?)
         // if (($crt['completionFlags'] & ACHIEVEMENT_CRITERIA_FLAG_HIDDEN) && User::$perms > 0)
         // continue;
         // alternative display option
         $displayMoney = $crt['completionFlags'] & ACHIEVEMENT_CRITERIA_FLAG_MONEY_COUNTER;
         $crtName = Util::localizedString($crt, 'name');
         $tmp = array('id' => $crt['id'], 'name' => $crtName, 'type' => $crt['type']);
         $obj = (int) $crt['value1'];
         $qty = (int) $crt['value2'];
         switch ($crt['type']) {
             // link to npc
             case ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE:
             case ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_CREATURE:
                 $tmp['link'] = array('href' => '?npc=' . $obj, 'text' => $crtName);
                 $tmp['extraText'] = Lang::achievement('slain');
                 break;
                 // link to area (by map)
             // link to area (by map)
             case ACHIEVEMENT_CRITERIA_TYPE_WIN_BG:
             case ACHIEVEMENT_CRITERIA_TYPE_WIN_ARENA:
             case ACHIEVEMENT_CRITERIA_TYPE_PLAY_ARENA:
             case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND:
             case ACHIEVEMENT_CRITERIA_TYPE_DEATH_AT_MAP:
                 if ($zoneId = DB::Aowow()->selectCell('SELECT id FROM ?_zones WHERE mapId = ? LIMIT 1', $obj)) {
                     $tmp['link'] = array('href' => '?zone=' . $zoneId, 'text' => $crtName);
                 } else {
                     $tmp['extraText'] = $crtName;
                 }
                 break;
                 // link to area
             // link to area
             case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_IN_ZONE:
             case ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL_AT_AREA:
                 $tmp['link'] = array('href' => '?zone=' . $obj, 'text' => $crtName);
                 break;
                 // link to skills
             // link to skills
             case ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL:
             case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LEVEL:
             case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILLLINE_SPELLS:
             case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LINE:
                 $tmp['link'] = array('href' => '?skill=' . $obj, 'text' => $crtName);
                 break;
                 // link to class
             // link to class
             case ACHIEVEMENT_CRITERIA_TYPE_HK_CLASS:
                 $tmp['link'] = array('href' => '?class=' . $obj, 'text' => $crtName);
                 break;
                 // link to race
             // link to race
             case ACHIEVEMENT_CRITERIA_TYPE_HK_RACE:
                 $tmp['link'] = array('href' => '?race=' . $obj, 'text' => $crtName);
                 break;
                 // link to title - todo (low): crosslink
             // link to title - todo (low): crosslink
             case ACHIEVEMENT_CRITERIA_TYPE_EARNED_PVP_TITLE:
                 $tmp['extraText'] = Util::ucFirst(Lang::game('title')) . Lang::main('colon') . $crtName;
                 break;
                 // link to achivement (/w icon)
             // link to achivement (/w icon)
             case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT:
                 $tmp['link'] = array('href' => '?achievement=' . $obj, 'text' => $crtName);
                 $tmp['icon'] = $iconId;
                 $this->criteria['icons'][] = array('itr' => $iconId++, 'type' => 'g_achievements', 'id' => $obj);
                 $this->extendGlobalIds(TYPE_ACHIEVEMENT, $obj);
                 break;
                 // link to quest
             // link to quest
             case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST:
                 // $crtName = ;
                 $tmp['link'] = array('href' => '?quest=' . $obj, 'text' => $crtName ?: QuestList::getName($obj));
                 break;
                 // link to spell (/w icon)
             // link to spell (/w icon)
             case ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET:
             case ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2:
             case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL:
             case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SPELL:
             case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2:
                 $tmp['link'] = array('href' => '?spell=' . $obj, 'text' => $crtName ?: SpellList::getName($obj));
                 $this->extendGlobalIds(TYPE_SPELL, $obj);
                 $tmp['icon'] = $iconId;
                 $this->criteria['icons'][] = array('itr' => $iconId++, 'type' => 'g_spells', 'id' => $obj);
                 break;
                 // link to item (/w icon)
             // link to item (/w icon)
             case ACHIEVEMENT_CRITERIA_TYPE_OWN_ITEM:
             case ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM:
             case ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM:
             case ACHIEVEMENT_CRITERIA_TYPE_EQUIP_ITEM:
                 $crtItm = new ItemList(array(['i.id', $obj]));
                 $tmp['link'] = array('href' => '?item=' . $obj, 'text' => $crtName ?: $crtItm->getField('name', true), 'quality' => $crtItm->getField('quality'), 'count' => $qty);
                 $this->extendGlobalData($crtItm->getJSGlobals());
                 $tmp['icon'] = $iconId;
                 $this->criteria['icons'][] = array('itr' => $iconId++, 'type' => 'g_items', 'id' => $obj, 'count' => $qty);
                 break;
                 // link to faction (/w target reputation)
             // link to faction (/w target reputation)
             case ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION:
                 $tmp['link'] = array('href' => '?faction=' . $obj, 'text' => $crtName ?: FactionList::getName($obj));
                 $tmp['extraText'] = ' (' . Lang::getReputationLevelForPoints($qty) . ')';
                 break;
                 // link to GObject
             // link to GObject
             case ACHIEVEMENT_CRITERIA_TYPE_USE_GAMEOBJECT:
             case ACHIEVEMENT_CRITERIA_TYPE_FISH_IN_GAMEOBJECT:
                 $tmp['link'] = array('href' => '?object=' . $obj, 'text' => $crtName);
                 break;
             default:
                 // Add a gold coin icon if required
                 $tmp['extraText'] = $displayMoney ? Util::formatMoney($qty) : $crtName;
                 break;
         }
         // If the right column
         if ($i % 2) {
             $this->criteria['data'][] = $tmp;
         } else {
             $rightCol[] = $tmp;
         }
     }
     // If you found the second column - merge data from it to the end of the main body
     if ($rightCol) {
         $this->criteria['data'] = array_merge($this->criteria['data'], $rightCol);
     }
 }
예제 #5
0
 public function getByItem($entry, $maxResults = CFG_SQL_LIMIT_DEFAULT, $lootTableList = [])
 {
     $this->entry = intVal($entry);
     if (!$this->entry) {
         return false;
     }
     //  [fileName, tabData, tabName, tabId, extraCols, hiddenCols, visibleCols]
     $tabsFinal = array(['item', [], '$LANG.tab_containedin', 'contained-in-item', [], [], []], ['item', [], '$LANG.tab_disenchantedfrom', 'disenchanted-from', [], [], []], ['item', [], '$LANG.tab_prospectedfrom', 'prospected-from', [], [], []], ['item', [], '$LANG.tab_milledfrom', 'milled-from', [], [], []], ['creature', [], '$LANG.tab_droppedby', 'dropped-by', [], [], []], ['creature', [], '$LANG.tab_pickpocketedfrom', 'pickpocketed-from', [], [], []], ['creature', [], '$LANG.tab_skinnedfrom', 'skinned-from', [], [], []], ['creature', [], '$LANG.tab_minedfromnpc', 'mined-from-npc', [], [], []], ['creature', [], '$LANG.tab_salvagedfrom', 'salvaged-from', [], [], []], ['creature', [], '$LANG.tab_gatheredfromnpc', 'gathered-from-npc', [], [], []], ['quest', [], '$LANG.tab_rewardfrom', 'reward-from-quest', [], [], []], ['zone', [], '$LANG.tab_fishedin', 'fished-in-zone', [], [], []], ['object', [], '$LANG.tab_containedin', 'contained-in-object', [], [], []], ['object', [], '$LANG.tab_minedfrom', 'mined-from-object', [], [], []], ['object', [], '$LANG.tab_gatheredfrom', 'gathered-from-object', [], [], []], ['object', [], '$LANG.tab_fishedin', 'fished-in-object', [], [], []], ['spell', [], '$LANG.tab_createdby', 'created-by', [], [], []], ['achievement', [], '$LANG.tab_rewardfrom', 'reward-from-achievement', [], [], []]);
     $refResults = [];
     $chanceMods = [];
     $query = 'SELECT
                         lt1.entry AS ARRAY_KEY,
                         IF(lt1.reference = 0, lt1.item, lt1.reference) AS item,
                         lt1.chance,
                         SUM(IF(lt2.chance = 0, 1, 0)) AS nZeroItems,
                         SUM(lt2.chance) AS sumChance,
                         IF(lt1.groupid > 0, 1, 0) AS isGrouped,
                         IF(lt1.reference = 0, lt1.mincount, 1) AS min,
                         IF(lt1.reference = 0, lt1.maxcount, 1) AS max,
                         IF(lt1.reference > 0, lt1.maxcount, 1) AS multiplier
                     FROM
                         ?# lt1
                     LEFT JOIN
                         ?# lt2 ON lt1.entry = lt2.entry AND lt1.groupid = lt2.groupid
                     WHERE
                         %s
                     GROUP BY lt2.entry, lt2.groupid';
     $calcChance = function ($refs, $parents = []) use(&$chanceMods) {
         $retData = [];
         $retKeys = [];
         foreach ($refs as $rId => $ref) {
             // check for possible database inconsistencies
             if (!$ref['chance'] && !$ref['isGrouped']) {
                 Util::addNote(U_GROUP_EMPLOYEE, 'Loot by Item: ungrouped Item/Ref ' . $ref['item'] . ' has 0% chance assigned!');
             }
             if ($ref['isGrouped'] && $ref['sumChance'] > 100) {
                 Util::addNote(U_GROUP_EMPLOYEE, 'Loot by Item: group with Item/Ref ' . $ref['item'] . ' has ' . number_format($ref['sumChance'], 2) . '% total chance! Some items cannot drop!');
             }
             if ($ref['isGrouped'] && $ref['sumChance'] >= 100 && !$ref['chance']) {
                 Util::addNote(U_GROUP_EMPLOYEE, 'Loot by Item: Item/Ref ' . $ref['item'] . ' with adaptive chance cannot drop. Group already at 100%!');
             }
             $chance = abs($ref['chance'] ?: (100 - $ref['sumChance']) / $ref['nZeroItems']) / 100;
             // apply inherited chanceMods
             if (isset($chanceMods[$ref['item']])) {
                 $chance *= $chanceMods[$ref['item']][0];
                 $chance = 1 - pow(1 - $chance, $chanceMods[$ref['item']][1]);
             }
             // save chance for parent-ref
             $chanceMods[$rId] = [$chance, $ref['multiplier']];
             // refTemplate doesn't point to a new ref -> we are done
             if (!in_array($rId, $parents)) {
                 $data = array('percent' => $chance, 'stack' => [$ref['min'], $ref['max']], 'count' => 1);
                 if ($_ = self::createStack($ref)) {
                     $data['pctstack'] = $_;
                 }
                 // sort highest chances first
                 $i = 0;
                 for (; $i < count($retData); $i++) {
                     if ($retData[$i]['percent'] < $data['percent']) {
                         break;
                     }
                 }
                 array_splice($retData, $i, 0, [$data]);
                 array_splice($retKeys, $i, 0, [$rId]);
             }
         }
         return array_combine($retKeys, $retData);
     };
     /*
         get references containing the item
     */
     $newRefs = DB::World()->select(sprintf($query, 'lt1.item = ?d AND lt1.reference = 0'), LOOT_REFERENCE, LOOT_REFERENCE, $this->entry);
     while ($newRefs) {
         $curRefs = $newRefs;
         $newRefs = DB::World()->select(sprintf($query, 'lt1.reference IN (?a)'), LOOT_REFERENCE, LOOT_REFERENCE, array_keys($curRefs));
         $refResults += $calcChance($curRefs, array_column($newRefs, 'item'));
     }
     /*
         search the real loot-templates for the itemId and gathered refds
     */
     for ($i = 1; $i < count($this->lootTemplates); $i++) {
         if ($lootTableList && !in_array($this->lootTemplates[$i], $lootTableList)) {
             continue;
         }
         $result = $calcChance(DB::World()->select(sprintf($query, '{lt1.reference IN (?a) OR }(lt1.reference = 0 AND lt1.item = ?d)'), $this->lootTemplates[$i], $this->lootTemplates[$i], $refResults ? array_keys($refResults) : DBSIMPLE_SKIP, $this->entry));
         // do not skip here if $result is empty. Additional loot for spells and quest is added separately
         // format for actual use
         foreach ($result as $k => $v) {
             unset($result[$k]);
             $v['percent'] = round($v['percent'] * 100, 3);
             $result[abs($k)] = $v;
         }
         // cap fetched entries to the sql-limit to guarantee, that the highest chance items get selected first
         // screws with GO-loot and skinnig-loot as these templates are shared for several tabs (fish, herb, ore) (herb, ore, leather)
         $ids = array_slice(array_keys($result), 0, $maxResults);
         switch ($this->lootTemplates[$i]) {
             case LOOT_CREATURE:
                 $field = 'lootId';
                 $tabId = 4;
                 break;
             case LOOT_PICKPOCKET:
                 $field = 'pickpocketLootId';
                 $tabId = 5;
                 break;
             case LOOT_SKINNING:
                 $field = 'skinLootId';
                 $tabId = -6;
                 break;
                 // assigned later
             // assigned later
             case LOOT_PROSPECTING:
                 $field = 'id';
                 $tabId = 2;
                 break;
             case LOOT_MILLING:
                 $field = 'id';
                 $tabId = 3;
                 break;
             case LOOT_ITEM:
                 $field = 'id';
                 $tabId = 0;
                 break;
             case LOOT_DISENCHANT:
                 $field = 'disenchantId';
                 $tabId = 1;
                 break;
             case LOOT_FISHING:
                 $field = 'id';
                 $tabId = 11;
                 break;
                 // subAreas are currently ignored
             // subAreas are currently ignored
             case LOOT_GAMEOBJECT:
                 if (!$ids) {
                     continue 2;
                 }
                 $srcObj = new GameObjectList(array(['lootId', $ids]));
                 if ($srcObj->error) {
                     continue 2;
                 }
                 $srcData = $srcObj->getListviewData();
                 foreach ($srcObj->iterate() as $__id => $curTpl) {
                     switch ($curTpl['typeCat']) {
                         case 25:
                             $tabId = 15;
                             break;
                             // fishing node
                         // fishing node
                         case -3:
                             $tabId = 14;
                             break;
                             // herb
                         // herb
                         case -4:
                             $tabId = 13;
                             break;
                             // vein
                         // vein
                         default:
                             $tabId = 12;
                             break;
                             // general chest loot
                     }
                     $tabsFinal[$tabId][1][] = array_merge($srcData[$srcObj->id], $result[$srcObj->getField('lootId')]);
                     $tabsFinal[$tabId][4][] = 'Listview.extraCols.percent';
                     if ($tabId != 15) {
                         $tabsFinal[$tabId][6][] = 'skill';
                     }
                 }
                 continue 2;
             case LOOT_MAIL:
                 // quest part
                 $conditions = array(['rewardChoiceItemId1', $this->entry], ['rewardChoiceItemId2', $this->entry], ['rewardChoiceItemId3', $this->entry], ['rewardChoiceItemId4', $this->entry], ['rewardChoiceItemId5', $this->entry], ['rewardChoiceItemId6', $this->entry], ['rewardItemId1', $this->entry], ['rewardItemId2', $this->entry], ['rewardItemId3', $this->entry], ['rewardItemId4', $this->entry], 'OR');
                 if ($ids) {
                     $conditions[] = ['rewardMailTemplateId', $ids];
                 }
                 $srcObj = new QuestList($conditions);
                 if (!$srcObj->error) {
                     self::storeJSGlobals($srcObj->getJSGlobals(GLOBALINFO_SELF | GLOBALINFO_REWARDS));
                     $srcData = $srcObj->getListviewData();
                     foreach ($srcObj->iterate() as $_) {
                         $tabsFinal[10][1][] = array_merge($srcData[$srcObj->id], empty($result[$srcObj->id]) ? ['percent' => -1] : $result[$srcObj->id]);
                     }
                 }
                 // achievement part
                 $conditions = array(['itemExtra', $this->entry]);
                 if ($ar = DB::World()->selectCol('SELECT entry FROM achievement_reward WHERE item = ?d{ OR mailTemplate IN (?a)}', $this->entry, $ids ?: DBSIMPLE_SKIP)) {
                     array_push($conditions, ['id', $ar], 'OR');
                 }
                 $srcObj = new AchievementList($conditions);
                 if (!$srcObj->error) {
                     self::storeJSGlobals($srcObj->getJSGlobals(GLOBALINFO_SELF | GLOBALINFO_REWARDS));
                     $srcData = $srcObj->getListviewData();
                     foreach ($srcObj->iterate() as $_) {
                         $tabsFinal[17][1][] = array_merge($srcData[$srcObj->id], empty($result[$srcObj->id]) ? ['percent' => -1] : $result[$srcObj->id]);
                     }
                     $tabsFinal[17][5][] = 'rewards';
                     $tabsFinal[17][6][] = 'category';
                 }
                 continue 2;
             case LOOT_SPELL:
                 $conditions = array('OR', ['AND', ['effect1CreateItemId', $this->entry], ['OR', ['effect1Id', SpellList::$effects['itemCreate']], ['effect1AuraId', SpellList::$auras['itemCreate']]]], ['AND', ['effect2CreateItemId', $this->entry], ['OR', ['effect2Id', SpellList::$effects['itemCreate']], ['effect2AuraId', SpellList::$auras['itemCreate']]]], ['AND', ['effect3CreateItemId', $this->entry], ['OR', ['effect3Id', SpellList::$effects['itemCreate']], ['effect3AuraId', SpellList::$auras['itemCreate']]]]);
                 if ($ids) {
                     $conditions[] = ['id', $ids];
                 }
                 $srcObj = new SpellList($conditions);
                 if (!$srcObj->error) {
                     self::storeJSGlobals($srcObj->getJSGlobals(GLOBALINFO_SELF | GLOBALINFO_RELATED));
                     $srcData = $srcObj->getListviewData();
                     if (!empty($result)) {
                         $tabsFinal[16][4][] = 'Listview.extraCols.percent';
                     }
                     if ($srcObj->hasSetFields(['reagent1'])) {
                         $tabsFinal[16][6][] = 'reagents';
                     }
                     foreach ($srcObj->iterate() as $_) {
                         $tabsFinal[16][1][] = array_merge($srcData[$srcObj->id], empty($result[$srcObj->id]) ? ['percent' => -1] : $result[$srcObj->id]);
                     }
                 }
                 continue 2;
         }
         if (!$ids) {
             continue;
         }
         switch ($tabsFinal[abs($tabId)][0]) {
             case 'creature':
                 // new CreatureList
             // new CreatureList
             case 'item':
                 // new ItemList
             // new ItemList
             case 'zone':
                 // new ZoneList
                 $oName = ucFirst($tabsFinal[abs($tabId)][0]) . 'List';
                 $srcObj = new $oName(array([$field, $ids]));
                 if (!$srcObj->error) {
                     $srcData = $srcObj->getListviewData();
                     self::storeJSGlobals($srcObj->getJSGlobals(GLOBALINFO_SELF | GLOBALINFO_RELATED));
                     foreach ($srcObj->iterate() as $curTpl) {
                         if ($tabId < 0 && $curTpl['typeFlags'] & NPC_TYPEFLAG_HERBLOOT) {
                             $tabId = 9;
                         } else {
                             if ($tabId < 0 && $curTpl['typeFlags'] & NPC_TYPEFLAG_ENGINEERLOOT) {
                                 $tabId = 8;
                             } else {
                                 if ($tabId < 0 && $curTpl['typeFlags'] & NPC_TYPEFLAG_MININGLOOT) {
                                     $tabId = 7;
                                 } else {
                                     if ($tabId < 0) {
                                         $tabId = abs($tabId);
                                     }
                                 }
                             }
                         }
                         // general case (skinning)
                         $tabsFinal[$tabId][1][] = array_merge($srcData[$srcObj->id], $result[$srcObj->getField($field)]);
                         $tabsFinal[$tabId][4][] = 'Listview.extraCols.percent';
                     }
                 }
                 break;
         }
     }
     $this->results = $tabsFinal;
     return true;
 }