protected function generateContent() { /***********/ /* Infobox */ /***********/ $infobox = Lang::getInfoBoxForFlags($this->subject->getField('cuFlags')); if ($this->subject->getField('side') == SIDE_ALLIANCE) { $infobox[] = Lang::main('side') . Lang::main('colon') . '[span class=icon-alliance]' . Lang::game('si', SIDE_ALLIANCE) . '[/span]'; } else { if ($this->subject->getField('side') == SIDE_HORDE) { $infobox[] = Lang::main('side') . Lang::main('colon') . '[span class=icon-horde]' . Lang::game('si', SIDE_HORDE) . '[/span]'; } else { $infobox[] = Lang::main('side') . Lang::main('colon') . Lang::game('si', SIDE_BOTH); } } if ($g = $this->subject->getField('gender')) { $infobox[] = Lang::main('gender') . Lang::main('colon') . '[span class=icon-' . ($g == 2 ? 'female' : 'male') . ']' . Lang::main('sex', $g) . '[/span]'; } if ($eId = $this->subject->getField('eventId')) { $this->extendGlobalIds(TYPE_WORLDEVENT, $eId); $infobox[] = Lang::game('eventShort') . Lang::main('colon') . '[event=' . $eId . ']'; } /****************/ /* Main Content */ /****************/ $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 => ['name' => $this->nameFixed]); // factionchange-equivalent if ($pendant = DB::World()->selectCell('SELECT IF(horde_id = ?d, alliance_id, -horde_id) FROM player_factionchange_titles WHERE alliance_id = ?d OR horde_id = ?d', $this->typeId, $this->typeId, $this->typeId)) { $altTitle = new TitleList(array(['id', abs($pendant)])); if (!$altTitle->error) { $this->transfer = sprintf(Lang::title('_transfer'), $altTitle->id, $altTitle->getHtmlizedName(), $pendant > 0 ? 'alliance' : 'horde', $pendant > 0 ? Lang::game('si', 1) : Lang::game('si', 2)); } } /**************/ /* Extra Tabs */ /**************/ // tab: quest source $quests = new QuestList(array(['rewardTitleId', $this->typeId])); if (!$quests->error) { $this->extendGlobalData($quests->getJSGlobals(GLOBALINFO_REWARDS)); $this->lvTabs[] = ['quest', array('data' => array_values($quests->getListviewData()), 'id' => 'reward-from-quest', 'name' => '$LANG.tab_rewardfrom', 'hiddenCols' => ['experience', 'money'], 'visibleCols' => ['category'])]; } // tab: achievement source if ($aIds = DB::World()->selectCol('SELECT entry FROM achievement_reward WHERE title_A = ?d OR title_H = ?d', $this->typeId, $this->typeId)) { $acvs = new AchievementList(array(['id', $aIds])); if (!$acvs->error) { $this->extendGlobalData($acvs->getJSGlobals()); $this->lvTabs[] = ['achievement', array('data' => array_values($acvs->getListviewData()), 'id' => 'reward-from-achievement', 'name' => '$LANG.tab_rewardfrom', 'visibleCols' => ['category'], 'sort' => ['reqlevel', 'name'])]; } } // tab: criteria of (to be added by TC) }
protected function generateContent() { /***********/ /* Infobox */ /***********/ $infobox = Lang::getInfoBoxForFlags($this->subject->getField('cuFlags')); // has Animation if ($this->subject->getField('isAnimated')) { $infobox[] = Lang::emote('isAnimated'); } /****************/ /* Main Content */ /****************/ $text = ''; if ($aliasses = DB::Aowow()->selectCol('SELECT command FROM ?_emotes_aliasses WHERE id = ?d AND locales & ?d', $this->typeId, 1 << User::$localeId)) { $text .= '[h3]' . Lang::emote('aliases') . '[/h3][ul]'; foreach ($aliasses as $a) { $text .= '[li]/' . $a . '[/li]'; } $text .= '[/ul][br][br]'; } $texts = []; if ($_ = $this->subject->getField('self', true)) { $texts[Lang::emote('self')] = $_; } if ($_ = $this->subject->getField('target', true)) { $texts[Lang::emote('target')] = $_; } if ($_ = $this->subject->getField('noTarget', true)) { $texts[Lang::emote('noTarget')] = $_; } if (!$texts) { $text .= '[div][i class=q0]' . Lang::emote('noText') . '[/i][/div]'; } else { foreach ($texts as $h => $t) { $text .= '[pad][b]' . $h . '[/b][ul][li][span class=s4]' . preg_replace('/%\\d?\\$?s/', '<' . Util::ucFirst(Lang::main('name')) . '>', $t) . '[/span][/li][/ul]'; } } $this->extraText = $text; $this->infobox = $infobox ? '[ul][li]' . implode('[/li][li]', $infobox) . '[/li][/ul]' : null; /**************/ /* Extra Tabs */ /**************/ // tab: achievement $condition = array(['ac.type', ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE], ['ac.value1', $this->typeId]); $acv = new AchievementList($condition); $this->lvTabs[] = ['achievement', ['data' => array_values($acv->getListviewData())]]; $this->extendGlobalData($acv->getJsGlobals()); }
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] [/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 ? ' (' . 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' => ' (' . 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') . ' (' . $_ . ')']; } /**********/ /* 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')); } }
protected function generateContent() { $this->addJS('?data=zones&locale=' . User::$localeId . '&t=' . $_SESSION['dataKey']); $_itemId = $this->subject->getField('itemId'); /***********/ /* Infobox */ /**********/ $infobox = Lang::getInfoBoxForFlags($this->subject->getField('cuFlags')); if ($this->typeId == 103) { // Arena Points $infobox[] = Lang::currency('cap') . Lang::main('colon') . '10\'000'; } else { if ($this->typeId == 104) { // Honor $infobox[] = Lang::currency('cap') . Lang::main('colon') . '75\'000'; } } /****************/ /* Main Content */ /****************/ $this->infobox = $infobox ? '[ul][li]' . implode('[/li][li]', $infobox) . '[/li][/ul]' : null; $this->name = $this->subject->getField('name', true); $this->headIcons = $this->typeId == 104 ? ['inv_bannerpvp_02', 'inv_bannerpvp_01'] : [$this->subject->getField('iconString')]; $this->redButtons = array(BUTTON_WOWHEAD => true, BUTTON_LINKS => true); /**************/ /* Extra Tabs */ /**************/ if ($this->typeId != 103 && $this->typeId != 104) { // tabs: this currency is contained in.. $lootTabs = new Loot(); if ($lootTabs->getByItem($_itemId)) { $this->extendGlobalData($lootTabs->jsGlobals); foreach ($lootTabs->iterate() as $tab) { $this->lvTabs[] = array('file' => $tab[0], 'data' => $tab[1], 'params' => ['name' => $tab[2], 'id' => $tab[3], 'extraCols' => $tab[4] ? '$[' . implode(', ', array_unique($tab[4])) . ']' : null, 'hiddenCols' => $tab[5] ? '$[' . implode(', ', array_unique($tab[5])) . ']' : null, 'visibleCols' => $tab[6] ? '$' . Util::toJSON(array_unique($tab[6])) : null]); } } // tab: sold by $itemObj = new ItemList(array(['id', $_itemId])); if (!empty($itemObj->getExtendedCost()[$_itemId])) { $vendors = $itemObj->getExtendedCost()[$_itemId]; $this->extendGlobalData($itemObj->getJSGlobals(GLOBALINFO_SELF | GLOBALINFO_RELATED)); $soldBy = new CreatureList(array(['id', array_keys($vendors)])); if (!$soldBy->error) { $sbData = $soldBy->getListviewData(); $extraCols = ['Listview.extraCols.stock', "Listview.funcBox.createSimpleCol('stack', 'stack', '10%', 'stack')", 'Listview.extraCols.cost']; $holidays = []; foreach ($sbData as $k => &$row) { $items = []; $tokens = []; foreach ($vendors[$k] as $id => $qty) { if (is_string($id)) { continue; } if ($id > 0) { $tokens[] = [$id, $qty]; } else { if ($id < 0) { $items[] = [-$id, $qty]; } } } if ($vendors[$k]['event']) { if (count($extraCols) == 3) { // not already pushed $extraCols[] = 'Listview.extraCols.condition'; } $this->extendGlobalIds(TYPE_WORLDEVENT, $vendors[$k]['event']); $row['condition'][0][$this->typeId][] = [[CND_ACTIVE_EVENT, $vendors[$k]['event']]]; } $row['stock'] = $vendors[$k]['stock']; $row['stack'] = $itemObj->getField('buyCount'); $row['cost'] = array($itemObj->getField('buyPrice'), $items ? $items : null, $tokens ? $tokens : null); } $this->lvTabs[] = array('file' => 'creature', 'data' => $sbData, 'params' => ['name' => '$LANG.tab_soldby', 'id' => 'sold-by-npc', 'extraCols' => '$[' . implode(', ', $extraCols) . ']', 'hiddenCols' => "\$['level', 'type']"]); } } } // tab: created by (spell) [for items its handled in Loot::getByContainer()] if ($this->typeId == 104) { $createdBy = new SpellList(array(['effect1Id', 45], ['effect2Id', 45], ['effect3Id', 45], 'OR')); if (!$createdBy->error) { $this->extendGlobalData($createdBy->getJSGlobals(GLOBALINFO_SELF | GLOBALINFO_RELATED)); if ($createdBy->hasSetFields(['reagent1'])) { $visCols = ['reagents']; } $this->lvTabs[] = array('file' => 'spell', 'data' => $createdBy->getListviewData(), 'params' => ['name' => '$LANG.tab_createdby', 'id' => 'created-by', 'visibleCols' => isset($visCols) ? '$' . Util::toJSON($visCols) : null]); } } // tab: currency for if ($this->typeId == 103) { $n = '?items&filter=cr=145;crs=1;crv=0'; $w = 'reqArenaPoints > 0'; } else { if ($this->typeId == 104) { $n = '?items&filter=cr=144;crs=1;crv=0'; $w = 'reqHonorPoints > 0'; } else { $n = in_array($this->typeId, [42, 61, 81, 241, 121, 122, 123, 125, 126, 161, 201, 101, 102, 221, 301, 341]) ? '?items&filter=cr=158;crs=' . $_itemId . ';crv=0' : null; $w = 'reqItemId1 = ' . $_itemId . ' OR reqItemId2 = ' . $_itemId . ' OR reqItemId3 = ' . $_itemId . ' OR reqItemId4 = ' . $_itemId . ' OR reqItemId5 = ' . $_itemId; } } $xCosts = DB::Aowow()->selectCol('SELECT id FROM ?_itemextendedcost WHERE ' . $w); $boughtBy = $xCosts ? DB::World()->selectCol('SELECT item FROM npc_vendor WHERE extendedCost IN (?a) UNION SELECT item FROM game_event_npc_vendor WHERE extendedCost IN (?a)', $xCosts, $xCosts) : []; if ($boughtBy) { $boughtBy = new ItemList(array(['id', $boughtBy])); if (!$boughtBy->error) { if ($boughtBy->getMatches() <= CFG_SQL_LIMIT_DEFAULT) { $n = null; } $this->lvTabs[] = array('file' => 'item', 'data' => $boughtBy->getListviewData(ITEMINFO_VENDOR, [TYPE_CURRENCY => $this->typeId]), 'params' => ['name' => '$LANG.tab_currencyfor', 'id' => 'currency-for', 'extraCols' => "\$[Listview.funcBox.createSimpleCol('stack', 'stack', '10%', 'stack')]", 'note' => $n ? sprintf(Util::$filterResultString, $n) : null]); $this->extendGlobalData($boughtBy->getJSGlobals(GLOBALINFO_SELF | GLOBALINFO_RELATED)); } } }
protected function generateContent() { $_ta = $this->subject->getField('contentGroup'); $_ty = $this->subject->getField('type'); $_cnt = count($this->subject->getField('pieces')); /***********/ /* Infobox */ /***********/ $infobox = Lang::getInfoBoxForFlags($this->subject->getField('cuFlags')); // unavailable (todo (low): set data) if ($this->subject->getField('cuFlags') & CUSTOM_UNAVAILABLE) { $infobox[] = Lang::main('unavailable'); } // worldevent if ($e = $this->subject->getField('eventId')) { $infobox[] = Lang::game('eventShort') . Lang::main('colon') . '[event=' . $e . ']'; $this->extendGlobalIds(TYPE_WORLDEVENT, $e); } // itemLevel if ($min = $this->subject->getField('minLevel')) { $foo = Lang::game('level') . Lang::main('colon') . $min; $max = $this->subject->getField('maxLevel'); if ($min < $max) { $foo .= ' - ' . $max; } $infobox[] = $foo; } // class if ($cl = Lang::getClassString($this->subject->getField('classMask'), $jsg, $qty, false)) { $this->extendGlobalIds(TYPE_CLASS, $jsg); $t = $qty == 1 ? Lang::game('class') : Lang::game('classes'); $infobox[] = Util::ucFirst($t) . Lang::main('colon') . $cl; } // required level if ($lvl = $this->subject->getField('reqLevel')) { $infobox[] = sprintf(Lang::game('reqLevel'), $lvl); } // type if ($_ty) { $infobox[] = Lang::game('type') . Lang::main('colon') . Lang::itemset('types', $_ty); } // tag if ($_ta) { $infobox[] = Lang::itemset('_tag') . Lang::main('colon') . '[url=?itemsets&filter=ta=' . $_ta . ']' . Lang::itemset('notes', $_ta) . '[/url]'; } /****************/ /* Main Content */ /****************/ // pieces + Summary $pieces = []; $eqList = []; $compare = []; if (!$this->subject->pieceToSet) { $cnd = [0]; } else { $cnd = ['i.id', array_keys($this->subject->pieceToSet)]; } $iList = new ItemList(array($cnd)); $data = $iList->getListviewData(ITEMINFO_SUBITEMS | ITEMINFO_JSON); foreach ($iList->iterate() as $itemId => $__) { if (empty($data[$itemId])) { continue; } $slot = $iList->getField('slot'); $disp = $iList->getField('displayId'); if ($slot && $disp) { $eqList[] = [$slot, $disp]; } $compare[] = $itemId; $pieces[] = array('id' => $itemId, 'name' => $iList->getField('name', true), 'quality' => $iList->getField('quality'), 'icon' => $iList->getField('iconString'), 'json' => $data[$itemId]); } $skill = ''; if ($_sk = $this->subject->getField('skillId')) { $spellLink = sprintf('<a href="?spells=11.%s">%s</a> (%s)', $_sk, Lang::spell('cat', 11, $_sk, 0), $this->subject->getField('skillLevel')); $skill = ' – <small><b>' . sprintf(Lang::game('requires'), $spellLink) . '</b></small>'; } $this->bonusExt = $skill; $this->description = $_ta ? sprintf(Lang::itemset('_desc'), $this->name, Lang::itemset('notes', $_ta), $_cnt) : sprintf(Lang::itemset('_descTagless'), $this->name, $_cnt); $this->unavailable = $this->subject->getField('cuFlags') & CUSTOM_UNAVAILABLE; $this->infobox = $infobox ? '[ul][li]' . implode('[/li][li]', $infobox) . '[/li][/ul]' : null; $this->pieces = $pieces; $this->spells = $this->subject->getBonuses(); $this->expansion = 0; $this->redButtons = array(BUTTON_WOWHEAD => $this->typeId > 0, BUTTON_LINKS => ['color' => '', 'linkId' => ''], BUTTON_VIEW3D => ['type' => TYPE_ITEMSET, 'typeId' => $this->typeId, 'equipList' => $eqList], BUTTON_COMPARE => ['eqList' => implode(':', $compare), 'qty' => $_cnt]); $this->compare = array('level' => $this->subject->getField('reqLevel'), 'items' => array_map(function ($v) { return [[$v]]; }, $compare)); /**************/ /* Extra Tabs */ /**************/ // related sets (priority: 1: similar tag + class; 2: has event; 3: no tag + similar type, 4: similar type + profession) $rel = []; if ($_ta && count($this->path) == 3) { $rel[] = ['id', $this->typeId, '!']; $rel[] = ['classMask', 1 << end($this->path) - 1, '&']; $rel[] = ['contentGroup', (int) $_ta]; } else { if ($this->subject->getField('eventId')) { $rel[] = ['id', $this->typeId, '!']; $rel[] = ['eventId', 0, '!']; } else { if ($this->subject->getField('skillId')) { $rel[] = ['id', $this->typeId, '!']; $rel[] = ['contentGroup', 0]; $rel[] = ['skillId', 0, '!']; $rel[] = ['type', $_ty]; } else { if (!$_ta && $_ty) { $rel[] = ['id', $this->typeId, '!']; $rel[] = ['contentGroup', 0]; $rel[] = ['type', $_ty]; $rel[] = ['skillId', 0]; } } } } if ($rel) { $relSets = new ItemsetList($rel); if (!$relSets->error) { $lv = array('file' => 'itemset', 'data' => $relSets->getListviewData(), 'params' => array('id' => 'see-also', 'name' => '$LANG.tab_seealso')); if (!$relSets->hasDiffFields(['classMask'])) { $lv['params']['hiddenCols'] = "\$['classes']"; } $this->lvTabs[] = $lv; $this->extendGlobalData($relSets->getJSGlobals()); } } }
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 . ':"..UnitGUID("player")..":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); } }
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)); } }
protected function generateContent() { /***********/ /* Infobox */ /***********/ $infobox = Lang::getInfoBoxForFlags($this->subject->getField('cuFlags')); // reqLevel if ($_ = $this->subject->getField('requiredLevel')) { $infobox[] = sprintf(Lang::game('reqLevel'), $_); } // reqskill if ($_ = $this->subject->getField('skillLine')) { $this->extendGlobalIds(TYPE_SKILL, $_); $foo = sprintf(Lang::game('requires'), ' [skill=' . $_ . ']'); if ($_ = $this->subject->getField('skillLevel')) { $foo .= ' (' . $_ . ')'; } $infobox[] = $foo; } /****************/ /* Main Content */ /****************/ $this->infobox = $infobox ? '[ul][li]' . implode('[/li][li]', $infobox) . '[/li][/ul]' : null; $this->effects = []; // 3 effects for ($i = 1; $i < 4; $i++) { $_ty = $this->subject->getField('type' . $i); $_qty = $this->subject->getField('amount' . $i); $_obj = $this->subject->getField('object' . $i); switch ($_ty) { case 1: case 3: case 7: $sArr = $this->subject->getField('spells')[$i]; $spl = $this->subject->getRelSpell($sArr[0]); $this->effects[$i]['name'] = User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, 'Type: ' . $_ty, Lang::item('trigger', $sArr[1])) : Lang::item('trigger', $sArr[1]); $this->effects[$i]['proc'] = $sArr[3]; $this->effects[$i]['value'] = $_qty ?: null; $this->effects[$i]['icon'] = array('name' => !$spl ? Util::ucFirst(Lang::game('spell')) . ' #' . $sArr[0] : Util::localizedString($spl, 'name'), 'id' => $sArr[0], 'count' => $sArr[2]); break; case 5: if ($_obj < 2) { // [mana, health] are on [0, 1] respectively and are expected on [1, 2] .. $_obj++; } // 0 is weaponDmg .. ehh .. i messed up somewhere $this->effects[$i]['tip'] = [$_obj, Util::$itemMods[$_obj]]; // DO NOT BREAK! // DO NOT BREAK! case 2: case 6: case 8: case 4: $this->effects[$i]['name'] = User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, 'Type: ' . $_ty, Lang::enchantment('types', $_ty)) : Lang::enchantment('types', $_ty); $this->effects[$i]['value'] = $_qty; if ($_ty == 4) { $this->effects[$i]['name'] .= Lang::main('colon') . '(' . (User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, 'Object: ' . $_obj, Lang::getMagicSchools(1 << $_obj)) : Lang::getMagicSchools(1 << $_obj)) . ')'; } } } // activation conditions if ($_ = $this->subject->getField('conditionId')) { $x = ''; if ($gemCnd = DB::Aowow()->selectRow('SELECT * FROM ?_itemenchantmentcondition WHERE id = ?d', $_)) { for ($i = 1; $i < 6; $i++) { if (!$gemCnd['color' . $i]) { continue; } $fiColors = function ($idx) { $foo = ''; switch ($idx) { case 2: $foo = '0:3:5'; break; // red // red case 3: $foo = '2:4:5'; break; // yellow // yellow case 4: $foo = '1:3:4'; break; // blue } return $foo; }; $bLink = $gemCnd['color' . $i] ? '<a href="?items=3&filter=ty=' . $fiColors($gemCnd['color' . $i]) . '">' . Lang::item('gemColors', $gemCnd['color' . $i] - 1) . '</a>' : ''; $cLink = $gemCnd['cmpColor' . $i] ? '<a href="?items=3&filter=ty=' . $fiColors($gemCnd['cmpColor' . $i]) . '">' . Lang::item('gemColors', $gemCnd['cmpColor' . $i] - 1) . '</a>' : ''; switch ($gemCnd['comparator' . $i]) { case 2: // requires less <color> than (<value> || <comparecolor>) gems // requires less <color> than (<value> || <comparecolor>) gems case 5: // requires at least <color> than (<value> || <comparecolor>) gems $sp = (int) $gemCnd['value' . $i] > 1; $x .= '<span class="q0">' . Lang::achievement('reqNumCrt') . ' ' . sprintf(Lang::item('gemConditions', $gemCnd['comparator' . $i], $sp), $gemCnd['value' . $i], $bLink) . '</span><br />'; break; case 3: // requires more <color> than (<value> || <comparecolor>) gems $link = '<a href="?items=3&filter=ty=' . $fiColors($gemCnd['cmpColor' . $i]) . '">' . Lang::item('gemColors', $gemCnd['cmpColor' . $i] - 1) . '</a>'; $x .= '<span class="q0">' . Lang::achievement('reqNumCrt') . ' ' . sprintf(Lang::item('gemConditions', 3), $bLink, $cLink) . '</span><br />'; break; } } } $this->activateCondition = $x; } /**************/ /* Extra Tabs */ /**************/ // used by gem $gemList = new ItemList(array(['gemEnchantmentId', $this->typeId])); if (!$gemList->error) { $this->lvTabs[] = ['item', array('data' => array_values($gemList->getListviewData()), 'name' => '$LANG.tab_usedby + \' \' + LANG.gems', 'id' => 'used-by-gem')]; $this->extendGlobalData($gemList->getJsGlobals()); } // used by socket bonus $socketsList = new ItemList(array(['socketBonus', $this->typeId])); if (!$socketsList->error) { $this->lvTabs[] = ['item', array('data' => array_values($socketsList->getListviewData()), 'name' => '$LANG.tab_usedby + \' \' + \'' . Lang::item('socketBonus') . '\'', 'id' => 'used-by-socketbonus')]; $this->extendGlobalData($socketsList->getJsGlobals()); } // used by spell // used by useItem $cnd = array('OR', ['AND', ['effect1Id', [53, 54, 156, 92]], ['effect1MiscValue', $this->typeId]], ['AND', ['effect2Id', [53, 54, 156, 92]], ['effect2MiscValue', $this->typeId]], ['AND', ['effect3Id', [53, 54, 156, 92]], ['effect3MiscValue', $this->typeId]]); $spellList = new SpellList($cnd); if (!$spellList->error) { $spellData = $spellList->getListviewData(); $this->extendGlobalData($spellList->getJsGlobals()); $spellIds = $spellList->getFoundIDs(); $conditions = array('OR', ['AND', ['spellTrigger1', [0, 5]], ['spellId1', $spellIds]], ['AND', ['spellTrigger2', [0, 5]], ['spellId2', $spellIds]], ['AND', ['spellTrigger3', [0, 5]], ['spellId3', $spellIds]], ['AND', ['spellTrigger4', [0, 5]], ['spellId4', $spellIds]], ['AND', ['spellTrigger5', [0, 5]], ['spellId5', $spellIds]]); $ubItems = new ItemList($conditions); if (!$ubItems->error) { $this->lvTabs[] = ['item', array('data' => array_values($ubItems->getListviewData()), 'name' => '$LANG.tab_usedby + \' \' + LANG.types[3][0]', 'id' => 'used-by-item')]; $this->extendGlobalData($ubItems->getJSGlobals(GLOBALINFO_SELF)); } // remove found spells if they are used by an item if (!$ubItems->error) { foreach ($spellList->iterate() as $sId => $__) { // if Perm. Enchantment has a createItem its a Scroll of Enchantment (display both) for ($i = 1; $i < 4; $i++) { if ($spellList->getField('effect' . $i . 'Id') == 53 && $spellList->getField('effect' . $i . 'CreateItemId')) { continue 2; } } foreach ($ubItems->iterate() as $__) { for ($i = 1; $i < 6; $i++) { if ($ubItems->getField('spellId' . $i) == $sId) { unset($spellData[$sId]); break 2; } } } } } $this->lvTabs[] = ['spell', array('data' => array_values($spellData), 'name' => '$LANG.tab_usedby + \' \' + LANG.types[6][0]', 'id' => 'used-by-spell')]; } // used by randomAttrItem $ire = DB::Aowow()->select('SELECT *, ABS(id) AS ARRAY_KEY FROM ?_itemrandomenchant WHERE enchantId1 = ?d OR enchantId2 = ?d OR enchantId3 = ?d OR enchantId4 = ?d OR enchantId5 = ?d', $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId); if ($ire) { if ($iet = DB::World()->select('SELECT entry AS ARRAY_KEY, ench, chance FROM item_enchantment_template WHERE ench IN (?a)', array_keys($ire))) { $randIds = []; // transform back to signed format foreach ($iet as $tplId => $data) { $randIds[$ire[$data['ench']]['id'] > 0 ? $tplId : -$tplId] = $ire[$data['ench']]['id']; } $randItems = new ItemList(array(CFG_SQL_LIMIT_NONE, ['randomEnchant', array_keys($randIds)])); if (!$randItems->error) { $data = $randItems->getListviewData(); foreach ($randItems->iterate() as $iId => $__) { $re = $randItems->getField('randomEnchant'); $data[$iId]['percent'] = $iet[abs($re)]['chance']; $data[$iId]['count'] = 1; // expected by js or the pct-col becomes unsortable $data[$iId]['rel'] = 'rand=' . $ire[$iet[abs($re)]['ench']]['id']; $data[$iId]['name'] .= ' ' . Util::localizedString($ire[$iet[abs($re)]['ench']], 'name'); } $this->lvTabs[] = ['item', array('data' => array_values($data), 'id' => 'used-by-rand', 'name' => '$LANG.tab_usedby + \' \' + \'' . Lang::item('_rndEnchants') . '\'', 'extraCols' => ['$Listview.extraCols.percent'])]; $this->extendGlobalData($randItems->getJSGlobals(GLOBALINFO_SELF)); } } } }
protected function generateContent() { $this->addJS('?data=zones&locale=' . User::$localeId . '&t=' . $_SESSION['dataKey']); $infobox = Lang::getInfoBoxForFlags($this->subject->getField('cuFlags')); $_mask = 1 << $this->typeId - 1; $tcClassId = [null, 8, 3, 1, 5, 4, 9, 6, 2, 7, null, 0]; // see TalentCalc.js /***********/ /* Infobox */ /***********/ // hero class if ($this->subject->getField('flags') & 0x40) { $infobox[] = '[tooltip=tooltip_heroclass]' . Lang::game('heroClass') . '[/tooltip]'; } // resource if ($this->typeId == 11) { // special Druid case $infobox[] = Lang::game('resources') . Lang::main('colon') . '[tooltip name=powertype1]' . Lang::game('st', 0) . ', ' . Lang::game('st', 31) . ', ' . Lang::game('st', 2) . '[/tooltip][span class=tip tooltip=powertype1]' . Util::ucFirst(Lang::spell('powerTypes', 0)) . '[/span], ' . '[tooltip name=powertype2]' . Lang::game('st', 5) . ', ' . Lang::game('st', 8) . '[/tooltip][span class=tip tooltip=powertype2]' . Util::ucFirst(Lang::spell('powerTypes', 1)) . '[/span], ' . '[tooltip name=powertype8]' . Lang::game('st', 1) . '[/tooltip][span class=tip tooltip=powertype8]' . Util::ucFirst(Lang::spell('powerTypes', 3)) . '[/span]'; } else { if ($this->typeId == 6) { // special DK case $infobox[] = Lang::game('resources') . Lang::main('colon') . '[span]' . Util::ucFirst(Lang::spell('powerTypes', 5)) . ', ' . Util::ucFirst(Lang::spell('powerTypes', $this->subject->getField('powerType'))) . '[/span]'; } else { // regular case $infobox[] = Lang::game('resource') . Lang::main('colon') . '[span]' . Util::ucFirst(Lang::spell('powerTypes', $this->subject->getField('powerType'))) . '[/span]'; } } // roles $roles = []; for ($i = 0; $i < 4; $i++) { if ($this->subject->getField('roles') & 1 << $i) { $roles[] = (count($roles) == 2 ? "\n" : '') . Lang::game('_roles', $i); } } if ($roles) { $infobox[] = (count($roles) > 1 ? Lang::game('roles') : Lang::game('role')) . Lang::main('colon') . implode(', ', $roles); } // specs $specList = []; $skills = new SkillList(array(['id', $this->subject->getField('skills')])); foreach ($skills->iterate() as $k => $__) { $specList[$k] = '[icon name=' . $skills->getField('iconString') . '][url=?spells=7.' . $this->typeId . '.' . $k . ']' . $skills->getField('name', true) . '[/url][/icon]'; } if ($specList) { $infobox[] = Lang::game('specs') . Lang::main('colon') . '[ul][li]' . implode('[/li][li]', $specList) . '[/li][/ul]'; } /****************/ /* Main Content */ /****************/ $this->infobox = '[ul][li]' . implode('[/li][li]', $infobox) . '[/li][/ul]'; $this->expansion = Util::$expansionString[$this->subject->getField('expansion')]; $this->headIcons = ['class_' . strtolower($this->subject->getField('fileString'))]; $this->redButtons = array(BUTTON_LINKS => ['color' => '', 'linkId' => ''], BUTTON_WOWHEAD => true, BUTTON_TALENT => ['href' => '?talent#' . Util::$tcEncoding[$tcClassId[$this->typeId] * 3], 'pet' => false], BUTTON_FORUM => false); /**************/ /* Extra Tabs */ /**************/ // Tab: Spells (grouped) // '$LANG.tab_armorproficiencies', // '$LANG.tab_weaponskills', // '$LANG.tab_glyphs', // '$LANG.tab_abilities', // '$LANG.tab_talents', $conditions = array(['s.typeCat', [-13, -11, -2, 7]], [['s.cuFlags', SPELL_CU_TRIGGERED | CUSTOM_EXCLUDE_FOR_LISTVIEW, '&'], 0], ['OR', ['s.reqClassMask', $_mask, '&'], ['s.skillLine1', $this->subject->getField('skills')], ['AND', ['s.skillLine1', 0, '>'], ['s.skillLine2OrMask', $this->subject->getField('skills')]]], ['OR', ['s.cuFlags', SPELL_CU_LAST_RANK, '&'], ['s.rankNo', 0]]); $genSpells = new SpellList($conditions); if (!$genSpells->error) { $this->extendGlobalData($genSpells->getJSGlobals(GLOBALINFO_SELF)); $this->lvTabs[] = array('file' => 'spell', 'data' => $genSpells->getListviewData(), 'params' => array('id' => 'spells', 'name' => '$LANG.tab_spells', 'visibleCols' => "\$['level', 'schools', 'type', 'classes']", 'hiddenCols' => "\$['reagents', 'skill']", 'sort' => "\$['-level', 'type', 'name']", 'computeDataFunc' => '$Listview.funcBox.initSpellFilter', 'onAfterCreate' => '$Listview.funcBox.addSpellIndicator')); } // Tab: Items (grouped) $conditions = array(['requiredClass', 0, '>'], ['requiredClass', $_mask, '&'], [['requiredClass', CLASS_MASK_ALL, '&'], CLASS_MASK_ALL, '!'], ['itemset', 0], 0); $items = new ItemList($conditions); if (!$items->error) { $this->extendGlobalData($items->getJSGlobals()); if (!$items->hasDiffFields(['requiredRace'])) { $hidden = "\$['side']"; } $this->lvTabs[] = array('file' => 'item', 'data' => $items->getListviewData(), 'params' => array('id' => 'items', 'name' => '$LANG.tab_items', 'visibleCols' => "\$['dps', 'armor', 'slot']", 'hiddenCols' => isset($hidden) ? $hidden : null, 'computeDataFunc' => '$Listview.funcBox.initSubclassFilter', 'onAfterCreate' => '$Listview.funcBox.addSubclassIndicator', 'note' => sprintf(Util::$filterResultString, '?items&filter=cr=152;crs=' . $this->typeId . ';crv=0'), '_truncated' => 1)); } // Tab: Quests $conditions = array(['reqClassMask', $_mask, '&'], [['reqClassMask', CLASS_MASK_ALL, '&'], CLASS_MASK_ALL, '!']); $quests = new QuestList($conditions); if (!$quests->error) { $this->extendGlobalData($quests->getJSGlobals()); $this->lvTabs[] = array('file' => 'quest', 'data' => $quests->getListviewData(), 'params' => ['sort' => "\$['reqlevel', 'name']"]); } // Tab: Itemsets $sets = new ItemsetList(array(['classMask', $_mask, '&'])); if (!$sets->error) { $this->extendGlobalData($sets->getJSGlobals(GLOBALINFO_SELF)); $this->lvTabs[] = array('file' => 'itemset', 'data' => $sets->getListviewData(), 'params' => array('note' => sprintf(Util::$filterResultString, '?itemsets&filter=cl=' . $this->typeId), 'hiddenCols' => "\$['classes']", 'sort' => "\$['-level', 'name']")); } // Tab: Trainer $conditions = array(['npcflag', 0x30, '&'], ['trainerType', 0], ['trainerClass', $this->typeId]); $trainer = new CreatureList($conditions); if (!$trainer->error) { $this->lvTabs[] = array('file' => 'creature', 'data' => $trainer->getListviewData(), 'params' => array('id' => 'trainers', 'name' => '$LANG.tab_trainers')); } // Tab: Races $races = new CharRaceList(array(['classMask', $_mask, '&'])); if (!$races->error) { $this->lvTabs[] = array('file' => 'race', 'data' => $races->getListviewData(), 'params' => []); } }
protected function generateContent() { $this->addJS('?data=zones&locale=' . User::$localeId . '&t=' . $_SESSION['dataKey']); $_typeFlags = $this->subject->getField('typeFlags'); $_altIds = []; $_altNPCs = null; $placeholder = null; $accessory = []; // difficulty entries of self if ($this->subject->getField('cuFlags') & NPC_CU_DIFFICULTY_DUMMY) { $placeholder = [$this->subject->getField('parentId'), $this->subject->getField('parent', true)]; } else { for ($i = 1; $i < 4; $i++) { if ($_ = $this->subject->getField('difficultyEntry' . $i)) { $_altIds[$_] = $i; } } if ($_altIds) { $_altNPCs = new CreatureList(array(['id', array_keys($_altIds)])); } } if ($_ = DB::World()->selectCol('SELECT DISTINCT entry FROM vehicle_template_accessory WHERE accessory_entry = ?d', $this->typeId)) { $vehicles = new CreatureList(array(['id', $_])); foreach ($vehicles->iterate() as $id => $__) { $accessory[] = [$id, $vehicles->getField('name', true)]; } } // try to determine, if it's spawned in a dungeon or raid (shaky at best, if spawned by script) $mapType = 0; if ($maps = DB::Aowow()->selectCol('SELECT DISTINCT areaId from ?_spawns WHERE type = ?d AND typeId = ?d', TYPE_NPC, $this->typeId)) { if (count($maps) == 1) { switch (DB::Aowow()->selectCell('SELECT `type` FROM ?_zones WHERE id = ?d', $maps[0])) { case 2: case 5: $mapType = 1; break; case 3: case 7: case 8: $mapType = 2; break; } } } else { if ($_altIds) { if (count($_altIds) > 1) { // 3 or more version -> definitly raid (10/25 + hc) $mapType = 2; } else { // 2 versions; may be Heroic (use this), but may also be 10/25-raid $mapType = 1; } } } /***********/ /* Infobox */ /***********/ $infobox = Lang::getInfoBoxForFlags($this->subject->getField('cuFlags')); // Event (ignore events, where the object only gets removed) if ($_ = DB::World()->selectCol('SELECT DISTINCT ge.eventEntry FROM game_event ge, game_event_creature gec, creature c WHERE ge.eventEntry = gec.eventEntry AND c.guid = gec.guid AND c.id = ?d', $this->typeId)) { $this->extendGlobalIds(TYPE_WORLDEVENT, $_); $ev = []; foreach ($_ as $i => $e) { $ev[] = ($i % 2 ? '[br]' : ' ') . '[event=' . $e . ']'; } $infobox[] = Util::ucFirst(Lang::game('eventShort')) . Lang::main('colon') . implode(',', $ev); } // Level if ($this->subject->getField('rank') != NPC_RANK_BOSS) { $level = $this->subject->getField('minLevel'); $maxLvl = $this->subject->getField('maxLevel'); if ($level < $maxLvl) { $level .= ' - ' . $maxLvl; } } else { // Boss Level $level = '??'; } $infobox[] = Lang::game('level') . Lang::main('colon') . $level; // Classification if ($_ = $this->subject->getField('rank')) { $str = $_typeFlags & 0x4 ? '[span class=icon-boss]' . Lang::npc('rank', $_) . '[/span]' : Lang::npc('rank', $_); $infobox[] = Lang::npc('classification') . Lang::main('colon') . $str; } // Reaction $_ = function ($r) { if ($r == 1) { return 2; } if ($r == -1) { return 10; } return; }; $infobox[] = Lang::npc('react') . Lang::main('colon') . '[color=q' . $_($this->subject->getField('A')) . ']A[/color] [color=q' . $_($this->subject->getField('H')) . ']H[/color]'; // Faction $this->extendGlobalIds(TYPE_FACTION, $this->subject->getField('factionId')); $infobox[] = Util::ucFirst(Lang::game('faction')) . Lang::main('colon') . '[faction=' . $this->subject->getField('factionId') . ']'; // Tameable if ($_typeFlags & 0x1) { if ($_ = $this->subject->getField('family')) { $infobox[] = sprintf(Lang::npc('tameable'), '[url=pet=' . $_ . ']' . Lang::game('fa', $_) . '[/url]'); } } // Wealth if ($_ = intVal(($this->subject->getField('minGold') + $this->subject->getField('maxGold')) / 2)) { $infobox[] = Lang::npc('worth') . Lang::main('colon') . '[tooltip=tooltip_avgmoneydropped][money=' . $_ . '][/tooltip]'; } // is Vehicle if ($this->subject->getField('vehicleId')) { $infobox[] = Lang::npc('vehicle'); } // AI if (User::isInGroup(U_GROUP_EMPLOYEE)) { if ($_ = $this->subject->getField('scriptName')) { $infobox[] = 'Script' . Lang::main('colon') . $_; } else { if ($_ = $this->subject->getField('aiName')) { $infobox[] = 'AI' . Lang::main('colon') . $_; } } } if (User::isInGroup(U_GROUP_STAFF)) { // Mechanic immune if ($immuneMask = $this->subject->getField('mechanicImmuneMask')) { $buff = []; for ($i = 0; $i < 31; $i++) { if ($immuneMask & 1 << $i) { $buff[] = (!fMod(count($buff), 3) ? "\n" : null) . '[url=?spells&filter=me=' . ($i + 1) . ']' . Lang::game('me', $i + 1) . '[/url]'; } } $infobox[] = 'Not affected by mechanic' . Lang::main('colon') . implode(', ', $buff); } // extra flags if ($flagsExtra = $this->subject->getField('flagsExtra')) { $buff = []; if ($flagsExtra & 0x1) { $buff[] = 'Binds attacker to instance on death'; } if ($flagsExtra & 0x2) { $buff[] = "[tooltip name=civilian]- does not aggro\n- death costs Honor[/tooltip][span class=tip tooltip=civilian]Civilian[/span]"; } if ($flagsExtra & 0x4) { $buff[] = 'Cannot parry'; } if ($flagsExtra & 0x8) { $buff[] = 'Has no parry haste'; } if ($flagsExtra & 0x10) { $buff[] = 'Cannot block'; } if ($flagsExtra & 0x20) { $buff[] = 'Cannot deal Crushing Blows'; } if ($flagsExtra & 0x40) { $buff[] = 'Rewards no experience'; } if ($flagsExtra & 0x80) { $buff[] = 'Trigger-Creature'; } if ($flagsExtra & 0x100) { $buff[] = 'Immune to Taunt'; } if ($flagsExtra & 0x8000) { $buff[] = "[tooltip name=guard]- engages PvP-Attacker\n- ignores enemy stealth, invisibility and Feign Death[/tooltip][span class=tip tooltip=guard]Guard[/span]"; } if ($flagsExtra & 0x20000) { $buff[] = 'Cannot deal Critical Hits'; } if ($flagsExtra & 0x40000) { $buff[] = 'Attacker does not gain weapon skill'; } if ($flagsExtra & 0x80000) { $buff[] = 'Taunt has diminishing returns'; } if ($flagsExtra & 0x100000) { $buff[] = 'Is subject to diminishing returns'; } if ($buff) { $infobox[] = 'Extra Flags' . Lang::main('colon') . '[ul][li]' . implode('[/li][li]', $buff) . '[/li][/ul]'; } } } // > Stats $stats = []; $modes = []; // get difficulty versions if set $hint = '[tooltip name=%3$s][table cellspacing=10][tr]%1s[/tr][/table][/tooltip][span class=tip tooltip=%3$s]%2s[/span]'; $modeRow = '[tr][td]%s [/td][td]%s[/td][/tr]'; // Health $health = $this->subject->getBaseStats('health'); $stats['health'] = Util::ucFirst(Lang::spell('powerTypes', -2)) . Lang::main('colon') . ($health[0] < $health[1] ? Lang::nf($health[0]) . ' - ' . Lang::nf($health[1]) : Lang::nf($health[0])); // Mana (may be 0) $mana = $this->subject->getBaseStats('power'); $stats['mana'] = $mana[0] ? Lang::spell('powerTypes', 0) . Lang::main('colon') . ($mana[0] < $mana[1] ? Lang::nf($mana[0]) . ' - ' . Lang::nf($mana[1]) : Lang::nf($mana[0])) : null; // Armor $armor = $this->subject->getBaseStats('armor'); $stats['armor'] = Lang::npc('armor') . Lang::main('colon') . ($armor[0] < $armor[1] ? Lang::nf($armor[0]) . ' - ' . Lang::nf($armor[1]) : Lang::nf($armor[0])); // Melee Damage $melee = $this->subject->getBaseStats('melee'); if ($_ = $this->subject->getField('dmgSchool')) { // magic damage $stats['melee'] = Lang::npc('melee') . Lang::main('colon') . Lang::nf($melee[0]) . ' - ' . Lang::nf($melee[1]) . ' (' . Lang::game('sc', $_) . ')'; } else { // phys. damage $stats['melee'] = Lang::npc('melee') . Lang::main('colon') . Lang::nf($melee[0]) . ' - ' . Lang::nf($melee[1]); } // Ranged Damage $ranged = $this->subject->getBaseStats('ranged'); $stats['ranged'] = Lang::npc('ranged') . Lang::main('colon') . Lang::nf($ranged[0]) . ' - ' . Lang::nf($ranged[1]); if (in_array($mapType, [1, 2])) { foreach ($_altIds as $id => $mode) { foreach ($_altNPCs->iterate() as $dId => $__) { if ($dId != $id) { continue; } $m = Lang::npc('modes', $mapType, $mode); // Health $health = $_altNPCs->getBaseStats('health'); $modes['health'][] = sprintf($modeRow, $m, $health[0] < $health[1] ? Lang::nf($health[0]) . ' - ' . Lang::nf($health[1]) : Lang::nf($health[0])); // Mana (may be 0) $mana = $_altNPCs->getBaseStats('power'); $modes['mana'][] = $mana[0] ? sprintf($modeRow, $m, $mana[0] < $mana[1] ? Lang::nf($mana[0]) . ' - ' . Lang::nf($mana[1]) : Lang::nf($mana[0])) : null; // Armor $armor = $_altNPCs->getBaseStats('armor'); $modes['armor'][] = sprintf($modeRow, $m, $armor[0] < $armor[1] ? Lang::nf($armor[0]) . ' - ' . Lang::nf($armor[1]) : Lang::nf($armor[0])); // Melee Damage $melee = $_altNPCs->getBaseStats('melee'); if ($_ = $_altNPCs->getField('dmgSchool')) { // magic damage $modes['melee'][] = sprintf($modeRow, $m, Lang::nf($melee[0]) . ' - ' . Lang::nf($melee[1]) . ' (' . Lang::game('sc', $_) . ')'); } else { // phys. damage $modes['melee'][] = sprintf($modeRow, $m, Lang::nf($melee[0]) . ' - ' . Lang::nf($melee[1])); } // Ranged Damage $ranged = $_altNPCs->getBaseStats('ranged'); $modes['ranged'][] = sprintf($modeRow, $m, Lang::nf($ranged[0]) . ' - ' . Lang::nf($ranged[1])); } } } if ($modes) { foreach ($stats as $k => $v) { if ($v) { $stats[$k] = sprintf($hint, implode('[/tr][tr]', $modes[$k]), $v, $k); } } } // < Stats if ($stats) { $infobox[] = Lang::npc('stats') . ($modes ? ' (' . Lang::npc('modes', $mapType, 0) . ')' : null) . Lang::main('colon') . '[ul][li]' . implode('[/li][li]', $stats) . '[/li][/ul]'; } /****************/ /* Main Content */ /****************/ // get spawns and path $map = null; 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); } } // consider pooled spawns $this->map = $map; $this->infobox = '[ul][li]' . implode('[/li][li]', $infobox) . '[/li][/ul]'; $this->placeholder = $placeholder; $this->accessory = $accessory; $this->quotes = $this->getQuotes(); $this->reputation = $this->getOnKillRep($_altIds, $mapType); $this->redButtons = array(BUTTON_WOWHEAD => true, BUTTON_LINKS => true, BUTTON_VIEW3D => ['type' => TYPE_NPC, 'typeId' => $this->typeId, 'displayId' => $this->subject->getRandomModelId()]); /**************/ /* Extra Tabs */ /**************/ // tab: SAI // hmm, how should this look like // tab: abilities / tab_controlledabilities (dep: VehicleId) // SMART_SCRIPT_TYPE_CREATURE = 0; SMART_ACTION_CAST = 11; SMART_ACTION_ADD_AURA = 75; SMART_ACTION_INVOKER_CAST = 85; SMART_ACTION_CROSS_CAST = 86 $smartSpells = DB::World()->selectCol('SELECT action_param1 FROM smart_scripts WHERE source_type = 0 AND action_type IN (11, 75, 85, 86) AND entryOrGUID = ?d', $this->typeId); $tplSpells = []; $conditions = ['OR']; for ($i = 1; $i < 9; $i++) { if ($_ = $this->subject->getField('spell' . $i)) { $tplSpells[] = $_; } } if ($tplSpells) { $conditions[] = ['id', $tplSpells]; } if ($smartSpells) { $conditions[] = ['id', $smartSpells]; } // Pet-Abilities if ($_typeFlags & 0x1 && ($_ = $this->subject->getField('family'))) { $skill = 0; $mask = 0x0; foreach (Util::$skillLineMask[-1] as $idx => $pair) { if ($pair[0] != $_) { continue; } $skill = $pair[1]; $mask = 1 << $idx; break; } $conditions[] = ['AND', ['s.typeCat', -3], ['OR', ['skillLine1', $skill], ['AND', ['skillLine1', 0, '>'], ['skillLine2OrMask', $skill]], ['AND', ['skillLine1', -1], ['skillLine2OrMask', $mask, '&']]]]; } if (count($conditions) > 1) { $abilities = new SpellList($conditions); if (!$abilities->error) { $this->extendGlobalData($abilities->getJSGlobals(GLOBALINFO_SELF | GLOBALINFO_RELATED)); $controled = $abilities->getListviewData(); $normal = []; foreach ($controled as $id => $values) { if (in_array($id, $smartSpells)) { $normal[$id] = $values; unset($controled[$id]); continue; } // not quite right. All seats should be checked for allowed-to-cast-flag-something if (!$this->subject->getField('vehicleId') && in_array($id, $tplSpells)) { $normal[$id] = $values; unset($controled[$id]); } } if ($normal) { $this->lvTabs[] = array('file' => 'spell', 'data' => $normal, 'params' => array('name' => '$LANG.tab_abilities', 'id' => 'abilities')); } if ($controled) { $this->lvTabs[] = array('file' => 'spell', 'data' => $controled, 'params' => array('name' => '$LANG.tab_controlledabilities', 'id' => 'controlled-abilities')); } } } // tab: summoned by $conditions = array('OR', ['AND', ['effect1Id', 28], ['effect1MiscValue', $this->typeId]], ['AND', ['effect2Id', 28], ['effect2MiscValue', $this->typeId]], ['AND', ['effect3Id', 28], ['effect3MiscValue', $this->typeId]]); $summoned = new SpellList($conditions); if (!$summoned->error) { $this->extendGlobalData($summoned->getJSGlobals()); $this->lvTabs[] = array('file' => 'spell', 'data' => $summoned->getListviewData(), 'params' => array('name' => '$LANG.tab_summonedby', 'id' => 'summoned-by')); } // tab: teaches if ($this->subject->getField('npcflag') & NPC_FLAG_TRAINER) { $teachQuery = ' SELECT IFNULL(t2.SpellID, t1.SpellID) AS ARRAY_KEY, IFNULL(t2.MoneyCost, t1.MoneyCost) AS cost, IFNULL(t2.ReqSkillLine, t1.ReqSkillLine) AS reqSkillId, IFNULL(t2.ReqSkillRank, t1.ReqSkillRank) AS reqSkillValue, IFNULL(t2.ReqLevel, t1.ReqLevel) AS reqLevel FROM npc_trainer t1 LEFT JOIN npc_trainer t2 ON t2.ID = IF(t1.SpellID < 0, -t1.SpellID, null) WHERE t1.ID = ?d '; if ($tSpells = DB::World()->select($teachQuery, $this->typeId)) { $teaches = new SpellList(array(['id', array_keys($tSpells)])); if (!$teaches->error) { $this->extendGlobalData($teaches->getJSGlobals(GLOBALINFO_SELF | GLOBALINFO_RELATED)); $data = $teaches->getListviewData(); $extra = []; foreach ($tSpells as $sId => $train) { if (empty($data[$sId])) { continue; } if ($_ = $train['reqSkillId']) { $this->extendGlobalIds(TYPE_SKILL, $_); if (!isset($extra[0])) { $extra[0] = 'Listview.extraCols.condition'; } $data[$sId]['condition'][0][$this->typeId][] = [[CND_SKILL, $_, $train['reqSkillValue']]]; } if ($_ = $train['reqLevel']) { if (!isset($extra[1])) { $extra[1] = "Listview.funcBox.createSimpleCol('reqLevel', LANG.tooltip_reqlevel, '7%', 'reqLevel')"; } $data[$sId]['reqLevel'] = $_; } if ($_ = $train['cost']) { $data[$sId]['trainingcost'] = $_; } } $this->lvTabs[] = array('file' => 'spell', 'data' => $data, 'params' => array('name' => '$LANG.tab_teaches', 'id' => 'teaches', 'visibleCols' => "\$['trainingcost']", 'extraCols' => $extra ? '$[' . implode(', ', $extra) . ']' : null)); } } else { trigger_error('NPC ' . $this->typeId . ' is flagged as trainer, but doesn\'t have any spells set', E_USER_WARNING); } } // tab: sells if ($sells = DB::World()->selectCol('SELECT item FROM npc_vendor nv WHERE entry = ?d UNION SELECT item FROM game_event_npc_vendor genv JOIN creature c ON genv.guid = c.guid WHERE c.id = ?d', $this->typeId, $this->typeId)) { $soldItems = new ItemList(array(['id', $sells])); if (!$soldItems->error) { $extraCols = ["Listview.funcBox.createSimpleCol('stack', 'stack', '10%', 'stack')", 'Listview.extraCols.cost']; if ($soldItems->hasSetFields(['condition'])) { $extraCols[] = 'Listview.extraCols.condition'; } $lvData = $soldItems->getListviewData(ITEMINFO_VENDOR, [TYPE_NPC => [$this->typeId]]); $sc = Util::getServerConditions(CND_SRC_NPC_VENDOR, $this->typeId); if (!empty($sc[0])) { $this->extendGlobalData($sc[1]); if (!array_search('Listview.extraCols.condition', $extraCols)) { $extraCols[] = 'Listview.extraCols.condition'; } foreach ($lvData as $id => &$row) { foreach ($sc[0] as $srcType => $cndData) { if (!empty($cndData[$id . ':' . $this->typeId])) { $row['condition'][0][$id . ':' . $this->typeId] = $cndData[$id . ':' . $this->typeId]; } } } } $this->lvTabs[] = array('file' => 'item', 'data' => $lvData, 'params' => array('name' => '$LANG.tab_sells', 'id' => 'currency-for', 'extraCols' => '$[' . implode(', ', $extraCols) . ']')); $this->extendGlobalData($soldItems->getJSGlobals(GLOBALINFO_SELF | GLOBALINFO_RELATED)); } } // tabs: this creature contains.. $skinTab = ['tab_skinning', 'skinning']; if ($_typeFlags & NPC_TYPEFLAG_HERBLOOT) { $skinTab = ['tab_herbalism', 'herbalism']; } else { if ($_typeFlags & NPC_TYPEFLAG_MININGLOOT) { $skinTab = ['tab_mining', 'mining']; } else { if ($_typeFlags & NPC_TYPEFLAG_ENGINEERLOOT) { $skinTab = ['tab_engineering', 'engineering']; } } } /* extraCols: [Listview.extraCols.count, Listview.extraCols.percent, Listview.extraCols.mode], _totalCount: 22531, computeDataFunc: Listview.funcBox.initLootTable, onAfterCreate: Listview.funcBox.addModeIndicator, modes:{"mode":1,"1":{"count":4408,"outof":16013},"4":{"count":4408,"outof":22531}} */ $sourceFor = array([LOOT_CREATURE, $this->subject->getField('lootId'), '$LANG.tab_drops', 'drops', []], [LOOT_PICKPOCKET, $this->subject->getField('pickpocketLootId'), '$LANG.tab_pickpocketing', 'pickpocketing', ['side', 'slot', 'reqlevel']], [LOOT_SKINNING, $this->subject->getField('skinLootId'), '$LANG.' . $skinTab[0], $skinTab[1], ['side', 'slot', 'reqlevel']]); // temp: manually add loot for difficulty-versions $langref = array("-2" => '$LANG.tab_heroic', "-1" => '$LANG.tab_normal', 1 => '$$WH.sprintf(LANG.tab_normalX, 10)', 2 => '$$WH.sprintf(LANG.tab_normalX, 25)', 3 => '$$WH.sprintf(LANG.tab_heroicX, 10)', 4 => '$$WH.sprintf(LANG.tab_heroicX, 25)'); if ($_altIds) { $sourceFor[0][2] = $mapType == 1 ? $langref[-1] : $langref[1]; foreach ($_altNPCs->iterate() as $id => $__) { $mode = ($_altIds[$id] + 1) * ($mapType == 1 ? -1 : 1); if ($lootGO = DB::Aowow()->selectRow('SELECT o.id, o.lootId, o.name_loc0, o.name_loc2, o.name_loc3, o.name_loc6, o.name_loc8 FROM ?_loot_link l JOIN ?_objects o ON o.id = l.objectId WHERE l.npcId = ?d', $id)) { array_splice($sourceFor, 1, 0, [[LOOT_GAMEOBJECT, $lootGO['lootId'], $langref[$mode], 'drops-object-' . abs($mode), [], 'note' => '$$WH.sprintf(LANG.lvnote_npcobjectsource, ' . $lootGO['id'] . ', \'' . Util::jsEscape(Util::localizedString($lootGO, 'name')) . '\')']]); } if ($lootId = $_altNPCs->getField('lootId')) { array_splice($sourceFor, 1, 0, [[LOOT_CREATURE, $lootId, $langref[$mode], 'drops-' . abs($mode), []]]); } } } if ($lootGOs = DB::Aowow()->select('SELECT o.id, IF(npcId < 0, 1, 0) AS modeDummy, o.lootId, o.name_loc0, o.name_loc2, o.name_loc3, o.name_loc6, o.name_loc8 FROM ?_loot_link l JOIN ?_objects o ON o.id = l.objectId WHERE ABS(l.npcId) = ?d', $this->typeId)) { foreach ($lootGOs as $idx => $lgo) { array_splice($sourceFor, 1, 0, [[LOOT_GAMEOBJECT, $lgo['lootId'], $mapType ? $langref[($mapType == 1 ? -1 : 1) + ($lgo['modeDummy'] ? 1 : 0)] : '$LANG.tab_drops', 'drops-object-' . $idx, [], 'note' => '$$WH.sprintf(LANG.lvnote_npcobjectsource, ' . $lgo['id'] . ', \'' . Util::jsEscape(Util::localizedString($lgo, 'name')) . '\')']]); } } $reqQuest = []; foreach ($sourceFor as $sf) { $creatureLoot = new Loot(); if ($creatureLoot->getByContainer($sf[0], $sf[1])) { $extraCols = $creatureLoot->extraCols; $extraCols[] = 'Listview.extraCols.percent'; $this->extendGlobalData($creatureLoot->jsGlobals); foreach ($creatureLoot->iterate() as &$lv) { if (!$lv['quest']) { continue; } $extraCols[] = 'Listview.extraCols.condition'; $reqQuest[$lv['id']] = 0; $lv['condition'][0][$this->typeId][] = [[CND_QUESTTAKEN, &$reqQuest[$lv['id']]]]; } $lootTab = array('file' => 'item', 'data' => $creatureLoot->getResult(), 'params' => array('name' => $sf[2], 'id' => $sf[3], 'extraCols' => "\$[" . implode(', ', array_unique($extraCols)) . "]", 'hiddenCols' => $sf[4] ? "\$" . Util::toJSON($sf[4]) : null, 'sort' => "\$['-percent', 'name']")); if (!empty($sf['note'])) { $lootTab['params']['note'] = $sf['note']; } $this->lvTabs[] = $lootTab; } } if ($reqIds = array_keys($reqQuest)) { $conditions = array('OR', ['reqSourceItemId1', $reqIds], ['reqSourceItemId2', $reqIds], ['reqSourceItemId3', $reqIds], ['reqSourceItemId4', $reqIds], ['reqItemId1', $reqIds], ['reqItemId2', $reqIds], ['reqItemId3', $reqIds], ['reqItemId4', $reqIds], ['reqItemId5', $reqIds], ['reqItemId6', $reqIds]); $reqQuests = new QuestList($conditions); $this->extendGlobalData($reqQuests->getJSGlobals()); foreach ($reqQuests->iterate() as $qId => $__) { if (empty($reqQuests->requires[$qId][TYPE_ITEM])) { continue; } foreach ($reqIds as $rId) { if (in_array($rId, $reqQuests->requires[$qId][TYPE_ITEM])) { $reqQuest[$rId] = $reqQuests->id; } } } } // tab: starts quest // tab: ends quest $startEnd = new QuestList(array(['qse.type', TYPE_NPC], ['qse.typeId', $this->typeId])); if (!$startEnd->error) { $this->extendGlobalData($startEnd->getJSGlobals()); $lvData = $startEnd->getListviewData(); $_ = [[], []]; foreach ($startEnd->iterate() as $id => $__) { $m = $startEnd->getField('method'); if ($m & 0x1) { $_[0][] = $lvData[$id]; } if ($m & 0x2) { $_[1][] = $lvData[$id]; } } if ($_[0]) { $this->lvTabs[] = array('file' => 'quest', 'data' => $_[0], 'params' => array('name' => '$LANG.tab_starts', 'id' => 'starts')); } if ($_[1]) { $this->lvTabs[] = array('file' => 'quest', 'data' => $_[1], 'params' => array('name' => '$LANG.tab_ends', 'id' => 'ends')); } } // tab: objective of quest $conditions = array('OR', ['AND', ['reqNpcOrGo1', $this->typeId], ['reqNpcOrGoCount1', 0, '>']], ['AND', ['reqNpcOrGo2', $this->typeId], ['reqNpcOrGoCount2', 0, '>']], ['AND', ['reqNpcOrGo3', $this->typeId], ['reqNpcOrGoCount3', 0, '>']], ['AND', ['reqNpcOrGo4', $this->typeId], ['reqNpcOrGoCount4', 0, '>']]); $objectiveOf = new QuestList($conditions); if (!$objectiveOf->error) { $this->extendGlobalData($objectiveOf->getJSGlobals()); $this->lvTabs[] = array('file' => 'quest', 'data' => $objectiveOf->getListviewData(), 'params' => array('name' => '$LANG.tab_objectiveof', 'id' => 'objective-of')); } // tab: criteria of [ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE_TYPE have no data set to check for] $conditions = array(['ac.type', [ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE, ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_CREATURE]], ['ac.value1', $this->typeId]); $crtOf = new AchievementList($conditions); if (!$crtOf->error) { $this->extendGlobalData($crtOf->getJSGlobals()); $this->lvTabs[] = array('file' => 'achievement', 'data' => $crtOf->getListviewData(), 'params' => array('name' => '$LANG.tab_criteriaof', 'id' => 'criteria-of')); } // tab: passengers if ($_ = DB::World()->selectCol('SELECT accessory_entry AS ARRAY_KEY, GROUP_CONCAT(seat_id) FROM vehicle_template_accessory WHERE entry = ?d GROUP BY accessory_entry', $this->typeId)) { $passengers = new CreatureList(array(['id', array_keys($_)])); if (!$passengers->error) { $data = $passengers->getListviewData(); $xCols = null; if (User::isInGroup(U_GROUP_STAFF)) { foreach ($data as $id => &$d) { $d['seat'] = str_replace(',', ', ', $_[$id]); } $xCols = "\$[Listview.funcBox.createSimpleCol('seat', '" . Lang::npc('seat') . "', '10%', 'seat')]"; } $this->extendGlobalData($passengers->getJSGlobals(GLOBALINFO_SELF)); $this->lvTabs[] = array('file' => 'creature', 'data' => $data, 'params' => array('extraCols' => $xCols, 'name' => Lang::npc('accessory'), 'id' => 'accessory')); } } }
protected function generateContent() { $this->addJS('?data=zones&locale=' . User::$localeId . '&t=' . $_SESSION['dataKey']); /***********/ /* Infobox */ /***********/ $this->infobox = Lang::getInfoBoxForFlags($this->subject->getField('cuFlags')); // boss if ($_ = $this->subject->getField('bossCreature')) { $this->extendGlobalIds(TYPE_NPC, $_); $this->infobox[] = Lang::npc('rank', 3) . Lang::main('colon') . '[npc=' . $_ . ']'; } // display internal id to staff if (User::isInGroup(U_GROUP_STAFF)) { $this->infobox[] = 'Event-Id' . Lang::main('colon') . $this->eId; } /****************/ /* Main Content */ /****************/ // no entry in ?_articles? use default HolidayDescription if ($this->hId && empty($this->article)) { $this->article = ['text' => Util::jsEscape($this->subject->getField('description', true)), 'params' => []]; } $this->headIcons = [$this->subject->getField('iconString')]; $this->redButtons = array(BUTTON_WOWHEAD => $this->hId > 0, BUTTON_LINKS => true); /**************/ /* Extra Tabs */ /**************/ $hasFilter = in_array($this->hId, [372, 283, 285, 353, 420, 400, 284, 201, 374, 409, 141, 324, 321, 424, 335, 327, 341, 181, 404, 398, 301]); // tab: npcs if ($npcIds = DB::World()->selectCol('SELECT id AS ARRAY_KEY, IF(ec.eventEntry > 0, 1, 0) AS added FROM creature c, game_event_creature ec WHERE ec.guid = c.guid AND ABS(ec.eventEntry) = ?d', $this->eId)) { $creatures = new CreatureList(array(['id', array_keys($npcIds)])); if (!$creatures->error) { $data = $creatures->getListviewData(); foreach ($data as &$d) { $d['method'] = $npcIds[$d['id']]; } $tabData = ['data' => array_values($data)]; if ($hasFilter) { $tabData['note'] = sprintf(Util::$filterResultString, '?npcs&filter=cr=38;crs=' . $this->hId . ';crv=0'); } $this->lvTabs[] = ['creature', $tabData]; } } // tab: objects if ($objectIds = DB::World()->selectCol('SELECT id AS ARRAY_KEY, IF(eg.eventEntry > 0, 1, 0) AS added FROM gameobject g, game_event_gameobject eg WHERE eg.guid = g.guid AND ABS(eg.eventEntry) = ?d', $this->eId)) { $objects = new GameObjectList(array(['id', array_keys($objectIds)])); if (!$objects->error) { $data = $objects->getListviewData(); foreach ($data as &$d) { $d['method'] = $objectIds[$d['id']]; } $tabData = ['data' => array_values($data)]; if ($hasFilter) { $tabData['note'] = sprintf(Util::$filterResultString, '?objects&filter=cr=16;crs=' . $this->hId . ';crv=0'); } $this->lvTabs[] = ['object', $tabData]; } } // tab: achievements if ($_ = $this->subject->getField('achievementCatOrId')) { $condition = $_ > 0 ? [['category', $_]] : [['id', -$_]]; $acvs = new AchievementList($condition); if (!$acvs->error) { $this->extendGlobalData($acvs->getJSGlobals(GLOBALINFO_SELF | GLOBALINFO_RELATED)); $tabData = array('data' => array_values($acvs->getListviewData()), 'visibleCols' => ['category']); if ($hasFilter) { $tabData['note'] = sprintf(Util::$filterResultString, '?achievements&filter=cr=11;crs=' . $this->hId . ';crv=0'); } $this->lvTabs[] = ['achievement', $tabData]; } } $itemCnd = []; if ($this->hId) { $itemCnd = array('OR', ['eventId', $this->eId]); // tab: quests (by table, go & creature) $quests = new QuestList(array(['eventId', $this->eId])); if (!$quests->error) { $this->extendGlobalData($quests->getJSGlobals(GLOBALINFO_SELF | GLOBALINFO_REWARDS)); $tabData = ['data' => array_values($quests->getListviewData())]; if ($hasFilter) { $tabData['note'] = sprintf(Util::$filterResultString, '?quests&filter=cr=33;crs=' . $this->hId . ';crv=0'); } $this->lvTabs[] = ['quest', $tabData]; $questItems = []; foreach (array_column($quests->rewards, TYPE_ITEM) as $arr) { $questItems = array_merge($questItems, $arr); } foreach (array_column($quests->requires, TYPE_ITEM) as $arr) { $questItems = array_merge($questItems, $arr); } if ($questItems) { $itemCnd[] = ['id', $questItems]; } } } // items from creature if ($npcIds && !$creatures->error) { // vendor $cIds = $creatures->getFoundIDs(); if ($sells = DB::World()->selectCol('SELECT item FROM npc_vendor nv WHERE entry IN (?a) UNION SELECT item FROM game_event_npc_vendor genv JOIN creature c ON genv.guid = c.guid WHERE c.id IN (?a)', $cIds, $cIds)) { $itemCnd[] = ['id', $sells]; } } // tab: items // not checking for loot ... cant distinguish between eventLoot and fillerCrapLoot if ($itemCnd) { $eventItems = new ItemList($itemCnd); if (!$eventItems->error) { $this->extendGlobalData($eventItems->getJSGlobals(GLOBALINFO_SELF)); $tabData = ['data' => array_values($eventItems->getListviewData())]; if ($hasFilter) { $tabData['note'] = sprintf(Util::$filterResultString, '?items&filter=cr=160;crs=' . $this->hId . ';crv=0'); } $this->lvTabs[] = ['item', $tabData]; } } // tab: see also (event conditions) if ($rel = DB::World()->selectCol('SELECT IF(eventEntry = prerequisite_event, NULL, IF(eventEntry = ?d, prerequisite_event, -eventEntry)) FROM game_event_prerequisite WHERE prerequisite_event = ?d OR eventEntry = ?d', $this->eId, $this->eId, $this->eId)) { $list = []; array_walk($rel, function ($v, $k) use(&$list) { if ($v > 0) { $list[] = $v; } else { if ($v === null) { trigger_error('game_event_prerequisite: this event has itself as prerequisite', E_USER_WARNING); } } }); if ($list) { $relEvents = new WorldEventList(array(['id', $list])); $this->extendGlobalData($relEvents->getJSGlobals()); $relData = $relEvents->getListviewData(); foreach ($relEvents->getFoundIDs() as $id) { $relData[$id]['condition'][0][$this->typeId][] = [[-CND_ACTIVE_EVENT, $this->eId]]; } $this->extendGlobalData($this->subject->getJSGlobals()); foreach ($rel as $r) { if ($r <= 0) { continue; } $this->extendGlobalIds(TYPE_WORLDEVENT, $r); $d = $this->subject->getListviewData(); $d[$this->eId]['condition'][0][$this->typeId][] = [[-CND_ACTIVE_EVENT, $r]]; $relData = array_merge($relData, $d); } $this->lvTabs[] = ['event', array('data' => array_values($relData), 'id' => 'see-also', 'name' => '$LANG.tab_seealso', 'hiddenCols' => ['date'], 'extraCols' => ['$Listview.extraCols.condition'])]; } } }
protected function generateContent() { $this->addJS('?data=zones&locale=' . User::$localeId . '&t=' . $_SESSION['dataKey']); /***********/ /* Infobox */ /***********/ $infobox = Lang::getInfoBoxForFlags($this->subject->getField('cuFlags')); // level range $infobox[] = Lang::game('level') . Lang::main('colon') . $this->subject->getField('minLevel') . ' - ' . $this->subject->getField('maxLevel'); // exotic if ($this->subject->getField('exotic')) { $infobox[] = '[url=?spell=53270]' . Lang::pet('exotic') . '[/url]'; } /****************/ /* Main Content */ /****************/ $this->infobox = '[ul][li]' . implode('[/li][li]', $infobox) . '[/li][/ul]'; $this->headIcons = [$this->subject->getField('iconString')]; $this->expansion = Util::$expansionString[$this->subject->getField('expansion')]; $this->redButtons = array(BUTTON_WOWHEAD => true, BUTTON_LINKS => true, BUTTON_TALENT => ['href' => '?petcalc#' . Util::$tcEncoding[(int) ($this->typeId / 10)] . Util::$tcEncoding[2 * ($this->typeId % 10) + ($this->subject->getField('exotic') ? 1 : 0)], 'pet' => true]); /**************/ /* Extra Tabs */ /**************/ // tab: tameable & gallery $condition = array(['ct.type', 1], ['ct.typeFlags', 0x1, '&'], ['ct.family', $this->typeId], ['OR', ['ft.A', 1, '<'], ['ft.H', 1, '<']]); $tng = new CreatureList($condition); $this->lvTabs[] = array('file' => 'creature', 'data' => $tng->getListviewData(NPCINFO_TAMEABLE), 'params' => array('name' => '$LANG.tab_tameable', 'hiddenCols' => "\$['type']", 'visibleCols' => "\$['skin']", 'note' => sprintf(Util::$filterResultString, '?npcs=1&filter=fa=38'), 'id' => 'tameable')); $this->lvTabs[] = array('file' => 'model', 'data' => $tng->getListviewData(NPCINFO_MODEL), 'params' => []); // tab: diet $list = []; $mask = $this->subject->getField('foodMask'); for ($i = 1; $i < 7; $i++) { if ($mask & 1 << $i - 1) { $list[] = $i; } } $food = new ItemList(array(['i.subClass', [5, 8]], ['i.FoodType', $list], CFG_SQL_LIMIT_NONE)); $this->extendGlobalData($food->getJSGlobals()); $this->lvTabs[] = array('file' => 'item', 'data' => $food->getListviewData(), 'params' => array('name' => '$LANG.diet', 'hiddenCols' => "\$['source', 'slot', 'side']", 'sort' => "\$['level']", 'id' => 'diet')); // tab: spells $mask = 0x0; foreach (Util::$skillLineMask[-1] as $idx => $pair) { if ($pair[0] == $this->typeId) { $mask = 1 << $idx; break; } } $conditions = [['s.typeCat', -3], ['OR', ['skillLine1', $this->subject->getField('skillLineId')], ['AND', ['skillLine1', 0, '>'], ['skillLine2OrMask', $this->subject->getField('skillLineId')]], ['AND', ['skillLine1', -1], ['skillLine2OrMask', $mask, '&']]]]; $spells = new SpellList($conditions); $this->extendGlobalData($spells->getJSGlobals(GLOBALINFO_SELF)); $this->lvTabs[] = array('file' => 'spell', 'data' => $spells->getListviewData(), 'params' => array('name' => '$LANG.tab_abilities', 'visibleCols' => "\$['schools', 'level']", 'id' => 'abilities')); // tab: talents $conditions = array(['s.typeCat', -7], ['OR', ['s.cuFlags', SPELL_CU_LAST_RANK, '&'], ['s.rankNo', 0]]); switch ($this->subject->getField('type')) { case 0: $conditions[] = ['s.cuFlags', SPELL_CU_PET_TALENT_TYPE0, '&']; break; case 1: $conditions[] = ['s.cuFlags', SPELL_CU_PET_TALENT_TYPE1, '&']; break; case 2: $conditions[] = ['s.cuFlags', SPELL_CU_PET_TALENT_TYPE2, '&']; break; } $talents = new SpellList($conditions); $this->extendGlobalData($talents->getJSGlobals(GLOBALINFO_SELF)); $this->lvTabs[] = array('file' => 'spell', 'data' => $talents->getListviewData(), 'params' => array('visibleCols' => "\$['tier', 'level']", 'name' => '$LANG.tab_talents', 'id' => 'talents', 'sort' => "\$['tier', 'name']", '_petTalents' => 1)); }
protected function generateContent() { $this->addJS('?data=weight-presets.zones&locale=' . User::$localeId . '&t=' . $_SESSION['dataKey']); $_flags = $this->subject->getField('flags'); $_slot = $this->subject->getField('slot'); $_class = $this->subject->getField('class'); $_subClass = $this->subject->getField('subClass'); $_bagFamily = $this->subject->getField('bagFamily'); $_model = $this->subject->getField('displayId'); $_visSlots = array(INVTYPE_HEAD, INVTYPE_SHOULDERS, INVTYPE_BODY, INVTYPE_CHEST, INVTYPE_WAIST, INVTYPE_LEGS, INVTYPE_FEET, INVTYPE_WRISTS, INVTYPE_HANDS, INVTYPE_WEAPON, INVTYPE_SHIELD, INVTYPE_RANGED, INVTYPE_CLOAK, INVTYPE_2HWEAPON, INVTYPE_TABARD, INVTYPE_ROBE, INVTYPE_WEAPONMAINHAND, INVTYPE_WEAPONOFFHAND, INVTYPE_HOLDABLE, INVTYPE_THROWN, INVTYPE_RANGEDRIGHT); /***********/ /* Infobox */ /***********/ $infobox = Lang::getInfoBoxForFlags($this->subject->getField('cuFlags')); // itemlevel if (in_array($_class, [ITEM_CLASS_ARMOR, ITEM_CLASS_WEAPON, ITEM_CLASS_AMMUNITION]) || $this->subject->getField('gemEnchantmentId')) { $infobox[] = Lang::game('level') . Lang::main('colon') . $this->subject->getField('itemLevel'); } // account-wide if ($_flags & ITEM_FLAG_ACCOUNTBOUND) { $infobox[] = Lang::item('accountWide'); } // side if ($si = $this->subject->json[$this->typeId]['side']) { if ($si != 3) { $infobox[] = Lang::main('side') . Lang::main('colon') . '[span class=icon-' . ($si == 1 ? 'alliance' : 'horde') . ']' . Lang::game('si', $si) . '[/span]'; } } // consumable / not consumable if (!$_slot) { $hasUse = false; for ($i = 1; $i < 6; $i++) { if ($this->subject->getField('spellId' . $i) <= 0 || in_array($this->subject->getField('spellTrigger' . $i), [1, 2])) { continue; } $hasUse = true; if ($this->subject->getField('spellCharges' . $i) >= 0) { continue; } $tt = '[tooltip=tooltip_consumedonuse]' . Lang::item('consumable') . '[/tooltip]'; break; } if ($hasUse) { $infobox[] = isset($tt) ? $tt : '[tooltip=tooltip_notconsumedonuse]' . Lang::item('nonConsumable') . '[/tooltip]'; } } // related holiday if ($hId = $this->subject->getField('holidayId')) { if ($hName = DB::Aowow()->selectRow('SELECT * FROM ?_holidays WHERE id = ?d', $hId)) { $infobox[] = Lang::game('eventShort') . Lang::main('colon') . '[url=?event=' . $hId . ']' . Util::localizedString($hName, 'name') . '[/url]'; } } // tool if ($tId = $this->subject->getField('totemCategory')) { if ($tName = DB::Aowow()->selectRow('SELECT * FROM ?_totemcategory WHERE id = ?d', $tId)) { $infobox[] = Lang::item('tool') . Lang::main('colon') . '[url=?items&filter=cr=91;crs=' . $tId . ';crv=0]' . Util::localizedString($tName, 'name') . '[/url]'; } } // extendedCost if (!empty($this->subject->getExtendedCost([], $_reqRating)[$this->subject->id])) { $vendors = $this->subject->getExtendedCost()[$this->subject->id]; $each = $this->subject->getField('stackable') > 1 ? '[color=q0] (' . Lang::item('each') . ')[/color]' : null; $handled = []; $costList = []; foreach ($vendors as $npcId => $data) { $tokens = []; $currency = []; if (!is_array($data)) { continue; } foreach ($data as $c => $qty) { if (is_string($c)) { unset($data[$c]); // unset miscData to prevent having two vendors /w the same cost being cached, because of different stock or rating-requirements continue; } if ($c < 0) { // currency items (and honor or arena) $currency[] = -$c . ',' . $qty; } else { if ($c > 0) { // plain items (item1,count1,item2,count2,...) $tokens[$c] = $c . ',' . $qty; } } } // display every cost-combination only once if (in_array(md5(serialize($data)), $handled)) { continue; } $handled[] = md5(serialize($data)); $cost = isset($data[0]) ? '[money=' . $data[0] : '[money'; if ($tokens) { $cost .= ' items=' . implode(',', $tokens); } if ($currency) { $cost .= ' currency=' . implode(',', $currency); } $cost .= ']'; $costList[] = $cost; } if (count($costList) == 1) { $infobox[] = Lang::item('cost') . Lang::main('colon') . $costList[0] . $each; } else { if (count($costList) > 1) { $infobox[] = Lang::item('cost') . $each . Lang::main('colon') . '[ul][li]' . implode('[/li][li]', $costList) . '[/li][/ul]'; } } if ($_reqRating) { $res = []; $i = 0; $len = 0; $parts = explode(' ', str_replace('<br>', ' ', sprintf(Lang::item('reqRating', $_reqRating[1]), $_reqRating[0]))); foreach ($parts as $p) { $res[$i][] = $p; $len += mb_strlen($p) + 1; if ($len < 30) { continue; } $len = 0; $i++; } foreach ($res as &$r) { $r = implode(' ', $r); } $infobox[] = implode('[br]', $res); } } // repair cost if ($_ = $this->subject->getField('repairPrice')) { $infobox[] = Lang::item('repairCost') . Lang::main('colon') . '[money=' . $_ . ']'; } // avg auction buyout if (in_array($this->subject->getField('bonding'), [0, 2, 3])) { if ($_ = Util::getBuyoutForItem($this->typeId)) { $infobox[] = '[tooltip=tooltip_buyoutprice]' . Lang::item('buyout.') . '[/tooltip]' . Lang::main('colon') . '[money=' . $_ . ']' . $each; } } // avg money contained if ($_flags & ITEM_FLAG_OPENABLE) { if ($_ = intVal(($this->subject->getField('minMoneyLoot') + $this->subject->getField('maxMoneyLoot')) / 2)) { $infobox[] = Lang::item('worth') . Lang::main('colon') . '[tooltip=tooltip_avgmoneycontained][money=' . $_ . '][/tooltip]'; } } // if it goes into a slot it may be disenchanted if ($_slot && $_class != ITEM_CLASS_CONTAINER) { if ($this->subject->getField('disenchantId')) { $_ = $this->subject->getField('requiredDisenchantSkill'); if ($_ < 1) { // these are some items, that never went live .. extremely rough emulation here $_ = intVal($this->subject->getField('itemLevel') / 7.5) * 25; } $infobox[] = Lang::item('disenchantable') . ' ([tooltip=tooltip_reqenchanting]' . $_ . '[/tooltip])'; } else { $infobox[] = Lang::item('cantDisenchant'); } } if ($_flags & ITEM_FLAG_MILLABLE && $this->subject->getField('requiredSkill') == 773) { $infobox[] = Lang::item('millable') . ' ([tooltip=tooltip_reqinscription]' . $this->subject->getField('requiredSkillRank') . '[/tooltip])'; } if ($_flags & ITEM_FLAG_PROSPECTABLE && $this->subject->getField('requiredSkill') == 755) { $infobox[] = Lang::item('prospectable') . ' ([tooltip=tooltip_reqjewelcrafting]' . $this->subject->getField('requiredSkillRank') . '[/tooltip])'; } if ($_flags & ITEM_FLAG_DEPRECATED) { $infobox[] = '[tooltip=tooltip_deprecated]' . Lang::item('deprecated') . '[/tooltip]'; } if ($_flags & ITEM_FLAG_NO_EQUIPCD) { $infobox[] = '[tooltip=tooltip_noequipcooldown]' . Lang::item('noEquipCD') . '[/tooltip]'; } if ($_flags & ITEM_FLAG_PARTYLOOT) { $infobox[] = '[tooltip=tooltip_partyloot]' . Lang::item('partyLoot') . '[/tooltip]'; } if ($_flags & ITEM_FLAG_REFUNDABLE) { $infobox[] = '[tooltip=tooltip_refundable]' . Lang::item('refundable') . '[/tooltip]'; } if ($_flags & ITEM_FLAG_SMARTLOOT) { $infobox[] = '[tooltip=tooltip_smartloot]' . Lang::item('smartLoot') . '[/tooltip]'; } if ($_flags & ITEM_FLAG_INDESTRUCTIBLE) { $infobox[] = Lang::item('indestructible'); } if ($_flags & ITEM_FLAG_USABLE_ARENA) { $infobox[] = Lang::item('useInArena'); } if ($_flags & ITEM_FLAG_USABLE_SHAPED) { $infobox[] = Lang::item('useInShape'); } // cant roll need if ($this->subject->getField('flagsExtra') & 0x100) { $infobox[] = '[tooltip=tooltip_cannotrollneed]' . Lang::item('noNeedRoll') . '[/tooltip]'; } // fits into keyring if ($_bagFamily & 0x100) { $infobox[] = Lang::item('atKeyring'); } /****************/ /* Main Content */ /****************/ $_cu = in_array($_class, [ITEM_CLASS_WEAPON, ITEM_CLASS_ARMOR]) || $this->subject->getField('gemEnchantmentId'); $this->headIcons = [$this->subject->getField('iconString'), $this->subject->getField('stackable')]; $this->infobox = $infobox ? '[ul][li]' . implode('[/li][li]', $infobox) . '[/li][/ul]' : null; $this->tooltip = $this->subject->renderTooltip(true); $this->redButtons = array(BUTTON_WOWHEAD => true, BUTTON_LINKS => ['color' => 'ff' . Util::$rarityColorStings[$this->subject->getField('quality')], 'linkId' => 'item:' . $this->typeId . ':0:0:0:0:0:0:0:0'], BUTTON_VIEW3D => in_array($_slot, $_visSlots) && $_model ? ['displayId' => $this->subject->getField('displayId'), 'slot' => $_slot, 'type' => TYPE_ITEM, 'typeId' => $this->typeId] : false, BUTTON_COMPARE => $_cu, BUTTON_EQUIP => in_array($_class, [ITEM_CLASS_WEAPON, ITEM_CLASS_ARMOR]), BUTTON_UPGRADE => $_cu ? ['class' => $_class, 'slot' => $_slot] : false); // availablility $this->disabled = false; // todo (med): get itemSources (which are not yet in DB :x) or // pageText if ($next = $this->subject->getField('pageTextId')) { $this->addJS('Book.js'); $this->addCSS(['path' => 'Book.css']); while ($next) { $row = DB::World()->selectRow('SELECT *, text as Text_loc0 FROM page_text pt LEFT JOIN locales_page_text lpt ON pt.entry = lpt.entry WHERE pt.entry = ?d', $next); $next = $row['next_page']; $this->pageText[] = Util::parseHtmlText(Util::localizedString($row, 'Text')); } } // subItems $this->subject->initSubItems(); if (!empty($this->subject->subItems[$this->typeId])) { uaSort($this->subject->subItems[$this->typeId], function ($a, $b) { return strcmp($a['name'], $b['name']); }); $this->subItems = array('data' => array_values($this->subject->subItems[$this->typeId]), 'quality' => $this->subject->getField('quality')); // merge identical stats and names for normal users (e.g. spellPower of a specific school became generel spellPower with 3.0) if (!User::isInGroup(U_GROUP_EMPLOYEE)) { for ($i = 1; $i < count($this->subItems['data']); $i++) { $prev =& $this->subItems['data'][$i - 1]; $cur =& $this->subItems['data'][$i]; if ($prev['jsonequip'] == $cur['jsonequip'] && $prev['name'] == $cur['name']) { $prev['chance'] += $cur['chance']; array_splice($this->subItems['data'], $i, 1); $i = 1; } } } } // factionchange-equivalent if ($pendant = DB::World()->selectCell('SELECT IF(horde_id = ?d, alliance_id, -horde_id) FROM player_factionchange_items WHERE alliance_id = ?d OR horde_id = ?d', $this->typeId, $this->typeId, $this->typeId)) { $altItem = new ItemList(array(['id', abs($pendant)])); if (!$altItem->error) { $this->transfer = sprintf(Lang::item('_transfer'), $altItem->id, $altItem->getField('quality'), $altItem->getField('iconString'), $altItem->getField('name', true), $pendant > 0 ? 'alliance' : 'horde', $pendant > 0 ? Lang::game('si', 1) : Lang::game('si', 2)); } } /**************/ /* Extra Tabs */ /**************/ // tabs: this item is contained in.. $lootTabs = new Loot(); $createdBy = []; if ($lootTabs->getByItem($this->typeId)) { $this->extendGlobalData($lootTabs->jsGlobals); foreach ($lootTabs->iterate() as $idx => $tab) { if (!$tab[1]) { continue; } if ($idx == 16) { $createdBy = array_column($tab[1], 'id'); } $this->lvTabs[] = array('file' => $tab[0], 'data' => $tab[1], 'params' => ['name' => $tab[2], 'id' => $tab[3], 'extraCols' => $tab[4] ? '$[' . implode(', ', array_unique($tab[4])) . ']' : null, 'hiddenCols' => $tab[5] ? '$ ' . Util::toJSON(array_unique($tab[5])) : null, 'visibleCols' => $tab[6] ? '$' . Util::toJSON(array_unique($tab[6])) : null]); } } // tabs: this item contains.. $sourceFor = array([LOOT_ITEM, $this->subject->id, '$LANG.tab_contains', 'contains', ['Listview.extraCols.percent'], [], []], [LOOT_PROSPECTING, $this->subject->id, '$LANG.tab_prospecting', 'prospecting', ['Listview.extraCols.percent'], ['side', 'slot', 'reqlevel'], []], [LOOT_MILLING, $this->subject->id, '$LANG.tab_milling', 'milling', ['Listview.extraCols.percent'], ['side', 'slot', 'reqlevel'], []], [LOOT_DISENCHANT, $this->subject->getField('disenchantId'), '$LANG.tab_disenchanting', 'disenchanting', ['Listview.extraCols.percent'], ['side', 'slot', 'reqlevel'], []]); $reqQuest = []; foreach ($sourceFor as $sf) { $lootTab = new Loot(); if ($lootTab->getByContainer($sf[0], $sf[1])) { $this->extendGlobalData($lootTab->jsGlobals); $sf[4] = array_merge($sf[4], $lootTab->extraCols); foreach ($lootTab->iterate() as $lv) { if (!$lv['quest']) { continue; } $sf[4] = array_merge($sf[4], ['Listview.extraCols.condition']); $reqQuest[$lv['id']] = 0; $lv['condition'][0][$this->typeId][] = [[CND_QUESTTAKEN, &$reqQuest[$lv['id']]]]; } $this->lvTabs[] = array('file' => 'item', 'data' => $lootTab->getResult(), 'params' => ['name' => $sf[2], 'id' => $sf[3], 'extraCols' => $sf[4] ? "\$[" . implode(', ', array_unique($sf[4])) . "]" : null, 'hiddenCols' => $sf[5] ? "\$" . Util::toJSON($sf[5]) : null, 'visibleCols' => $sf[6] ? '$' . Util::toJSON($sf[6]) : null]); } } if ($reqIds = array_keys($reqQuest)) { $conditions = array('OR', ['reqSourceItemId1', $reqIds], ['reqSourceItemId2', $reqIds], ['reqSourceItemId3', $reqIds], ['reqSourceItemId4', $reqIds], ['reqItemId1', $reqIds], ['reqItemId2', $reqIds], ['reqItemId3', $reqIds], ['reqItemId4', $reqIds], ['reqItemId5', $reqIds], ['reqItemId6', $reqIds]); $reqQuests = new QuestList($conditions); $reqQuests->getJSGlobals(GLOBALINFO_SELF); foreach ($reqQuests->iterate() as $qId => $__) { if (empty($reqQuests->requires[$qId][TYPE_ITEM])) { continue; } foreach ($reqIds as $rId) { if (in_array($rId, $reqQuests->requires[$qId][TYPE_ITEM])) { $reqQuest[$rId] = $reqQuests->id; } } } } // tab: container can contain if ($this->subject->getField('slots') > 0) { $contains = new ItemList(array(['bagFamily', $_bagFamily, '&'], ['slots', 1, '<'], CFG_SQL_LIMIT_NONE)); if (!$contains->error) { $this->extendGlobalData($contains->getJSGlobals(GLOBALINFO_SELF)); $hCols = ['side']; if (!$contains->hasSetFields(['slot'])) { $hCols[] = 'slot'; } $this->lvTabs[] = array('file' => 'item', 'data' => $contains->getListviewData(), 'params' => ['name' => '$LANG.tab_cancontain', 'id' => 'can-contain', 'hiddenCols' => '$' . Util::toJSON($hCols)]); } } else { if ($_bagFamily != 0x100) { $contains = new ItemList(array(['bagFamily', $_bagFamily, '&'], ['slots', 0, '>'], CFG_SQL_LIMIT_NONE)); if (!$contains->error) { $this->extendGlobalData($contains->getJSGlobals(GLOBALINFO_SELF)); $this->lvTabs[] = array('file' => 'item', 'data' => $contains->getListviewData(), 'params' => ['name' => '$LANG.tab_canbeplacedin', 'id' => 'can-be-placed-in', 'hiddenCols' => "\$['side']"]); } } } // tab: criteria of $conditions = array(['ac.type', [ACHIEVEMENT_CRITERIA_TYPE_OWN_ITEM, ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM, ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM, ACHIEVEMENT_CRITERIA_TYPE_EQUIP_ITEM]], ['ac.value1', $this->typeId]); $criteriaOf = new AchievementList($conditions); if (!$criteriaOf->error) { $this->extendGlobalData($criteriaOf->getJSGlobals(GLOBALINFO_SELF | GLOBALINFO_REWARDS)); $hCols = []; if (!$criteriaOf->hasSetFields(['reward_loc0'])) { $hCols = ['rewards']; } $this->lvTabs[] = array('file' => 'achievement', 'data' => $criteriaOf->getListviewData(), 'params' => ['name' => '$LANG.tab_criteriaof', 'id' => 'criteria-of', 'visibleCols' => "\$['category']", 'hiddenCols' => '$' . Util::toJSON($hCols)]); } // tab: reagent for $conditions = array('OR', ['reagent1', $this->typeId], ['reagent2', $this->typeId], ['reagent3', $this->typeId], ['reagent4', $this->typeId], ['reagent5', $this->typeId], ['reagent6', $this->typeId], ['reagent7', $this->typeId], ['reagent8', $this->typeId]); $reagent = new SpellList($conditions); if (!$reagent->error) { $this->extendGlobalData($reagent->getJSGlobals(GLOBALINFO_SELF | GLOBALINFO_RELATED)); $this->lvTabs[] = array('file' => 'spell', 'data' => $reagent->getListviewData(), 'params' => ['name' => '$LANG.tab_reagentfor', 'id' => 'reagent-for', 'visibleCols' => "\$['reagents']"]); } // tab: unlocks (object or item) $lockIds = DB::Aowow()->selectCol('SELECT id FROM ?_lock WHERE (type1 = 1 AND properties1 = ?d) OR (type2 = 1 AND properties2 = ?d) OR (type3 = 1 AND properties3 = ?d) OR (type4 = 1 AND properties4 = ?d) OR (type5 = 1 AND properties5 = ?d)', $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId); if ($lockIds) { // objects $lockedObj = new GameObjectList(array(['lockId', $lockIds])); if (!$lockedObj->error) { $this->lvTabs[] = array('file' => 'object', 'data' => $lockedObj->getListviewData(), 'params' => ['name' => '$LANG.tab_unlocks', 'id' => 'unlocks-object']); } // items (generally unused. It's the spell on the item, that unlocks stuff) $lockedItm = new ItemList(array(['lockId', $lockIds])); if (!$lockedItm->error) { $this->extendGlobalData($lockedItm->getJSGlobals(GLOBALINFO_SELF)); $this->lvTabs[] = array('file' => 'item', 'data' => $lockedItm->getListviewData(), 'params' => ['name' => '$LANG.tab_unlocks', 'id' => 'unlocks-item']); } } // tab: see also $conditions = array(['id', $this->typeId, '!'], ['OR', ['name_loc' . User::$localeId, $this->subject->getField('name', true)], ['AND', ['class', $_class], ['subClass', $_subClass], ['slot', $_slot], ['itemLevel', $this->subject->getField('itemLevel') - 15, '>'], ['itemLevel', $this->subject->getField('itemLevel') + 15, '<'], ['quality', $this->subject->getField('quality')], ['requiredClass', $this->subject->getField('requiredClass')]]]); $saItems = new ItemList($conditions); if (!$saItems->error) { $this->extendGlobalData($saItems->getJSGlobals(GLOBALINFO_SELF)); $this->lvTabs[] = array('file' => 'item', 'data' => $saItems->getListviewData(), 'params' => ['name' => '$LANG.tab_seealso', 'id' => 'see-also']); } // tab: starts (quest) if ($qId = $this->subject->getField('startQuest')) { $starts = new QuestList(array(['id', $qId])); if (!$starts->error) { $this->extendGlobalData($starts->getJSGlobals(GLOBALINFO_SELF | GLOBALINFO_REWARDS)); $this->lvTabs[] = array('file' => 'quest', 'data' => $starts->getListviewData(), 'params' => ['name' => '$LANG.tab_starts', 'id' => 'starts-quest']); } } // tab: objective of (quest) $conditions = array('OR', ['reqItemId1', $this->typeId], ['reqItemId2', $this->typeId], ['reqItemId3', $this->typeId], ['reqItemId4', $this->typeId], ['reqItemId5', $this->typeId], ['reqItemId6', $this->typeId]); $objective = new QuestList($conditions); if (!$objective->error) { $this->extendGlobalData($objective->getJSGlobals(GLOBALINFO_SELF | GLOBALINFO_REWARDS)); $this->lvTabs[] = array('file' => 'quest', 'data' => $objective->getListviewData(), 'params' => ['name' => '$LANG.tab_objectiveof', 'id' => 'objective-of-quest']); } // tab: provided for (quest) $conditions = array('OR', ['sourceItemId', $this->typeId], ['reqSourceItemId1', $this->typeId], ['reqSourceItemId2', $this->typeId], ['reqSourceItemId3', $this->typeId], ['reqSourceItemId4', $this->typeId]); $provided = new QuestList($conditions); if (!$provided->error) { $this->extendGlobalData($provided->getJSGlobals(GLOBALINFO_SELF | GLOBALINFO_REWARDS)); $this->lvTabs[] = array('file' => 'quest', 'data' => $provided->getListviewData(), 'params' => ['name' => '$LANG.tab_providedfor', 'id' => 'provided-for-quest']); } // tab: same model as // todo (low): should also work for creatures summoned by item if (($model = $this->subject->getField('model')) && $_slot) { $sameModel = new ItemList(array(['model', $model], ['id', $this->typeId, '!'], ['slot', $_slot])); if (!$sameModel->error) { $this->extendGlobalData($sameModel->getJSGlobals(GLOBALINFO_SELF)); $this->lvTabs[] = array('file' => 'genericmodel', 'data' => $sameModel->getListviewData(ITEMINFO_MODEL), 'params' => ['name' => '$LANG.tab_samemodelas', 'id' => 'same-model-as', 'genericlinktype' => 'item']); } } // tab: sold by if (!empty($this->subject->getExtendedCost()[$this->subject->id])) { $vendors = $this->subject->getExtendedCost()[$this->subject->id]; $soldBy = new CreatureList(array(['id', array_keys($vendors)])); if (!$soldBy->error) { $sbData = $soldBy->getListviewData(); $this->extendGlobalData($soldBy->getJSGlobals(GLOBALINFO_SELF)); $extraCols = ['Listview.extraCols.stock', "Listview.funcBox.createSimpleCol('stack', 'stack', '10%', 'stack')", 'Listview.extraCols.cost']; $holidays = []; foreach ($sbData as $k => &$row) { $currency = []; $tokens = []; foreach ($vendors[$k] as $id => $qty) { if (is_string($id)) { continue; } if ($id > 0) { $tokens[] = [$id, $qty]; } else { if ($id < 0) { $currency[] = [-$id, $qty]; } } } if ($currency) { $this->extendGlobalIds(TYPE_CURRENCY, array_column($currency, 0)); } if ($tokens) { $this->extendGlobalIds(TYPE_ITEM, array_column($tokens, 0)); } $row['stock'] = $vendors[$k]['stock']; $row['cost'] = [empty($vendors[$k][0]) ? 0 : $vendors[$k][0]]; if ($e = $vendors[$k]['event']) { if (count($extraCols) == 3) { $extraCols[] = 'Listview.extraCols.condition'; } $this->extendGlobalIds(TYPE_WORLDEVENT, $e); $row['condition'][0][$this->typeId][] = [[CND_ACTIVE_EVENT, $e]]; } if ($currency || $tokens) { // fill idx:3 if required $row['cost'][] = $currency; } if ($tokens) { $row['cost'][] = $tokens; } if ($x = $this->subject->getField('buyPrice')) { $row['buyprice'] = $x; } if ($x = $this->subject->getField('sellPrice')) { $row['sellprice'] = $x; } if ($x = $this->subject->getField('buyCount')) { $row['stack'] = $x; } } $this->lvTabs[] = array('file' => 'creature', 'data' => $sbData, 'params' => ['name' => '$LANG.tab_soldby', 'id' => 'sold-by-npc', 'extraCols' => '$[' . implode(', ', $extraCols) . ']', 'hiddenCols' => "\$['level', 'type']"]); } } // tab: currency for // some minor trickery: get arenaPoints(43307) and honorPoints(43308) directly if ($this->typeId == 43307) { $n = '?items&filter=cr=145;crs=1;crv=0'; $w = 'reqArenaPoints > 0'; } else { if ($this->typeId == 43308) { $n = '?items&filter=cr=144;crs=1;crv=0'; $w = 'reqHonorPoints > 0'; } else { $n = in_array($this->typeId, [42, 61, 81, 241, 121, 122, 123, 125, 126, 161, 201, 101, 102, 221, 301, 341]) ? '?items&filter=cr=158;crs=' . $this->typeId . ';crv=0' : null; $w = 'reqItemId1 = ' . $this->typeId . ' OR reqItemId2 = ' . $this->typeId . ' OR reqItemId3 = ' . $this->typeId . ' OR reqItemId4 = ' . $this->typeId . ' OR reqItemId5 = ' . $this->typeId; } } $xCosts = DB::Aowow()->selectCol('SELECT id FROM ?_itemextendedcost WHERE ' . $w); $boughtBy = $xCosts ? DB::World()->selectCol('SELECT item FROM npc_vendor WHERE extendedCost IN (?a) UNION SELECT item FROM game_event_npc_vendor WHERE extendedCost IN (?a)', $xCosts, $xCosts) : null; if ($boughtBy) { $boughtBy = new ItemList(array(['id', $boughtBy])); if (!$boughtBy->error) { if ($boughtBy->getMatches() <= CFG_SQL_LIMIT_DEFAULT) { $n = null; } $iCur = new CurrencyList(array(['itemId', $this->typeId])); $filter = $iCur->error ? [TYPE_ITEM => $this->typeId] : [TYPE_CURRENCY => $iCur->id]; $this->lvTabs[] = array('file' => 'item', 'data' => $boughtBy->getListviewData(ITEMINFO_VENDOR, $filter), 'params' => ['name' => '$LANG.tab_currencyfor', 'id' => 'currency-for', 'extraCols' => "\$[Listview.funcBox.createSimpleCol('stack', 'stack', '10%', 'stack'), Listview.extraCols.cost]", 'note' => $n ? sprintf(Util::$filterResultString, $n) : null]); $this->extendGlobalData($boughtBy->getJSGlobals(GLOBALINFO_ANY)); } } // tab: teaches $ids = $indirect = []; for ($i = 1; $i < 6; $i++) { if ($this->subject->getField('spellTrigger' . $i) == 6) { $ids[] = $this->subject->getField('spellId' . $i); } else { if ($this->subject->getField('spellTrigger' . $i) == 0 && $this->subject->getField('spellId' . $i) > 0) { $indirect[] = $this->subject->getField('spellId' . $i); } } } // taught indirectly if ($indirect) { $indirectSpells = new SpellList(array(['id', $indirect])); foreach ($indirectSpells->iterate() as $__) { if ($_ = $indirectSpells->canTeachSpell()) { foreach ($_ as $idx) { $ids[] = $indirectSpells->getField('effect' . $idx . 'TriggerSpell'); } } } $ids = array_merge($ids, Util::getTaughtSpells($indirect)); } if ($ids) { $taughtSpells = new SpellList(array(['id', $ids])); if (!$taughtSpells->error) { $this->extendGlobalData($taughtSpells->getJSGlobals(GLOBALINFO_SELF | GLOBALINFO_RELATED)); $visCols = ['level', 'schools']; if ($taughtSpells->hasSetFields(['reagent1'])) { $visCols[] = 'reagents'; } $this->lvTabs[] = array('file' => 'spell', 'data' => $taughtSpells->getListviewData(), 'params' => ['name' => '$LANG.tab_teaches', 'id' => 'teaches', 'visibleCols' => '$' . Util::toJSON($visCols)]); } } // tab: Shared cooldown $cdCats = []; for ($i = 1; $i < 6; $i++) { if ($this->subject->getField('spellId' . $i) > 0 && $this->subject->getField('spellCategory' . $i) > 0) { $cdCats[] = $this->subject->getField('spellCategory' . $i); } } if ($cdCats) { $conditions = array('OR', ['spellCategory1', $cdCats], ['spellCategory2', $cdCats], ['spellCategory3', $cdCats], ['spellCategory4', $cdCats], ['spellCategory5', $cdCats]); $cdItems = new ItemList($conditions); if (!$cdItems->error) { $this->lvTabs[] = array('file' => 'item', 'data' => $cdItems->getListviewData(), 'params' => ['name' => '$LANG.tab_sharedcooldown', 'id' => 'shared-cooldown']); $this->extendGlobalData($cdItems->getJSGlobals(GLOBALINFO_SELF)); } } // // todo - tab: taught by // use var $createdBy to find source of this spell // id: 'taught-by-X', // name: LANG.tab_taughtby }
protected function generateContent() { $this->addJS('?data=zones&locale=' . User::$localeId . '&t=' . $_SESSION['dataKey']); $_cat = $this->subject->getField('typeCat'); $redButtons = array(BUTTON_LINKS => ['color' => 'ff71d5ff', 'linkId' => Util::$typeStrings[TYPE_SPELL] . ':' . $this->typeId], BUTTON_VIEW3D => false, BUTTON_WOWHEAD => true); /***********/ /* Infobox */ /***********/ $infobox = Lang::getInfoBoxForFlags($this->subject->getField('cuFlags')); // level if (!in_array($_cat, [-5, -6])) { if ($_ = $this->subject->getField('talentLevel')) { $infobox[] = in_array($_cat, [-2, 7, -13]) ? sprintf(Lang::game('reqLevel'), $_) : Lang::game('level') . Lang::main('colon') . $_; } else { if ($_ = $this->subject->getField('spellLevel')) { $infobox[] = in_array($_cat, [-2, 7, -13]) ? sprintf(Lang::game('reqLevel'), $_) : Lang::game('level') . Lang::main('colon') . $_; } } } // races if ($_ = Lang::getRaceString($this->subject->getField('reqRaceMask'), $__, $jsg, $n, false)) { if ($_ != Lang::game('ra', 0)) { $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') . $_; } // spell focus if ($_ = $this->subject->getField('spellFocusObject')) { $bar = DB::Aowow()->selectRow('SELECT * FROM ?_spellfocusobject WHERE id = ?d', $_); $focus = new GameObjectList(array(['spellFocusId', $_], 1)); $infobox[] = Lang::game('requires2') . ' ' . ($focus->error ? Util::localizedString($bar, 'name') : '[url=?object=' . $focus->id . ']' . Util::localizedString($bar, 'name') . '[/url]'); } // primary & secondary trades if (in_array($_cat, [9, 11])) { // skill if ($_ = $this->subject->getField('skillLines')[0]) { $rSkill = new SkillList(array(['id', $_])); if (!$rSkill->error) { $this->extendGlobalData($rSkill->getJSGlobals()); $bar = sprintf(Lang::game('requires'), ' [skill=' . $rSkill->id . ']'); if ($_ = $this->subject->getField('learnedAt')) { $bar .= ' (' . $_ . ')'; } $infobox[] = $bar; } } // specialization if ($_ = $this->subject->getField('reqSpellId')) { $rSpell = new SpellList(array(['id', $_])); if (!$rSpell->error) { $this->extendGlobalData($rSpell->getJSGlobals()); $infobox[] = Lang::game('requires2') . ' [spell=' . $rSpell->id . '][/li]'; } } // difficulty if ($_ = $this->subject->getColorsForCurrent()) { $bar = []; for ($i = 0; $i < 4; $i++) { if ($_[$i]) { $bar[] = '[color=r' . ($i + 1) . ']' . $_[$i] . '[/color]'; } } $infobox[] = Lang::game('difficulty') . Lang::main('colon') . implode(' ', $bar); } } // accquisition.. 10: starter spell; 7: discovery if (isset($this->subject->sources[$this->subject->id][10])) { $infobox[] = Lang::spell('starter'); } else { if (isset($this->subject->sources[$this->subject->id][7])) { $infobox[] = Lang::spell('discovered'); } } // training cost if ($cost = $this->subject->getField('trainingCost')) { $infobox[] = Lang::spell('trainingCost') . Lang::main('colon') . '[money=' . $cost . '][/li]'; } // used in mode foreach ($this->difficulties as $n => $id) { if ($id == $this->typeId) { // "Mode" seems to be multilingual acceptable $infobox[] = 'Mode' . Lang::main('colon') . Lang::game('modes', $n); } } $effects = $this->createEffects($infobox, $redButtons); // spell script if (User::isInGroup(U_GROUP_STAFF)) { if ($_ = DB::World()->selectCell('SELECT ScriptName FROM spell_script_names WHERE ABS(spell_id) = ?d', $this->firstRank)) { $infobox[] = 'Script' . Lang::main('colon') . $_; } } $infobox = $infobox ? '[ul][li]' . implode('[/li][li]', $infobox) . '[/li][/ul]' : ''; // append glyph symbol if available $glyphId = 0; for ($i = 1; $i < 4; $i++) { if ($this->subject->getField('effect' . $i . 'Id') == 74) { $glyphId = $this->subject->getField('effect' . $i . 'MiscValue'); } } if ($_ = DB::Aowow()->selectCell('SELECT si.iconString FROM ?_glyphproperties gp JOIN ?_icons si ON gp.iconId = si.id WHERE gp.spellId = ?d { OR gp.id = ?d }', $this->typeId, $glyphId ?: DBSIMPLE_SKIP)) { if (file_exists('static/images/wow/Interface/Spellbook/' . $_ . '.png')) { $infobox .= '[img src=' . STATIC_URL . '/images/wow/Interface/Spellbook/' . $_ . '.png border=0 float=center margin=15]'; } } /****************/ /* Main Content */ /****************/ $this->reagents = $this->createReagentList(); $this->scaling = $this->createScalingData(); $this->items = $this->createRequiredItems(); $this->tools = $this->createTools(); $this->effects = $effects; $this->infobox = $infobox; $this->powerCost = $this->subject->createPowerCostForCurrent(); $this->castTime = $this->subject->createCastTimeForCurrent(false, false); $this->name = $this->subject->getField('name', true); $this->headIcons = [$this->subject->getField('iconString'), $this->subject->getField('stackAmount')]; $this->level = $this->subject->getField('spellLevel'); $this->rangeName = $this->subject->getField('rangeText', true); $this->range = $this->subject->getField('rangeMaxHostile'); $this->gcd = Util::formatTime($this->subject->getField('startRecoveryTime')); $this->gcdCat = null; // todo (low): nyi; find out how this works [n/a; normal; ..] $this->school = [Util::asHex($this->subject->getField('schoolMask')), Lang::getMagicSchools($this->subject->getField('schoolMask'))]; $this->dispel = $this->subject->getField('dispelType') ? Lang::game('dt', $this->subject->getField('dispelType')) : null; $this->mechanic = $this->subject->getField('mechanic') ? Lang::game('me', $this->subject->getField('mechanic')) : null; $this->unavailable = $this->subject->getField('cuFlags') & CUSTOM_UNAVAILABLE; $this->redButtons = $redButtons; // minRange exists.. prepend if ($_ = $this->subject->getField('rangeMinHostile')) { $this->range = $_ . ' - ' . $this->range; } if ($this->subject->getField('attributes2') & 0x80000) { $this->stances = Lang::getStances($this->subject->getField('stanceMask')); } if (($_ = $this->subject->getField('recoveryTime')) && $_ > 0) { $this->cooldown = Util::formatTime($_); } if (($_ = $this->subject->getField('duration')) && $_ > 0) { $this->duration = Util::formatTime($_); } // factionchange-equivalent if ($pendant = DB::World()->selectCell('SELECT IF(horde_id = ?d, alliance_id, -horde_id) FROM player_factionchange_spells WHERE alliance_id = ?d OR horde_id = ?d', $this->typeId, $this->typeId, $this->typeId)) { $altSpell = new SpellList(array(['id', abs($pendant)])); if (!$altSpell->error) { $this->transfer = sprintf(Lang::spell('_transfer'), $altSpell->id, 1, $altSpell->getField('iconString'), $altSpell->getField('name', true), $pendant > 0 ? 'alliance' : 'horde', $pendant > 0 ? Lang::game('si', 1) : Lang::game('si', 2)); } } /**************/ /* Extra Tabs */ /**************/ $j = [null, 'A', 'B', 'C']; // tab: abilities [of shapeshift form] for ($i = 1; $i < 4; $i++) { if ($this->subject->getField('effect' . $i . 'AuraId') != 36) { continue; } $formSpells = DB::Aowow()->selectRow('SELECT spellId1, spellId2, spellId3, spellId4, spellId5, spellId6, spellId7, spellId8 FROM ?_shapeshiftforms WHERE id = ?d', $this->subject->getField('effect' . $i . 'MiscValue')); if (!$formSpells) { continue; } $abilities = new SpellList(array(['id', $formSpells])); if (!$abilities->error) { if (!$abilities->hasSetFields(['skillLines'])) { $abH = "\$['skill']"; } $this->lvTabs[] = array('file' => 'spell', 'data' => $abilities->getListviewData(), 'params' => array('id' => 'controlledabilities', 'name' => '$LANG.tab_controlledabilities', 'visibleCols' => "\$['level']", 'hiddenCols' => isset($abH) ? $abH : null)); $this->extendGlobalData($abilities->getJSGlobals(GLOBALINFO_SELF)); } } // tab: modifies $this $sub = ['OR']; $conditions = [['s.typeCat', [0, -9, -8], '!'], ['s.spellFamilyId', $this->subject->getField('spellFamilyId')], &$sub]; for ($i = 1; $i < 4; $i++) { // Flat Mods (107), Pct Mods (108), No Reagent Use (256) .. include dummy..? (4) if (!in_array($this->subject->getField('effect' . $i . 'AuraId'), [107, 108, 256, 286])) { continue; } $m1 = $this->subject->getField('effect1SpellClassMask' . $j[$i]); $m2 = $this->subject->getField('effect2SpellClassMask' . $j[$i]); $m3 = $this->subject->getField('effect3SpellClassMask' . $j[$i]); if (!$m1 && !$m2 && !$m3) { continue; } $sub[] = ['s.spellFamilyFlags1', $m1, '&']; $sub[] = ['s.spellFamilyFlags2', $m2, '&']; $sub[] = ['s.spellFamilyFlags3', $m3, '&']; } if (count($sub) > 1) { $modSpells = new SpellList($conditions); if (!$modSpells->error) { if (!$modSpells->hasSetFields(['skillLines'])) { $msH = "\$['skill']"; } $this->lvTabs[] = array('file' => 'spell', 'data' => $modSpells->getListviewData(), 'params' => array('id' => 'modifies', 'name' => '$LANG.tab_modifies', 'visibleCols' => "\$['level']", 'hiddenCols' => isset($msH) ? $msH : null)); $this->extendGlobalData($modSpells->getJSGlobals(GLOBALINFO_SELF | GLOBALINFO_RELATED)); } } // tab: modified by $this $sub = ['OR']; $conditions = [['s.spellFamilyId', $this->subject->getField('spellFamilyId')], &$sub]; for ($i = 1; $i < 4; $i++) { $m1 = $this->subject->getField('spellFamilyFlags1'); $m2 = $this->subject->getField('spellFamilyFlags2'); $m3 = $this->subject->getField('spellFamilyFlags3'); if (!$m1 && !$m2 && !$m3) { continue; } $sub[] = array('AND', ['s.effect' . $i . 'AuraId', [107, 108, 256, 286]], ['OR', ['s.effect1SpellClassMask' . $j[$i], $m1, '&'], ['s.effect2SpellClassMask' . $j[$i], $m2, '&'], ['s.effect3SpellClassMask' . $j[$i], $m3, '&']]); } if (count($sub) > 1) { $modsSpell = new SpellList($conditions); if (!$modsSpell->error) { if (!$modsSpell->hasSetFields(['skillLines'])) { $mbH = "\$['skill']"; } $this->lvTabs[] = array('file' => 'spell', 'data' => $modsSpell->getListviewData(), 'params' => array('id' => 'modified-by', 'name' => '$LANG.tab_modifiedby', 'visibleCols' => "\$['level']", 'hiddenCols' => isset($mbH) ? $mbH : null)); $this->extendGlobalData($modsSpell->getJSGlobals(GLOBALINFO_SELF | GLOBALINFO_RELATED)); } } // tab: see also $conditions = array(['s.schoolMask', $this->subject->getField('schoolMask')], ['s.effect1Id', $this->subject->getField('effect1Id')], ['s.effect2Id', $this->subject->getField('effect2Id')], ['s.effect3Id', $this->subject->getField('effect3Id')], ['s.id', $this->subject->id, '!'], ['s.name_loc' . User::$localeId, $this->subject->getField('name', true)]); $saSpells = new SpellList($conditions); if (!$saSpells->error) { $data = $saSpells->getListviewData(); if ($this->difficulties) { $saE = '$[Listview.extraCols.mode]'; foreach ($data as $id => &$d) { $d['modes'] = ['mode' => 0]; if ($this->difficulties[0] == $id) { if (!$this->difficulties[2] && !$this->difficulties[3]) { $d['modes']['mode'] |= 0x2; } else { $d['modes']['mode'] |= 0x8; } } if ($this->difficulties[1] == $id) { if (!$this->difficulties[2] && !$this->difficulties[3]) { $d['modes']['mode'] |= 0x1; } else { $d['modes']['mode'] |= 0x10; } } if ($this->difficulties[2] == $id) { // b0100000 $d['modes']['mode'] |= 0x20; } if ($this->difficulties[3] == $id) { // b1000000 $d['modes']['mode'] |= 0x40; } } } if (!$saSpells->hasSetFields(['skillLines'])) { $saH = "\$['skill']"; } $this->lvTabs[] = array('file' => 'spell', 'data' => $data, 'params' => array('id' => 'see-also', 'name' => '$LANG.tab_seealso', 'visibleCols' => "\$['level']", 'extraCols' => isset($saE) ? $saE : null, 'hiddenCols' => isset($saH) ? $saH : null)); $this->extendGlobalData($saSpells->getJSGlobals(GLOBALINFO_SELF | GLOBALINFO_RELATED)); } // tab: used by - itemset $conditions = array('OR', ['spell1', $this->subject->id], ['spell2', $this->subject->id], ['spell3', $this->subject->id], ['spell4', $this->subject->id], ['spell5', $this->subject->id], ['spell6', $this->subject->id], ['spell7', $this->subject->id], ['spell8', $this->subject->id]); $ubSets = new ItemsetList($conditions); if (!$ubSets->error) { $this->lvTabs[] = array('file' => 'itemset', 'data' => $ubSets->getListviewData(), 'params' => array('id' => 'used-by-itemset', 'name' => '$LANG.tab_usedby')); $this->extendGlobalData($ubSets->getJSGlobals(GLOBALINFO_SELF | GLOBALINFO_RELATED)); } // tab: used by - item $conditions = array('OR', ['AND', ['spellTrigger1', 6, '!'], ['spellId1', $this->subject->id]], ['AND', ['spellTrigger2', 6, '!'], ['spellId2', $this->subject->id]], ['AND', ['spellTrigger3', 6, '!'], ['spellId3', $this->subject->id]], ['AND', ['spellTrigger4', 6, '!'], ['spellId4', $this->subject->id]], ['AND', ['spellTrigger5', 6, '!'], ['spellId5', $this->subject->id]]); $ubItems = new ItemList($conditions); if (!$ubItems->error) { $this->lvTabs[] = array('file' => 'item', 'data' => $ubItems->getListviewData(), 'params' => array('id' => 'used-by-item', 'name' => '$LANG.tab_usedby')); $this->extendGlobalData($ubItems->getJSGlobals(GLOBALINFO_SELF)); } // tab: used by - object $conditions = array('OR', ['onUseSpell', $this->subject->id], ['onSuccessSpell', $this->subject->id], ['auraSpell', $this->subject->id], ['triggeredSpell', $this->subject->id]); $ubObjects = new GameObjectList($conditions); if (!$ubObjects->error) { $this->lvTabs[] = array('file' => 'object', 'data' => $ubObjects->getListviewData(), 'params' => array('id' => 'used-by-object', 'name' => '$LANG.tab_usedby')); $this->extendGlobalData($ubObjects->getJSGlobals()); } // tab: criteria of $conditions = array(['ac.type', [ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2, ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL, ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2, ACHIEVEMENT_CRITERIA_TYPE_LEARN_SPELL]], ['ac.value1', $this->typeId]); $coAchievemnts = new AchievementList($conditions); if (!$coAchievemnts->error) { $this->lvTabs[] = array('file' => 'achievement', 'data' => $coAchievemnts->getListviewData(), 'params' => array('id' => 'criteria-of', 'name' => '$LANG.tab_criteriaof')); $this->extendGlobalData($coAchievemnts->getJSGlobals(GLOBALINFO_SELF | GLOBALINFO_RELATED)); } // tab: contains // spell_loot_template & skill_extra_item_template $extraItem = DB::World()->selectRow('SELECT * FROM skill_extra_item_template WHERE spellid = ?d', $this->subject->id); $spellLoot = new Loot(); if ($spellLoot->getByContainer(LOOT_SPELL, $this->subject->id) || $extraItem) { $this->extendGlobalData($spellLoot->jsGlobals); $lv = $spellLoot->getResult(); $extraCols = $spellLoot->extraCols; $extraCols[] = 'Listview.extraCols.percent'; if ($extraItem && $this->subject->canCreateItem()) { $foo = $this->subject->relItems->getListviewData(); for ($i = 1; $i < 4; $i++) { if (($bar = $this->subject->getField('effect' . $i . 'CreateItemId')) && isset($foo[$bar])) { $lv[$bar] = $foo[$bar]; $lv[$bar]['percent'] = $extraItem['additionalCreateChance']; $lv[$bar]['condition'][0][$this->typeId][] = [[CND_SPELL, $extraItem['requiredSpecialization']]]; $this->extendGlobalIds(TYPE_SPELL, $extraItem['requiredSpecialization']); $extraCols[] = 'Listview.extraCols.condition'; if ($max = $extraItem['additionalMaxNum']) { $lv[$bar]['mincount'] = 1; $lv[$bar]['maxcount'] = $max; } break; // skill_extra_item_template can only contain 1 item } } } $this->lvTabs[] = array('file' => 'item', 'data' => $lv, 'params' => array('name' => '$LANG.tab_contains', 'id' => 'contains', 'hiddenCols' => "\$['side', 'slot', 'source', 'reqlevel']", 'extraCols' => '$[' . implode(', ', $extraCols) . ']')); } // tab: exclusive with if ($this->firstRank) { $linkedSpells = DB::World()->selectCol('SELECT IF(sg2.spell_id < 0, sg2.id, sg2.spell_id) AS ARRAY_KEY, IF(sg2.spell_id < 0, sg2.spell_id, sr.stack_rule) FROM spell_group sg1 JOIN spell_group sg2 ON (sg1.id = sg2.id OR sg1.id = -sg2.spell_id) AND sg1.spell_id != sg2.spell_id LEFT JOIN spell_group_stack_rules sr ON sg1.id = sr.group_id WHERE sg1.spell_id = ?d', $this->firstRank); if ($linkedSpells) { $extraSpells = []; foreach ($linkedSpells as $k => $v) { if ($v > 0) { continue; } $extraSpells += DB::World()->selectCol('SELECT sg2.spell_id AS ARRAY_KEY, sr.stack_rule FROM spell_group sg1 JOIN spell_group sg2 ON sg2.id = -sg1.spell_id AND sg2.spell_id != ?d LEFT JOIN spell_group_stack_rules sr ON sg1.id = sr.group_id WHERE sg1.id = ?d', $this->firstRank, $k); unset($linkedSpells[$k]); } $groups = $linkedSpells + $extraSpells; $stacks = new SpellList(array(['s.id', array_keys($groups)])); if (!$stacks->error) { $data = $stacks->getListviewData(); foreach ($data as $k => $d) { $data[$k]['stackRule'] = $groups[$k]; } if (!$stacks->hasSetFields(['skillLines'])) { $sH = "\$['skill']"; } $this->lvTabs[] = array('file' => 'spell', 'data' => $data, 'params' => array('id' => 'spell-group-stack', 'name' => 'Stack Group', 'visibleCols' => "\$['stackRules']", 'hiddenCols' => isset($sH) ? $sH : null)); $this->extendGlobalData($stacks->getJSGlobals(GLOBALINFO_SELF | GLOBALINFO_RELATED)); } } } // tab: linked with $rows = DB::World()->select(' SELECT spell_trigger AS `trigger`, spell_effect AS effect, type, IF(ABS(spell_effect) = ?d, ABS(spell_trigger), ABS(spell_effect)) AS related FROM spell_linked_spell WHERE ABS(spell_effect) = ?d OR ABS(spell_trigger) = ?d', $this->typeId, $this->typeId, $this->typeId); $related = []; foreach ($rows as $row) { $related[] = $row['related']; } if ($related) { $linked = new SpellList(array(['s.id', $related])); } if (isset($linked) && !$linked->error) { $lv = $linked->getListviewData(); $data = []; foreach ($rows as $r) { foreach ($lv as $dk => $d) { if ($r['related'] != $dk) { continue; } $lv[$dk]['linked'] = [$r['trigger'], $r['effect'], $r['type']]; $data[] = $lv[$dk]; break; } } $this->lvTabs[] = array('file' => 'spell', 'data' => $data, 'params' => array('id' => 'spell-link', 'name' => 'Linked with', 'hiddenCols' => "\$['skill', 'name']", 'visibleCols' => "\$['linkedTrigger', 'linkedEffect']")); $this->extendGlobalData($linked->getJSGlobals(GLOBALINFO_SELF | GLOBALINFO_RELATED)); } // tab: triggered by $conditions = array('OR', ['AND', ['OR', ['effect1Id', SpellList::$effects['trigger']], ['effect1AuraId', SpellList::$auras['trigger']]], ['effect1TriggerSpell', $this->subject->id]], ['AND', ['OR', ['effect2Id', SpellList::$effects['trigger']], ['effect2AuraId', SpellList::$auras['trigger']]], ['effect2TriggerSpell', $this->subject->id]], ['AND', ['OR', ['effect3Id', SpellList::$effects['trigger']], ['effect3AuraId', SpellList::$auras['trigger']]], ['effect3TriggerSpell', $this->subject->id]]); $trigger = new SpellList($conditions); if (!$trigger->error) { $this->lvTabs[] = array('file' => 'spell', 'data' => $trigger->getListviewData(), 'params' => array('id' => 'triggered-by', 'name' => '$LANG.tab_triggeredby')); $this->extendGlobalData($trigger->getJSGlobals(GLOBALINFO_SELF)); } // tab: used by - creature // SMART_SCRIPT_TYPE_CREATURE = 0; SMART_ACTION_CAST = 11; SMART_ACTION_ADD_AURA = 75; SMART_ACTION_INVOKER_CAST = 85; SMART_ACTION_CROSS_CAST = 86 $conditions = array('OR', ['spell1', $this->typeId], ['spell2', $this->typeId], ['spell3', $this->typeId], ['spell4', $this->typeId], ['spell5', $this->typeId], ['spell6', $this->typeId], ['spell7', $this->typeId], ['spell8', $this->typeId]); if ($_ = DB::World()->selectCol('SELECT entryOrGUID FROM smart_scripts WHERE entryorguid > 0 AND source_type = 0 AND action_type IN (11, 75, 85, 86) AND action_param1 = ?d', $this->typeId)) { $conditions[] = ['id', $_]; } $ubCreature = new CreatureList($conditions); if (!$ubCreature->error) { $this->lvTabs[] = array('file' => 'creature', 'data' => $ubCreature->getListviewData(), 'params' => array('id' => 'used-by-npc', 'name' => '$LANG.tab_usedby')); $this->extendGlobalData($ubCreature->getJSGlobals(GLOBALINFO_SELF)); } // tab: zone if ($areas = DB::World()->select('SELECT * FROM spell_area WHERE spell = ?d', $this->typeId)) { $zones = new ZoneList(array(['id', array_column($areas, 'area')])); if (!$zones->error) { $lvZones = $zones->getListviewData(); $this->extendGlobalData($zones->getJSGlobals()); $lv = []; $parents = []; $extra = false; foreach ($areas as $a) { if (empty($lvZones[$a['area']])) { 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]]; } $row = $lvZones[$a['area']]; if ($condition) { $extra = true; $row = array_merge($row, ['condition' => $condition]); } // merge subzones, into one row, if: conditions match && parentZone is shared if ($p = $zones->getEntry($a['area'])['parentArea']) { $parents[] = $p; $row['parentArea'] = $p; $row['subzones'] = [$a['area']]; } else { $row['parentArea'] = 0; } $set = false; foreach ($lv as &$v) { if ($v['parentArea'] != $row['parentArea'] && $v['id'] != $row['parentArea']) { continue; } if (empty($v['condition']) xor empty($row['condition'])) { continue; } if (!empty($row['condition']) && !empty($v['condition']) && $v['condition'] != $row['condition']) { continue; } if (!$row['parentArea'] && $v['id'] != $row['parentArea']) { continue; } $set = true; $v['subzones'][] = $row['id']; break; } // add self as potential subzone; IF we are a parentZone without added children, we get filtered in JScript if (!$set) { $row['subzones'] = [$row['id']]; $lv[] = $row; } } // overwrite lvData with parent-lvData (condition and subzones are kept) if ($parents) { $parents = (new ZoneList(array(['id', $parents])))->getListviewData(); foreach ($lv as &$_) { if (isset($parents[$_['parentArea']])) { $_ = array_merge($_, $parents[$_['parentArea']]); } } } $this->lvTabs[] = array('file' => 'zone', 'data' => $lv, 'params' => array('extraCols' => $extra ? '$[Listview.extraCols.condition]' : null, 'hiddenCols' => $extra ? "\$['instancetype']" : null)); } } // tab: teaches if ($ids = Util::getTaughtSpells($this->subject)) { $teaches = new SpellList(array(['id', $ids])); if (!$teaches->error) { $this->extendGlobalData($teaches->getJSGlobals(GLOBALINFO_SELF | GLOBALINFO_RELATED)); $vis = ['level', 'schools']; $hid = []; if (!$teaches->hasSetFields(['skillLines'])) { $hid[] = 'skill'; } foreach ($teaches->iterate() as $__) { if (!$teaches->canCreateItem()) { continue; } $vis[] = 'reagents'; break; } $this->lvTabs[] = array('file' => 'spell', 'data' => $teaches->getListviewData(), 'params' => array('id' => 'teaches-spell', 'name' => '$LANG.tab_teaches', 'visibleCols' => '$' . Util::toJSON($vis), 'hiddenCols' => $hid ? '$' . Util::toJSON($hid) : null)); } } // tab: taught by npc (source:6 => trainer) if (!empty($this->subject->sources[$this->typeId][6])) { $src = $this->subject->sources[$this->typeId][6]; $list = []; if (count($src) == 1 && $src[0] == 1) { $tt = null; // Professions if (in_array($_cat, [9, 11]) && isset(Util::$trainerTemplates[TYPE_SKILL][$this->subject->getField('skillLines')[0]])) { $tt = Util::$trainerTemplates[TYPE_SKILL][$this->subject->getField('skillLines')[0]]; } else { if ($_cat == 7 && $this->subject->getField('reqClassMask')) { $clId = log($this->subject->getField('reqClassMask'), 2) + 1; if (intVal($clId) == $clId) { // only one class was set, so float == int if (isset(Util::$trainerTemplates[TYPE_CLASS][$clId])) { $tt = Util::$trainerTemplates[TYPE_CLASS][$clId]; } } } } if ($tt) { $list = DB::World()->selectCol('SELECT DISTINCT ID FROM npc_trainer WHERE SpellID IN (?a) AND ID < 200000', $tt); } else { $mask = 0; foreach (Util::$skillLineMask[-3] as $idx => $pair) { if ($pair[1] == $this->typeId) { $mask |= 1 << $idx; } } $list = DB::World()->selectCol(' SELECT IF(t1.ID > 200000, t2.ID, t1.ID) FROM npc_trainer t1 LEFT JOIN npc_trainer t2 ON t2.SpellID = -t1.ID WHERE t1.SpellID = ?d', $this->typeId); } } else { if ($src) { $list = array_values($src); } } if ($list) { $tbTrainer = new CreatureList(array(CFG_SQL_LIMIT_NONE, ['ct.id', $list], ['s.guid', NULL, '!'], ['ct.npcflag', 0x10, '&'])); if (!$tbTrainer->error) { $this->extendGlobalData($tbTrainer->getJSGlobals()); $this->lvTabs[] = array('file' => 'creature', 'data' => $tbTrainer->getListviewData(), 'params' => array('id' => 'taught-by-npc', 'name' => '$LANG.tab_taughtby')); } } } // tab: taught by spell $conditions = array('OR', ['AND', ['effect1Id', SpellList::$effects['teach']], ['effect1TriggerSpell', $this->subject->id]], ['AND', ['effect2Id', SpellList::$effects['teach']], ['effect2TriggerSpell', $this->subject->id]], ['AND', ['effect3Id', SpellList::$effects['teach']], ['effect3TriggerSpell', $this->subject->id]]); $tbSpell = new SpellList($conditions); $tbsData = []; if (!$tbSpell->error) { $tbsData = $tbSpell->getListviewData(); $this->lvTabs[] = array('file' => 'spell', 'data' => $tbsData, 'params' => array('id' => 'taught-by-spell', 'name' => '$LANG.tab_taughtby')); $this->extendGlobalData($tbSpell->getJSGlobals(GLOBALINFO_SELF)); } // tab: taught by quest $conditions = ['OR', ['sourceSpellId', $this->typeId], ['rewardSpell', $this->typeId]]; if ($tbsData) { $conditions[] = ['rewardSpell', array_keys($tbsData)]; if (User::isInGroup(U_GROUP_EMPLOYEE)) { $conditions[] = ['rewardSpellCast', array_keys($tbsData)]; } } if (User::isInGroup(U_GROUP_EMPLOYEE)) { $conditions[] = ['rewardSpellCast', $this->typeId]; } $tbQuest = new QuestList($conditions); if (!$tbQuest->error) { $this->lvTabs[] = array('file' => 'quest', 'data' => $tbQuest->getListviewData(), 'params' => array('id' => 'reward-from-quest', 'name' => '$LANG.tab_rewardfrom')); $this->extendGlobalData($tbQuest->getJSGlobals()); } // tab: taught by item (i'd like to precheck $this->subject->sources, but there is no source:item only complicated crap like "drop" and "vendor") $conditions = array('OR', ['AND', ['spellTrigger1', 6], ['spellId1', $this->subject->id]], ['AND', ['spellTrigger2', 6], ['spellId2', $this->subject->id]], ['AND', ['spellTrigger3', 6], ['spellId3', $this->subject->id]], ['AND', ['spellTrigger4', 6], ['spellId4', $this->subject->id]], ['AND', ['spellTrigger5', 6], ['spellId5', $this->subject->id]]); $tbItem = new ItemList($conditions); if (!$tbItem->error) { $this->lvTabs[] = array('file' => 'item', 'data' => $tbItem->getListviewData(), 'params' => array('id' => 'taught-by-item', 'name' => '$LANG.tab_taughtby')); $this->extendGlobalData($tbItem->getJSGlobals(GLOBALINFO_SELF)); } // tab: enchantments $conditions = array('OR', ['AND', ['type1', [1, 3, 7]], ['object1', $this->typeId]], ['AND', ['type2', [1, 3, 7]], ['object2', $this->typeId]], ['AND', ['type3', [1, 3, 7]], ['object3', $this->typeId]]); $enchList = new EnchantmentList($conditions); if (!$enchList->error) { $this->lvTabs[] = array('file' => 'enchantment', 'data' => $enchList->getListviewData(), 'params' => []); $this->extendGlobalData($enchList->getJSGlobals()); } // find associated NPC, Item and merge results // taughtbypets (unused..?) // taughtbyquest (usually the spell casted as quest reward teaches something; exclude those seplls from taughtBySpell) // taughtbytrainers // taughtbyitem // tab: conditions $sc = Util::getServerConditions([CND_SRC_SPELL_LOOT_TEMPLATE, CND_SRC_SPELL_IMPLICIT_TARGET, CND_SRC_SPELL, CND_SRC_SPELL_CLICK_EVENT, CND_SRC_VEHICLE_SPELL, CND_SRC_SPELL_PROC], null, $this->typeId); if (!empty($sc[0])) { $this->extendGlobalData($sc[1]); $tab = "<script type=\"text/javascript\">\n" . "var markup = ConditionList.createTab(" . Util::toJSON($sc[0]) . ");\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')); } }
protected function generateContent() { $this->addJS('?data=zones&locale=' . User::$localeId . '&t=' . $_SESSION['dataKey']); /***********/ /* Infobox */ /***********/ $infobox = Lang::getInfoBoxForFlags($this->subject->getField('cuFlags')); // Event (ignore events, where the object only gets removed) if ($_ = DB::World()->selectCol('SELECT DISTINCT IF(ge.holiday, ge.holiday, -ge.eventEntry) FROM game_event ge, game_event_gameobject geg, gameobject g WHERE ge.eventEntry = geg.eventEntry AND g.guid = geg.guid AND g.id = ?d', $this->typeId)) { $this->extendGlobalIds(TYPE_WORLDEVENT, $_); $ev = []; foreach ($_ as $i => $e) { $ev[] = ($i % 2 ? '[br]' : ' ') . '[event=' . $e . ']'; } $infobox[] = Util::ucFirst(Lang::game('eventShort')) . Lang::main('colon') . implode(',', $ev); } // Reaction $_ = function ($r) { if ($r == 1) { return 2; } if ($r == -1) { return 10; } return; }; $infobox[] = Lang::npc('react') . Lang::main('colon') . '[color=q' . $_($this->subject->getField('A')) . ']A[/color] [color=q' . $_($this->subject->getField('H')) . ']H[/color]'; // reqSkill switch ($this->subject->getField('typeCat')) { case -3: // Herbalism $infobox[] = sprintf(Lang::game('requires'), Lang::spell('lockType', 2) . ' (' . $this->subject->getField('reqSkill') . ')'); break; case -4: // Mining $infobox[] = sprintf(Lang::game('requires'), Lang::spell('lockType', 3) . ' (' . $this->subject->getField('reqSkill') . ')'); break; case -5: // Lockpicking $infobox[] = sprintf(Lang::game('requires'), Lang::spell('lockType', 1) . ' (' . $this->subject->getField('reqSkill') . ')'); break; default: $locks = Lang::getLocks($this->subject->getField('lockId')); $l = ''; foreach ($locks as $idx => $_) { if ($idx < 0) { continue; } $this->extendGlobalIds(TYPE_ITEM, $idx); $l = Lang::gameObject('key') . Lang::main('colon') . '[item=' . $idx . ']'; } // if no propper item is found use a skill if ($locks) { $infobox[] = $l ? $l : array_pop($locks); } } // linked trap if ($_ = $this->subject->getField('linkedTrap')) { $this->extendGlobalIds(TYPE_OBJECT, $_); $infobox[] = Lang::gameObject('trap') . Lang::main('colon') . '[object=' . $_ . ']'; } // trap for $trigger = new GameObjectList(array(['linkedTrap', $this->typeId])); if (!$trigger->error) { $this->extendGlobalData($trigger->getJSGlobals()); $infobox[] = Lang::gameObject('triggeredBy') . Lang::main('colon') . '[object=' . $trigger->id . ']'; } // SpellFocus if ($_ = $this->subject->getField('spellFocusId')) { if ($sfo = DB::Aowow()->selectRow('SELECT * FROM ?_spellfocusobject WHERE id = ?d', $_)) { $infobox[] = '[tooltip name=focus]' . Lang::gameObject('focusDesc') . '[/tooltip][span class=tip tooltip=focus]' . Lang::gameObject('focus') . Lang::main('colon') . Util::localizedString($sfo, 'name') . '[/span]'; } } // lootinfo: [min, max, restock] if (($_ = $this->subject->getField('lootStack')) && $_[0]) { $buff = Lang::item('charges') . Lang::main('colon') . $_[0]; if ($_[0] < $_[1]) { $buff .= Lang::game('valueDelim') . $_[1]; } // since Veins don't have charges anymore, the timer is questionable $infobox[] = $_[2] > 1 ? '[tooltip name=restock]' . sprintf(Lang::gameObject('restock'), Util::formatTime($_[2] * 1000)) . '[/tooltip][span class=tip tooltip=restock]' . $buff . '[/span]' : $buff; } // meeting stone [minLevel, maxLevel, zone] if ($this->subject->getField('type') == OBJECT_MEETINGSTONE) { if ($_ = $this->subject->getField('mStone')) { $this->extendGlobalIds(TYPE_ZONE, $_[2]); $m = Lang::game('meetingStone') . Lang::main('colon') . '[zone=' . $_[2] . ']'; $l = $_[0]; if ($_[0] > 1 && $_[1] > $_[0]) { $l .= Lang::game('valueDelim') . min($_[1], MAX_LEVEL); } $infobox[] = $l ? '[tooltip name=meetingstone]' . sprintf(Lang::game('reqLevel'), $l) . '[/tooltip][span class=tip tooltip=meetingstone]' . $m . '[/span]' : $m; } } // capture area [minPlayer, maxPlayer, minTime, maxTime, radius] if ($this->subject->getField('type') == OBJECT_CAPTURE_POINT) { if ($_ = $this->subject->getField('capture')) { $buff = Lang::gameObject('capturePoint'); if ($_[2] > 1 || $_[0]) { $buff .= Lang::main('colon') . '[ul]'; } if ($_[2] > 1) { $buff .= '[li]' . Lang::game('duration') . Lang::main('colon') . ($_[3] > $_[2] ? Util::FormatTime($_[3] * 1000, true) . ' - ' : null) . Util::FormatTime($_[2] * 1000, true) . '[/li]'; } if ($_[1]) { $buff .= '[li]' . Lang::main('players') . Lang::main('colon') . $_[0] . ($_[1] > $_[0] ? ' - ' . $_[1] : null) . '[/li]'; } if ($_[4]) { $buff .= '[li]' . sprintf(Lang::spell('range'), $_[4]) . '[/li]'; } if ($_[2] > 1 || $_[0]) { $buff .= '[/ul]'; } } $infobox[] = $buff; } // AI if (User::isInGroup(U_GROUP_EMPLOYEE)) { if ($_ = $this->subject->getField('ScriptName')) { $infobox[] = 'Script' . Lang::main('colon') . $_; } else { if ($_ = $this->subject->getField('AIName')) { $infobox[] = 'AI' . Lang::main('colon') . $_; } } } /****************/ /* Main Content */ /****************/ // pageText $pageText = []; if ($next = $this->subject->getField('pageTextId')) { while ($next) { $row = DB::World()->selectRow('SELECT *, text as Text_loc0 FROM page_text pt LEFT JOIN locales_page_text lpt ON pt.entry = lpt.entry WHERE pt.entry = ?d', $next); $next = $row['next_page']; $pageText[] = Util::parseHtmlText(Util::localizedString($row, 'Text')); } } // add conditional js & css if ($pageText) { $this->addCSS(['path' => 'Book.css']); $this->addJS('Book.js'); } // get spawns and path $map = null; 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); } } // consider pooled spawns $this->infobox = $infobox ? '[ul][li]' . implode('[/li][li]', $infobox) . '[/li][/ul]' : null; $this->pageText = $pageText; $this->map = $map; $this->redButtons = array(BUTTON_WOWHEAD => true, BUTTON_LINKS => true, BUTTON_VIEW3D => ['displayId' => $this->subject->getField('displayId'), 'type' => TYPE_OBJECT, 'typeId' => $this->typeId]); /**************/ /* Extra Tabs */ /**************/ // tab: summoned by $conditions = array('OR', ['AND', ['effect1Id', [50, 76, 104, 105, 106, 107]], ['effect1MiscValue', $this->typeId]], ['AND', ['effect2Id', [50, 76, 104, 105, 106, 107]], ['effect2MiscValue', $this->typeId]], ['AND', ['effect3Id', [50, 76, 104, 105, 106, 107]], ['effect3MiscValue', $this->typeId]]); $summons = new SpellList($conditions); if (!$summons->error) { $this->extendGlobalData($summons->getJSGlobals(GLOBALINFO_SELF | GLOBALINFO_RELATED)); $this->lvTabs[] = array('file' => 'spell', 'data' => $summons->getListviewData(), 'params' => array('id' => 'summoned-by', 'name' => '$LANG.tab_summonedby')); } // tab: related spells if ($_ = $this->subject->getField('spells')) { $relSpells = new SpellList(array(['id', $_])); if (!$relSpells->error) { $this->extendGlobalData($relSpells->getJSGlobals(GLOBALINFO_SELF | GLOBALINFO_RELATED)); $data = $relSpells->getListviewData(); foreach ($data as $relId => $d) { $data[$relId]['trigger'] = array_search($relId, $_); } $this->lvTabs[] = array('file' => 'spell', 'data' => $data, 'params' => array('id' => 'spells', 'name' => '$LANG.tab_spells', 'hiddenCols' => "\$['skill']", 'extraCols' => "\$[Listview.funcBox.createSimpleCol('trigger', 'Condition', '10%', 'trigger')]")); } } // tab: criteria of $acvs = new AchievementList(array(['ac.type', [ACHIEVEMENT_CRITERIA_TYPE_USE_GAMEOBJECT, ACHIEVEMENT_CRITERIA_TYPE_FISH_IN_GAMEOBJECT]], ['ac.value1', $this->typeId])); if (!$acvs->error) { $this->extendGlobalData($acvs->getJSGlobals(GLOBALINFO_SELF | GLOBALINFO_RELATED)); $this->lvTabs[] = array('file' => 'achievement', 'data' => $acvs->getListviewData(), 'params' => array('id' => 'criteria-of', 'name' => '$LANG.tab_criteriaof')); } // tab: starts quest // tab: ends quest $startEnd = new QuestList(array(['qse.type', TYPE_OBJECT], ['qse.typeId', $this->typeId])); if (!$startEnd->error) { $this->extendGlobalData($startEnd->getJSGlobals()); $lvData = $startEnd->getListviewData(); $_ = [[], []]; foreach ($startEnd->iterate() as $id => $__) { $m = $startEnd->getField('method'); if ($m & 0x1) { $_[0][] = $lvData[$id]; } if ($m & 0x2) { $_[1][] = $lvData[$id]; } } if ($_[0]) { $this->lvTabs[] = array('file' => 'quest', 'data' => $_[0], 'params' => array('name' => '$LANG.tab_starts', 'id' => 'starts')); } if ($_[1]) { $this->lvTabs[] = array('file' => 'quest', 'data' => $_[1], 'params' => array('name' => '$LANG.tab_ends', 'id' => 'ends')); } } // tab: related quests if ($_ = $this->subject->getField('reqQuest')) { $relQuest = new QuestList(array(['id', $_])); if (!$relQuest->error) { $this->extendGlobalData($relQuest->getJSGlobals()); $this->lvTabs[] = array('file' => 'quest', 'data' => $relQuest->getListviewData(), 'params' => array('name' => '$LANG.tab_quests', 'id' => 'quests')); } } // tab: contains $reqQuest = []; if ($_ = $this->subject->getField('lootId')) { $goLoot = new Loot(); if ($goLoot->getByContainer(LOOT_GAMEOBJECT, $_)) { $extraCols = $goLoot->extraCols; $hiddenCols = ['source', 'side', 'slot', 'reqlevel']; $this->extendGlobalData($goLoot->jsGlobals); foreach ($goLoot->iterate() as &$lv) { if (!empty($hiddenCols)) { foreach ($hiddenCols as $k => $str) { if (!empty($lv[$str])) { unset($hiddenCols[$k]); } } } if (!$lv['quest']) { continue; } $extraCols[] = 'Listview.extraCols.condition'; $reqQuest[$lv['id']] = 0; $lv['condition'][0][$this->typeId][] = [[CND_QUESTTAKEN, &$reqQuest[$lv['id']]]]; } $extraCols[] = 'Listview.extraCols.percent'; $this->lvTabs[] = array('file' => 'item', 'data' => $goLoot->getResult(), 'params' => array('name' => '$LANG.tab_contains', 'id' => 'contains', 'extraCols' => "\$[" . implode(', ', array_unique($extraCols)) . "]", 'hiddenCols' => $hiddenCols ? '$' . Util::toJSON(array_values($hiddenCols)) : null)); } } if ($reqIds = array_keys($reqQuest)) { $conditions = array('OR', ['reqSourceItemId1', $reqIds], ['reqSourceItemId2', $reqIds], ['reqSourceItemId3', $reqIds], ['reqSourceItemId4', $reqIds], ['reqItemId1', $reqIds], ['reqItemId2', $reqIds], ['reqItemId3', $reqIds], ['reqItemId4', $reqIds], ['reqItemId5', $reqIds], ['reqItemId6', $reqIds]); $reqQuests = new QuestList($conditions); $this->extendGlobalData($reqQuests->getJSGlobals()); foreach ($reqQuests->iterate() as $qId => $__) { if (empty($reqQuests->requires[$qId][TYPE_ITEM])) { continue; } foreach ($reqIds as $rId) { if (in_array($rId, $reqQuests->requires[$qId][TYPE_ITEM])) { $reqQuest[$rId] = $reqQuests->id; } } } } // tab: Same model as .. whats the f*****g point..? $sameModel = new GameObjectList(array(['displayId', $this->subject->getField('displayId')], ['id', $this->typeId, '!'])); if (!$sameModel->error) { $this->extendGlobalData($sameModel->getJSGlobals()); $this->lvTabs[] = array('file' => 'object', 'data' => $sameModel->getListviewData(), 'params' => array('name' => '$LANG.tab_samemodelas', 'id' => 'same-model-as')); } }
protected function generateContent() { $infobox = []; $_mask = 1 << $this->typeId - 1; $mountVendors = array(null, [384, 33307], [3362, 33553], [1261, 33310], [4730, 33653], [4731, 33555], [3685, 33556], [7955, 33650], [7952, 33554], null, [16264, 33557], [17584, 33657]); /***********/ /* Infobox */ /***********/ $infobox = Lang::getInfoBoxForFlags($this->subject->getField('cuFlags')); // side if ($_ = $this->subject->getField('side')) { $infobox[] = Lang::main('side') . Lang::main('colon') . '[span class=icon-' . ($_ == 2 ? 'horde' : 'alliance') . ']' . Lang::game('si', $_) . '[/span]'; } // faction if ($_ = $this->subject->getField('factionId')) { $fac = new FactionList(array(['f.id', $_])); $this->extendGlobalData($fac->getJSGlobals()); $infobox[] = Util::ucFirst(Lang::game('faction')) . Lang::main('colon') . '[faction=' . $fac->id . ']'; } // leader if ($_ = $this->subject->getField('leader')) { $this->extendGlobalIds(TYPE_NPC, $_); $infobox[] = Lang::race('racialLeader') . Lang::main('colon') . '[npc=' . $_ . ']'; } // start area if ($_ = $this->subject->getField('startAreaId')) { $this->extendGlobalIds(TYPE_ZONE, $_); $infobox[] = Lang::race('startZone') . Lang::main('colon') . '[zone=' . $_ . ']'; } /****************/ /* Main Content */ /****************/ $this->infobox = '[ul][li]' . implode('[/li][li]', $infobox) . '[/li][/ul]'; $this->expansion = Util::$expansionString[$this->subject->getField('expansion')]; $this->headIcons = array('race_' . strtolower($this->subject->getField('fileString')) . '_male', 'race_' . strtolower($this->subject->getField('fileString')) . '_female'); $this->redButtons = array(BUTTON_WOWHEAD => true, BUTTON_LINKS => true); /**************/ /* Extra Tabs */ /**************/ // Classes $classes = new CharClassList(array(['racemask', $_mask, '&'])); if (!$classes->error) { $this->extendGlobalData($classes->getJSGlobals()); $this->lvTabs[] = ['class', ['data' => array_values($classes->getListviewData())]]; } // Tongues $conditions = array(['typeCat', -11], ['reqRaceMask', $_mask, '&']); $tongues = new SpellList($conditions); if (!$tongues->error) { $this->extendGlobalData($tongues->getJSGlobals()); $this->lvTabs[] = ['spell', array('data' => array_values($tongues->getListviewData()), 'id' => 'languages', 'name' => '$LANG.tab_languages', 'hiddenCols' => ['reagents'])]; } // Racials $conditions = array(['typeCat', -4], ['reqRaceMask', $_mask, '&']); $racials = new SpellList($conditions); if (!$racials->error) { $this->extendGlobalData($racials->getJSGlobals()); $this->lvTabs[] = ['spell', array('data' => array_values($racials->getListviewData()), 'id' => 'racial-traits', 'name' => '$LANG.tab_racialtraits', 'hiddenCols' => ['reagents'])]; } // Quests $conditions = array(['reqRaceMask', $_mask, '&'], [['reqRaceMask', RACE_MASK_HORDE, '&'], RACE_MASK_HORDE, '!'], [['reqRaceMask', RACE_MASK_ALLIANCE, '&'], RACE_MASK_ALLIANCE, '!']); $quests = new QuestList($conditions); if (!$quests->error) { $this->extendGlobalData($quests->getJSGlobals()); $this->lvTabs[] = ['quest', ['data' => array_values($quests->getListviewData())]]; } // Mounts // ok, this sucks, but i rather hardcode the trainer, than fetch items by namepart $items = isset($mountVendors[$this->typeId]) ? DB::World()->selectCol('SELECT item FROM npc_vendor WHERE entry IN (?a)', $mountVendors[$this->typeId]) : 0; $conditions = array(['i.id', $items], ['i.class', ITEM_CLASS_MISC], ['i.subClass', 5]); $mounts = new ItemList($conditions); if (!$mounts->error) { $this->extendGlobalData($mounts->getJSGlobals()); $this->lvTabs[] = ['item', array('data' => array_values($mounts->getListviewData()), 'id' => 'mounts', 'name' => '$LANG.tab_mounts', 'hiddenCols' => ['slot', 'type'])]; } }