コード例 #1
0
ファイル: objects.php プロジェクト: TrinityCore/aowow
 protected function generateContent()
 {
     $conditions = [];
     if (!User::isInGroup(U_GROUP_EMPLOYEE)) {
         $conditions[] = [['cuFlags', CUSTOM_EXCLUDE_FOR_LISTVIEW, '&'], 0];
     }
     if ($this->category) {
         $conditions[] = ['typeCat', (int) $this->category[0]];
     }
     // recreate form selection
     $this->filter = $this->filterObj->getForm('form');
     $this->filter['query'] = isset($_GET['filter']) ? $_GET['filter'] : null;
     $this->filter['fi'] = $this->filterObj->getForm();
     if ($_ = $this->filterObj->getConditions()) {
         $conditions[] = $_;
     }
     $tabData = ['data' => []];
     $objects = new GameObjectList($conditions, ['extraOpts' => $this->filterObj->extraOpts]);
     if (!$objects->error) {
         $tabData['data'] = array_values($objects->getListviewData());
         if ($objects->hasSetFields(['reqSkill'])) {
             $tabData['visibleCols'] = ['skill'];
         }
         // create note if search limit was exceeded
         if ($objects->getMatches() > CFG_SQL_LIMIT_DEFAULT) {
             $tabData['note'] = sprintf(Util::$tryFilteringString, 'LANG.lvnote_objectsfound', $objects->getMatches(), CFG_SQL_LIMIT_DEFAULT);
             $tabData['_truncated'] = 1;
         }
         if ($this->filterObj->error) {
             $tabData['_errors'] = 1;
         }
     }
     $this->lvTabs[] = ['object', $tabData];
 }
コード例 #2
0
ファイル: search.php プロジェクト: Niknox/aowow
 private function _searchObject($cndBase)
 {
     $result = [];
     $cnd = array_merge($cndBase, [$this->createLookup()]);
     $objects = new GameObjectList($cnd);
     if ($data = $objects->getListviewData()) {
         if ($this->searchMask & SEARCH_TYPE_REGULAR) {
             $this->extendGlobalData($objects->getJSGlobals());
         }
         $result = array('type' => TYPE_OBJECT, 'appendix' => ' (Object)', 'matches' => $objects->getMatches(), 'file' => GameObjectList::$brickFile, 'data' => $data, 'params' => []);
         if ($objects->getMatches() > $this->maxResults) {
             $result['params']['note'] = sprintf(Util::$tryNarrowingString, 'LANG.lvnote_objectsfound', $objects->getMatches(), $this->maxResults);
             $result['params']['_truncated'] = 1;
         }
         if (isset($result['params']['note'])) {
             $result['params']['note'] .= ' + LANG.dash + $WH.sprintf(LANG.lvnote_filterresults, \'?objects&filter=na=' . urlencode($this->search) . '\')';
         } else {
             $result['params']['note'] = '$$WH.sprintf(LANG.lvnote_filterresults, \'?objects&filter=na=' . urlencode($this->search) . '\')';
         }
     }
     return $result;
 }
コード例 #3
0
ファイル: spell.php プロジェクト: Niknox/aowow
 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'));
     }
 }
コード例 #4
0
ファイル: quest.php プロジェクト: Niknox/aowow
 protected function generateContent()
 {
     $_level = $this->subject->getField('level');
     $_minLevel = $this->subject->getField('minLevel');
     $_flags = $this->subject->getField('flags');
     $_specialFlags = $this->subject->getField('specialFlags');
     $_side = Util::sideByRaceMask($this->subject->getField('reqRaceMask'));
     /***********/
     /* Infobox */
     /***********/
     $infobox = Lang::getInfoBoxForFlags($this->subject->getField('cuFlags'));
     // event (todo: assign eventData)
     if ($_ = $this->subject->getField('eventId')) {
         $this->extendGlobalIds(TYPE_WORLDEVENT, $_);
         $infobox[] = Lang::game('eventShort') . Lang::main('colon') . '[event=' . $_ . ']';
     }
     // level
     if ($_level > 0) {
         $infobox[] = Lang::game('level') . Lang::main('colon') . $_level;
     }
     // reqlevel
     if ($_minLevel) {
         $lvl = $_minLevel;
         if ($_ = $this->subject->getField('maxLevel')) {
             $lvl .= ' - ' . $_;
         }
         $infobox[] = sprintf(Lang::game('reqLevel'), $lvl);
     }
     // loremaster (i dearly hope those flags cover every case...)
     if ($this->subject->getField('zoneOrSortBak') > 0 && !$this->subject->isRepeatable()) {
         $conditions = array(['ac.type', ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_IN_ZONE], ['ac.value1', $this->subject->getField('zoneOrSortBak')], ['a.faction', $_side, '&']);
         $loremaster = new AchievementList($conditions);
         $this->extendGlobalData($loremaster->getJSGlobals(GLOBALINFO_SELF));
         switch ($loremaster->getMatches()) {
             case 0:
                 break;
             case 1:
                 $infobox[] = Lang::quest('loremaster') . Lang::main('colon') . '[achievement=' . $loremaster->id . ']';
                 break;
             default:
                 $lm = Lang::quest('loremaster') . Lang::main('colon') . '[ul]';
                 foreach ($loremaster->iterate() as $id => $__) {
                     $lm .= '[li][achievement=' . $id . '][/li]';
                 }
                 $infobox[] = $lm . '[/ul]';
                 break;
         }
     }
     // type (maybe expand uppon?)
     $_ = [];
     if ($_flags & QUEST_FLAG_DAILY) {
         $_[] = Lang::quest('daily');
     } else {
         if ($_flags & QUEST_FLAG_WEEKLY) {
             $_[] = Lang::quest('weekly');
         } else {
             if ($_specialFlags & QUEST_FLAG_SPECIAL_MONTHLY) {
                 $_[] = Lang::quest('monthly');
             }
         }
     }
     if ($t = $this->subject->getField('type')) {
         $_[] = Lang::quest('questInfo', $t);
     }
     if ($_) {
         $infobox[] = Lang::game('type') . Lang::main('colon') . implode(' ', $_);
     }
     // side
     $_ = Lang::main('side') . Lang::main('colon');
     switch ($_side) {
         case 3:
             $infobox[] = $_ . Lang::game('si', 3);
             break;
         case 2:
             $infobox[] = $_ . '[span class=icon-horde]' . Lang::game('si', 2) . '[/span]';
             break;
         case 1:
             $infobox[] = $_ . '[span class=icon-alliance]' . Lang::game('si', 1) . '[/span]';
             break;
     }
     // races
     if ($_ = Lang::getRaceString($this->subject->getField('reqRaceMask'), $__, $jsg, $n, false)) {
         $this->extendGlobalIds(TYPE_RACE, $jsg);
         $t = $n == 1 ? Lang::game('race') : Lang::game('races');
         $infobox[] = Util::ucFirst($t) . Lang::main('colon') . $_;
     }
     // classes
     if ($_ = Lang::getClassString($this->subject->getField('reqClassMask'), $jsg, $n, false)) {
         $this->extendGlobalIds(TYPE_CLASS, $jsg);
         $t = $n == 1 ? Lang::game('class') : Lang::game('classes');
         $infobox[] = Util::ucFirst($t) . Lang::main('colon') . $_;
     }
     // profession / skill
     if ($_ = $this->subject->getField('reqSkillId')) {
         $this->extendGlobalIds(TYPE_SKILL, $_);
         $sk = '[skill=' . $_ . ']';
         if ($_ = $this->subject->getField('reqSkillPoints')) {
             $sk .= ' (' . $_ . ')';
         }
         $infobox[] = Lang::quest('profession') . Lang::main('colon') . $sk;
     }
     // timer
     if ($_ = $this->subject->getField('timeLimit')) {
         $infobox[] = Lang::quest('timer') . Lang::main('colon') . Util::formatTime($_ * 1000);
     }
     $startEnd = DB::Aowow()->select('SELECT * FROM ?_quests_startend WHERE questId = ?d', $this->typeId);
     // start
     $start = '[icon name=quest_start' . ($this->subject->isDaily() ? '_daily' : '') . ']' . Lang::event('start') . Lang::main('colon') . '[/icon]';
     $s = [];
     foreach ($startEnd as $se) {
         if ($se['method'] & 0x1) {
             $this->extendGlobalIds($se['type'], $se['typeId']);
             $s[] = ($s ? '[span=invisible]' . $start . '[/span] ' : $start . ' ') . '[' . Util::$typeStrings[$se['type']] . '=' . $se['typeId'] . ']';
         }
     }
     if ($s) {
         $infobox[] = implode('[br]', $s);
     }
     // end
     $end = '[icon name=quest_end' . ($this->subject->isDaily() ? '_daily' : '') . ']' . Lang::event('end') . Lang::main('colon') . '[/icon]';
     $e = [];
     foreach ($startEnd as $se) {
         if ($se['method'] & 0x2) {
             $this->extendGlobalIds($se['type'], $se['typeId']);
             $e[] = ($e ? '[span=invisible]' . $end . '[/span] ' : $end . ' ') . '[' . Util::$typeStrings[$se['type']] . '=' . $se['typeId'] . ']';
         }
     }
     if ($e) {
         $infobox[] = implode('[br]', $e);
     }
     // Repeatable
     if ($_flags & QUEST_FLAG_REPEATABLE || $_specialFlags & QUEST_FLAG_SPECIAL_REPEATABLE) {
         $infobox[] = Lang::quest('repeatable');
     }
     // sharable | not sharable
     $infobox[] = $_flags & QUEST_FLAG_SHARABLE ? Lang::quest('sharable') : Lang::quest('notSharable');
     // Keeps you PvP flagged
     if ($this->subject->isPvPEnabled()) {
         $infobox[] = Lang::quest('keepsPvpFlag');
     }
     // difficulty (todo (low): formula unclear. seems to be [minLevel,] -4, -2, (level), +3, +(9 to 15))
     if ($_level > 0) {
         $_ = [];
         // red
         if ($_minLevel && $_minLevel < $_level - 4) {
             $_[] = '[color=q10]' . $_minLevel . '[/color]';
         }
         // orange
         if (!$_minLevel || $_minLevel < $_level - 2) {
             $_[] = '[color=r1]' . (!$_ && $_minLevel > $_level - 4 ? $_minLevel : $_level - 4) . '[/color]';
         }
         // yellow
         $_[] = '[color=r2]' . (!$_ && $_minLevel > $_level - 2 ? $_minLevel : $_level - 2) . '[/color]';
         // green
         $_[] = '[color=r3]' . ($_level + 3) . '[/color]';
         // grey (is about +/-1 level off)
         $_[] = '[color=r4]' . ($_level + 3 + ceil(12 * $_level / MAX_LEVEL)) . '[/color]';
         if ($_) {
             $infobox[] = Lang::game('difficulty') . Lang::main('colon') . implode('[small] &nbsp;[/small]', $_);
         }
     }
     $this->infobox = '[ul][li]' . implode('[/li][li]', $infobox) . '[/li][/ul]';
     /**********/
     /* Series */
     /**********/
     // Quest Chain (are there cases where quests go in parallel?)
     $chain = array(array(array('side' => $_side, 'typeStr' => Util::$typeStrings[TYPE_QUEST], 'typeId' => $this->typeId, 'name' => $this->name, '_next' => $this->subject->getField('nextQuestIdChain'))));
     $_ = $chain[0][0];
     while ($_) {
         if ($_ = DB::Aowow()->selectRow('SELECT id AS typeId, name_loc0, name_loc2, name_loc3, name_loc6, name_loc8, reqRaceMask FROM ?_quests WHERE nextQuestIdChain = ?d', $_['typeId'])) {
             $n = Util::localizedString($_, 'name');
             array_unshift($chain, array(array('side' => Util::sideByRaceMask($_['reqRaceMask']), 'typeStr' => Util::$typeStrings[TYPE_QUEST], 'typeId' => $_['typeId'], 'name' => strlen($n) > 40 ? substr($n, 0, 40) . '…' : $n)));
         }
     }
     $_ = end($chain)[0];
     while ($_) {
         if ($_ = DB::Aowow()->selectRow('SELECT id AS typeId, name_loc0, name_loc2, name_loc3, name_loc6, name_loc8, reqRaceMask, nextQuestIdChain AS _next FROM ?_quests WHERE id = ?d', $_['_next'])) {
             $n = Util::localizedString($_, 'name');
             array_push($chain, array(array('side' => Util::sideByRaceMask($_['reqRaceMask']), 'typeStr' => Util::$typeStrings[TYPE_QUEST], 'typeId' => $_['typeId'], 'name' => strlen($n) > 40 ? substr($n, 0, 40) . '…' : $n, '_next' => $_['_next'])));
         }
     }
     if (count($chain) > 1) {
         $this->series[] = [$chain, null];
     }
     // todo (low): sensibly merge the following lists into 'series'
     $listGen = function ($cnd) {
         $chain = [];
         $list = new QuestList($cnd);
         if ($list->error) {
             return null;
         }
         foreach ($list->iterate() as $id => $__) {
             $n = $list->getField('name', true);
             $chain[] = array(array('side' => Util::sideByRaceMask($list->getField('reqRaceMask')), 'typeStr' => Util::$typeStrings[TYPE_QUEST], 'typeId' => $id, 'name' => strlen($n) > 40 ? substr($n, 0, 40) . '…' : $n));
         }
         return $chain;
     };
     $extraLists = array(['reqQ', array('OR', ['AND', ['nextQuestId', $this->typeId], ['exclusiveGroup', 0, '<']], ['AND', ['id', $this->subject->getField('prevQuestId')], ['nextQuestIdChain', $this->typeId, '!']])], ['reqOneQ', array(['exclusiveGroup', 0, '>'], ['nextQuestId', $this->typeId])], ['opensQ', array('OR', ['AND', ['prevQuestId', $this->typeId], ['id', $this->subject->getField('nextQuestIdChain'), '!']], ['id', $this->subject->getField('nextQuestId')])], ['closesQ', array(['exclusiveGroup', 0, '!'], ['exclusiveGroup', $this->subject->getField('exclusiveGroup')], ['id', $this->typeId, '!'])], ['enablesQ', array(['prevQuestId', -$this->typeId])], ['enabledByQ', array(['id', -$this->subject->getField('prevQuestId')])]);
     foreach ($extraLists as $el) {
         if ($_ = $listGen($el[1])) {
             $this->series[] = [$_, sprintf(Util::$dfnString, Lang::quest($el[0] . 'Desc'), Lang::quest($el[0]))];
         }
     }
     /*******************/
     /* Objectives List */
     /*******************/
     $this->objectiveList = [];
     $this->providedItem = [];
     // gather ids for lookup
     $olItems = $olNPCs = $olGOs = $olFactions = [];
     // items
     $olItems[0] = array($this->subject->getField('sourceItemId'), $this->subject->getField('sourceItemCount'), false);
     for ($i = 1; $i < 7; $i++) {
         $id = $this->subject->getField('reqItemId' . $i);
         $qty = $this->subject->getField('reqItemCount' . $i);
         if (!$id || !$qty) {
             continue;
         }
         $olItems[$i] = [$id, $qty, $id == $olItems[0][0]];
     }
     if ($ids = array_column($olItems, 0)) {
         $olItemData = new ItemList(array(['id', $ids]));
         $this->extendGlobalData($olItemData->getJSGlobals(GLOBALINFO_SELF));
         $providedRequired = false;
         foreach ($olItems as $i => list($itemId, $qty, $provided)) {
             if (!$i || !$itemId || !in_array($itemId, $olItemData->getFoundIDs())) {
                 continue;
             }
             if ($provided) {
                 $providedRequired = true;
             }
             $this->objectiveList[] = array('typeStr' => Util::$typeStrings[TYPE_ITEM], 'id' => $itemId, 'name' => $olItemData->json[$itemId]['name'], 'qty' => $qty > 1 ? $qty : 0, 'quality' => 7 - $olItemData->json[$itemId]['quality'], 'extraText' => $provided ? '&nbsp;(' . Lang::quest('provided') . ')' : '');
         }
         // if providd item is not required by quest, list it below other requirements
         if (!$providedRequired && $olItems[0][0] && in_array($olItems[0][0], $olItemData->getFoundIDs())) {
             $this->providedItem = array('id' => $olItems[0][0], 'name' => $olItemData->json[$olItems[0][0]]['name'], 'qty' => $olItems[0][1] > 1 ? $olItems[0][1] : 0, 'quality' => 7 - $olItemData->json[$olItems[0][0]]['quality']);
         }
     }
     // creature or GO...
     for ($i = 1; $i < 5; $i++) {
         $id = $this->subject->getField('reqNpcOrGo' . $i);
         $qty = $this->subject->getField('reqNpcOrGoCount' . $i);
         $altTxt = $this->subject->getField('objectiveText' . $i, true);
         if ($id > 0 && $qty) {
             $olNPCs[$id] = [$qty, $altTxt, []];
         } else {
             if ($id < 0 && $qty) {
                 $olGOs[-$id] = [$qty, $altTxt];
             }
         }
     }
     // .. creature kills
     if ($ids = array_keys($olNPCs)) {
         $olNPCData = new CreatureList(array('OR', ['id', $ids], ['killCredit1', $ids], ['killCredit2', $ids]));
         $this->extendGlobalData($olNPCData->getJSGlobals(GLOBALINFO_SELF));
         // create proxy-references
         foreach ($olNPCData->iterate() as $id => $__) {
             if ($p = $olNPCData->getField('KillCredit1')) {
                 if (isset($olNPCs[$p])) {
                     $olNPCs[$p][2][$id] = $olNPCData->getField('name', true);
                 }
             }
             if ($p = $olNPCData->getField('KillCredit2')) {
                 if (isset($olNPCs[$p])) {
                     $olNPCs[$p][2][$id] = $olNPCData->getField('name', true);
                 }
             }
         }
         foreach ($olNPCs as $i => $pair) {
             if (!$i || !in_array($i, $olNPCData->getFoundIDs())) {
                 continue;
             }
             $ol = array('typeStr' => Util::$typeStrings[TYPE_NPC], 'id' => $i, 'name' => $pair[1] ?: Util::localizedString($olNPCData->getEntry($i), 'name'), 'qty' => $pair[0] > 1 ? $pair[0] : 0, 'extraText' => $_specialFlags & QUEST_FLAG_SPECIAL_SPELLCAST || $pair[1] ? '' : ' ' . Lang::achievement('slain'), 'proxy' => $pair[2]);
             if ($pair[2]) {
                 // has proxies assigned, add yourself as another proxy
                 $ol['proxy'][$i] = Util::localizedString($olNPCData->getEntry($i), 'name');
             }
             $this->objectiveList[] = $ol;
         }
     }
     // .. GO interactions
     if ($ids = array_keys($olGOs)) {
         $olGOData = new GameObjectList(array(['id', $ids]));
         $this->extendGlobalData($olGOData->getJSGlobals(GLOBALINFO_SELF));
         foreach ($olNPCs as $i => $pair) {
             if (!$i || !in_array($i, $olGOData->getFoundIDs())) {
                 continue;
             }
             $this->objectiveList[] = array('typeStr' => Util::$typeStrings[TYPE_OBJECT], 'id' => $i, 'name' => $pair[1] ?: Util::localizedString($olGOData->getEntry($i), 'name'), 'qty' => $pair[0] > 1 ? $pair[0] : 0);
         }
     }
     // reputation required
     for ($i = 1; $i < 3; $i++) {
         $id = $this->subject->getField('reqFactionId' . $i);
         $val = $this->subject->getField('reqFactionValue' . $i);
         if (!$id) {
             continue;
         }
         $olFactions[$id] = $val;
     }
     if ($ids = array_keys($olFactions)) {
         $olFactionsData = new FactionList(array(['id', $ids]));
         $this->extendGlobalData($olFactionsData->getJSGlobals(GLOBALINFO_SELF));
         foreach ($olFactions as $i => $val) {
             if (!$i || !in_array($i, $olFactionsData->getFoundIDs())) {
                 continue;
             }
             $this->objectiveList[] = array('typeStr' => Util::$typeStrings[TYPE_FACTION], 'id' => $i, 'name' => Util::localizedString($olFactionsData->getEntry($i), 'name'), 'qty' => sprintf(Util::$dfnString, $val . ' ' . Lang::achievement('points'), Lang::getReputationLevelForPoints($val)), 'extraText' => '');
         }
     }
     // granted spell
     if ($_ = $this->subject->getField('sourceSpellId')) {
         $this->extendGlobalIds(TYPE_SPELL, $_);
         $this->objectiveList[] = array('typeStr' => Util::$typeStrings[TYPE_SPELL], 'id' => $_, 'name' => SpellList::getName($_), 'qty' => 0, 'extraText' => '&nbsp;(' . Lang::quest('provided') . ')');
     }
     // required money
     if ($this->subject->getField('rewardOrReqMoney') < 0) {
         $this->objectiveList[] = ['text' => Lang::quest('reqMoney') . Lang::main('colon') . Util::formatMoney(abs($this->subject->getField('rewardOrReqMoney')))];
     }
     // required pvp kills
     if ($_ = $this->subject->getField('reqPlayerKills')) {
         $this->objectiveList[] = ['text' => Lang::quest('playerSlain') . '&nbsp;(' . $_ . ')'];
     }
     /**********/
     /* Mapper */
     /**********/
     $this->addJS('?data=zones&locale=' . User::$localeId . '&t=' . $_SESSION['dataKey']);
     /*
         TODO (GODDAMNIT): jeez..
     */
     // $startend + reqNpcOrGo[1-4]
     $this->map = null;
     // array(
     // 'data' => ['zone' => $this->typeId],
     // 'som'  => Util::toJSON($som)
     // );
     /****************/
     /* Main Content */
     /****************/
     $this->gains = $this->createGains();
     $this->mail = $this->createMail($maTab, $startEnd);
     $this->rewards = $this->createRewards();
     $this->objectives = $this->subject->parseText('objectives', false);
     $this->details = $this->subject->parseText('details', false);
     $this->offerReward = $this->subject->parseText('offerReward', false);
     $this->requestItems = $this->subject->parseText('requestItems', false);
     $this->completed = $this->subject->parseText('completed', false);
     $this->end = $this->subject->parseText('end', false);
     $this->suggestedPl = $this->subject->getField('suggestedPlayers');
     $this->unavailable = $_flags & QUEST_FLAG_UNAVAILABLE || $this->subject->getField('cuFlags') & CUSTOM_EXCLUDE_FOR_LISTVIEW;
     $this->redButtons = array(BUTTON_LINKS => ['color' => 'ffffff00', 'linkId' => 'quest:' . $this->typeId . ':' . $_level . ''], BUTTON_WOWHEAD => true);
     if ($maTab) {
         $this->lvTabs[] = $maTab;
     }
     // factionchange-equivalent
     if ($pendant = DB::World()->selectCell('SELECT IF(horde_id = ?d, alliance_id, -horde_id) FROM player_factionchange_quests WHERE alliance_id = ?d OR horde_id = ?d', $this->typeId, $this->typeId, $this->typeId)) {
         $altQuest = new QuestList(array(['id', abs($pendant)]));
         if (!$altQuest->error) {
             $this->transfer = sprintf(Lang::quest('_transfer'), $altQuest->id, $altQuest->getField('name', true), $pendant > 0 ? 'alliance' : 'horde', $pendant > 0 ? Lang::game('si', 1) : Lang::game('si', 2));
         }
     }
     /**************/
     /* Extra Tabs */
     /**************/
     // tab: see also
     $seeAlso = new QuestList(array(['name_loc' . User::$localeId, '%' . $this->name . '%'], ['id', $this->typeId, '!']));
     if (!$seeAlso->error) {
         $this->extendGlobalData($seeAlso->getJSGlobals());
         $this->lvTabs[] = array('file' => 'quest', 'data' => $seeAlso->getListviewData(), 'params' => array('name' => '$LANG.tab_seealso', 'id' => 'see-also'));
     }
     // tab: criteria of
     $criteriaOf = new AchievementList(array(['ac.type', ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST], ['ac.value1', $this->typeId]));
     if (!$criteriaOf->error) {
         $this->extendGlobalData($criteriaOf->getJSGlobals());
         $this->lvTabs[] = array('file' => 'achievement', 'data' => $criteriaOf->getListviewData(), 'params' => array('name' => '$LANG.tab_criteriaof', 'id' => 'criteria-of'));
     }
     // tab: conditions
     $cnd = [];
     if ($_ = $this->subject->getField('reqMinRepFaction')) {
         $cnd[CND_SRC_QUEST_ACCEPT][$this->typeId][0][] = [CND_REPUTATION_RANK, $_, 1 << Util::getReputationLevelForPoints($this->subject->getField('reqMinRepValue'))];
         $this->extendGlobalIds(TYPE_FACTION, $_);
     }
     if ($_ = $this->subject->getField('reqMaxRepFaction')) {
         $cnd[CND_SRC_QUEST_ACCEPT][$this->typeId][0][] = [-CND_REPUTATION_RANK, $_, 1 << Util::getReputationLevelForPoints($this->subject->getField('reqMaxRepValue'))];
         $this->extendGlobalIds(TYPE_FACTION, $_);
     }
     $_ = Util::getServerConditions([CND_SRC_QUEST_ACCEPT, CND_SRC_QUEST_SHOW_MARK], null, $this->typeId);
     if (!empty($_[0])) {
         // awkward merger
         if (isset($_[0][CND_SRC_QUEST_ACCEPT][$this->typeId][0])) {
             if (isset($cnd[CND_SRC_QUEST_ACCEPT][$this->typeId][0])) {
                 $cnd[CND_SRC_QUEST_ACCEPT][$this->typeId][0] = array_merge($cnd[CND_SRC_QUEST_ACCEPT][$this->typeId][0], $_[0][CND_SRC_QUEST_ACCEPT][$this->typeId][0]);
             } else {
                 $cnd[CND_SRC_QUEST_ACCEPT] = $_[0][CND_SRC_QUEST_ACCEPT];
             }
         }
         if (isset($_[0][CND_SRC_QUEST_SHOW_MARK])) {
             $cnd[CND_SRC_QUEST_SHOW_MARK] = $_[0][CND_SRC_QUEST_SHOW_MARK];
         }
         $this->extendGlobalData($_[1]);
     }
     if ($cnd) {
         $tab = "<script type=\"text/javascript\">\n" . "var markup = ConditionList.createTab(" . Util::toJSON($cnd) . ");\n" . "Markup.printHtml(markup, 'tab-conditions', { allow: Markup.CLASS_STAFF })" . "</script>";
         $this->lvTabs[] = array('file' => null, 'data' => $tab, 'params' => array('id' => 'conditions', 'name' => '$LANG.requires'));
     }
 }
コード例 #5
0
ファイル: faction.php プロジェクト: TrinityCore/aowow
 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'])];
     }
 }
コード例 #6
0
ファイル: object.php プロジェクト: Carbenium/aowow
 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'));
     }
 }
コード例 #7
0
ファイル: search.php プロジェクト: TrinityCore/aowow
 private function _searchObject($cndBase)
 {
     $cnd = array_merge($cndBase, [$this->createLookup()]);
     $objects = new GameObjectList($cnd);
     if ($data = $objects->getListviewData()) {
         if ($this->searchMask & SEARCH_TYPE_REGULAR) {
             $this->extendGlobalData($objects->getJSGlobals());
         }
         $osInfo = [TYPE_OBJECT, ' (Object)', $objects->getMatches()];
         $result['data'] = array_values($data);
         if ($objects->getMatches() > $this->maxResults) {
             $result['note'] = sprintf(Util::$tryNarrowingString, 'LANG.lvnote_objectsfound', $objects->getMatches(), $this->maxResults);
             $result['_truncated'] = 1;
         }
         if (isset($result['note'])) {
             $result['note'] .= ' + LANG.dash + $WH.sprintf(LANG.lvnote_filterresults, \'?objects&filter=na=' . urlencode($this->search) . '\')';
         } else {
             $result['note'] = '$$WH.sprintf(LANG.lvnote_filterresults, \'?objects&filter=na=' . urlencode($this->search) . '\')';
         }
         return ['object', $result, null, $osInfo];
     }
     return false;
 }
コード例 #8
0
ファイル: spell.class.php プロジェクト: saqar/aowow
 public function getModelInfo($spellId = 0, $effIdx = 0)
 {
     $displays = [0 => []];
     foreach ($this->iterate() as $id => $__) {
         if ($spellId && $spellId != $id) {
             continue;
         }
         for ($i = 1; $i < 4; $i++) {
             $effMV = $this->curTpl['effect' . $i . 'MiscValue'];
             if (!$effMV) {
                 continue;
             }
             // GO Model from MiscVal
             if (in_array($this->curTpl['effect' . $i . 'Id'], [50, 76, 104, 105, 106, 107])) {
                 if (isset($displays[TYPE_OBJECT][$id])) {
                     $displays[TYPE_OBJECT][$id][0][] = $i;
                 } else {
                     $displays[TYPE_OBJECT][$id] = [[$i], $effMV];
                 }
             } else {
                 if (in_array($this->curTpl['effect' . $i . 'Id'], [28, 90, 134]) || in_array($this->curTpl['effect' . $i . 'AuraId'], [56, 78])) {
                     if (isset($displays[TYPE_NPC][$id])) {
                         $displays[TYPE_NPC][$id][0][] = $i;
                     } else {
                         $displays[TYPE_NPC][$id] = [[$i], $effMV];
                     }
                 } else {
                     if ($this->curTpl['effect' . $i . 'AuraId'] == 36) {
                         $subForms = array(892 => [892, 29407, 29406, 29408, 29405], 8571 => [8571, 29410, 29411, 29412], 2281 => [2281, 29413, 29414, 29416, 29417], 2289 => [2289, 29415, 29418, 29419, 29420, 29421]);
                         if ($st = DB::Aowow()->selectRow('SELECT *, displayIdA as model1, displayIdH as model2 FROM ?_shapeshiftforms WHERE id = ?d', $effMV)) {
                             foreach ([1, 2] as $j) {
                                 if (isset($subForms[$st['model' . $j]])) {
                                     $st['model' . $j] = $subForms[$st['model' . $j]][array_rand($subForms[$st['model' . $j]])];
                                 }
                             }
                             $displays[0][$id][$i] = array('typeId' => 0, 'displayId' => $st['model2'] ? $st['model' . rand(1, 2)] : $st['model1'], 'creatureType' => $st['creatureType'], 'displayName' => Util::localizedString($st, 'name'));
                         }
                     }
                 }
             }
         }
     }
     $results = $displays[0];
     if (!empty($displays[TYPE_NPC])) {
         $nModels = new CreatureList(array(['id', array_column($displays[TYPE_NPC], 1)]));
         foreach ($nModels->iterate() as $nId => $__) {
             $srcId = 0;
             foreach ($displays[TYPE_NPC] as $srcId => $set) {
                 if ($set[1] == $nId) {
                     break;
                 }
             }
             foreach ($set[0] as $idx) {
                 $results[$srcId][$idx] = array('typeId' => $nId, 'displayId' => $nModels->getRandomModelId(), 'displayName' => $nModels->getField('name', true));
             }
         }
     }
     if (!empty($displays[TYPE_OBJECT])) {
         $oModels = new GameObjectList(array(['id', array_column($displays[TYPE_OBJECT], 1)]));
         foreach ($oModels->iterate() as $oId => $__) {
             $srcId = 0;
             foreach ($displays[TYPE_OBJECT] as $srcId => $set) {
                 if ($set[1] == $oId) {
                     break;
                 }
             }
             foreach ($set[0] as $idx) {
                 $results[$srcId][$idx] = array('typeId' => $oId, 'displayId' => $oModels->getField('displayId'), 'displayName' => $oModels->getField('name', true));
             }
         }
     }
     if ($spellId && $effIdx) {
         return !empty($results[$spellId][$effIdx]) ? $results[$spellId][$effIdx] : 0;
     }
     return $results;
 }
コード例 #9
0
ファイル: loot.class.php プロジェクト: Carbenium/aowow
 public function getByItem($entry, $maxResults = CFG_SQL_LIMIT_DEFAULT, $lootTableList = [])
 {
     $this->entry = intVal($entry);
     if (!$this->entry) {
         return false;
     }
     //  [fileName, tabData, tabName, tabId, extraCols, hiddenCols, visibleCols]
     $tabsFinal = array(['item', [], '$LANG.tab_containedin', 'contained-in-item', [], [], []], ['item', [], '$LANG.tab_disenchantedfrom', 'disenchanted-from', [], [], []], ['item', [], '$LANG.tab_prospectedfrom', 'prospected-from', [], [], []], ['item', [], '$LANG.tab_milledfrom', 'milled-from', [], [], []], ['creature', [], '$LANG.tab_droppedby', 'dropped-by', [], [], []], ['creature', [], '$LANG.tab_pickpocketedfrom', 'pickpocketed-from', [], [], []], ['creature', [], '$LANG.tab_skinnedfrom', 'skinned-from', [], [], []], ['creature', [], '$LANG.tab_minedfromnpc', 'mined-from-npc', [], [], []], ['creature', [], '$LANG.tab_salvagedfrom', 'salvaged-from', [], [], []], ['creature', [], '$LANG.tab_gatheredfromnpc', 'gathered-from-npc', [], [], []], ['quest', [], '$LANG.tab_rewardfrom', 'reward-from-quest', [], [], []], ['zone', [], '$LANG.tab_fishedin', 'fished-in-zone', [], [], []], ['object', [], '$LANG.tab_containedin', 'contained-in-object', [], [], []], ['object', [], '$LANG.tab_minedfrom', 'mined-from-object', [], [], []], ['object', [], '$LANG.tab_gatheredfrom', 'gathered-from-object', [], [], []], ['object', [], '$LANG.tab_fishedin', 'fished-in-object', [], [], []], ['spell', [], '$LANG.tab_createdby', 'created-by', [], [], []], ['achievement', [], '$LANG.tab_rewardfrom', 'reward-from-achievement', [], [], []]);
     $refResults = [];
     $chanceMods = [];
     $query = 'SELECT
                         lt1.entry AS ARRAY_KEY,
                         IF(lt1.reference = 0, lt1.item, lt1.reference) AS item,
                         lt1.chance,
                         SUM(IF(lt2.chance = 0, 1, 0)) AS nZeroItems,
                         SUM(lt2.chance) AS sumChance,
                         IF(lt1.groupid > 0, 1, 0) AS isGrouped,
                         IF(lt1.reference = 0, lt1.mincount, 1) AS min,
                         IF(lt1.reference = 0, lt1.maxcount, 1) AS max,
                         IF(lt1.reference > 0, lt1.maxcount, 1) AS multiplier
                     FROM
                         ?# lt1
                     LEFT JOIN
                         ?# lt2 ON lt1.entry = lt2.entry AND lt1.groupid = lt2.groupid
                     WHERE
                         %s
                     GROUP BY lt2.entry, lt2.groupid';
     $calcChance = function ($refs, $parents = []) use(&$chanceMods) {
         $retData = [];
         $retKeys = [];
         foreach ($refs as $rId => $ref) {
             // check for possible database inconsistencies
             if (!$ref['chance'] && !$ref['isGrouped']) {
                 Util::addNote(U_GROUP_EMPLOYEE, 'Loot by Item: ungrouped Item/Ref ' . $ref['item'] . ' has 0% chance assigned!');
             }
             if ($ref['isGrouped'] && $ref['sumChance'] > 100) {
                 Util::addNote(U_GROUP_EMPLOYEE, 'Loot by Item: group with Item/Ref ' . $ref['item'] . ' has ' . number_format($ref['sumChance'], 2) . '% total chance! Some items cannot drop!');
             }
             if ($ref['isGrouped'] && $ref['sumChance'] >= 100 && !$ref['chance']) {
                 Util::addNote(U_GROUP_EMPLOYEE, 'Loot by Item: Item/Ref ' . $ref['item'] . ' with adaptive chance cannot drop. Group already at 100%!');
             }
             $chance = abs($ref['chance'] ?: (100 - $ref['sumChance']) / $ref['nZeroItems']) / 100;
             // apply inherited chanceMods
             if (isset($chanceMods[$ref['item']])) {
                 $chance *= $chanceMods[$ref['item']][0];
                 $chance = 1 - pow(1 - $chance, $chanceMods[$ref['item']][1]);
             }
             // save chance for parent-ref
             $chanceMods[$rId] = [$chance, $ref['multiplier']];
             // refTemplate doesn't point to a new ref -> we are done
             if (!in_array($rId, $parents)) {
                 $data = array('percent' => $chance, 'stack' => [$ref['min'], $ref['max']], 'count' => 1);
                 if ($_ = self::createStack($ref)) {
                     $data['pctstack'] = $_;
                 }
                 // sort highest chances first
                 $i = 0;
                 for (; $i < count($retData); $i++) {
                     if ($retData[$i]['percent'] < $data['percent']) {
                         break;
                     }
                 }
                 array_splice($retData, $i, 0, [$data]);
                 array_splice($retKeys, $i, 0, [$rId]);
             }
         }
         return array_combine($retKeys, $retData);
     };
     /*
         get references containing the item
     */
     $newRefs = DB::World()->select(sprintf($query, 'lt1.item = ?d AND lt1.reference = 0'), LOOT_REFERENCE, LOOT_REFERENCE, $this->entry);
     while ($newRefs) {
         $curRefs = $newRefs;
         $newRefs = DB::World()->select(sprintf($query, 'lt1.reference IN (?a)'), LOOT_REFERENCE, LOOT_REFERENCE, array_keys($curRefs));
         $refResults += $calcChance($curRefs, array_column($newRefs, 'item'));
     }
     /*
         search the real loot-templates for the itemId and gathered refds
     */
     for ($i = 1; $i < count($this->lootTemplates); $i++) {
         if ($lootTableList && !in_array($this->lootTemplates[$i], $lootTableList)) {
             continue;
         }
         $result = $calcChance(DB::World()->select(sprintf($query, '{lt1.reference IN (?a) OR }(lt1.reference = 0 AND lt1.item = ?d)'), $this->lootTemplates[$i], $this->lootTemplates[$i], $refResults ? array_keys($refResults) : DBSIMPLE_SKIP, $this->entry));
         // do not skip here if $result is empty. Additional loot for spells and quest is added separately
         // format for actual use
         foreach ($result as $k => $v) {
             unset($result[$k]);
             $v['percent'] = round($v['percent'] * 100, 3);
             $result[abs($k)] = $v;
         }
         // cap fetched entries to the sql-limit to guarantee, that the highest chance items get selected first
         // screws with GO-loot and skinnig-loot as these templates are shared for several tabs (fish, herb, ore) (herb, ore, leather)
         $ids = array_slice(array_keys($result), 0, $maxResults);
         switch ($this->lootTemplates[$i]) {
             case LOOT_CREATURE:
                 $field = 'lootId';
                 $tabId = 4;
                 break;
             case LOOT_PICKPOCKET:
                 $field = 'pickpocketLootId';
                 $tabId = 5;
                 break;
             case LOOT_SKINNING:
                 $field = 'skinLootId';
                 $tabId = -6;
                 break;
                 // assigned later
             // assigned later
             case LOOT_PROSPECTING:
                 $field = 'id';
                 $tabId = 2;
                 break;
             case LOOT_MILLING:
                 $field = 'id';
                 $tabId = 3;
                 break;
             case LOOT_ITEM:
                 $field = 'id';
                 $tabId = 0;
                 break;
             case LOOT_DISENCHANT:
                 $field = 'disenchantId';
                 $tabId = 1;
                 break;
             case LOOT_FISHING:
                 $field = 'id';
                 $tabId = 11;
                 break;
                 // subAreas are currently ignored
             // subAreas are currently ignored
             case LOOT_GAMEOBJECT:
                 if (!$ids) {
                     continue 2;
                 }
                 $srcObj = new GameObjectList(array(['lootId', $ids]));
                 if ($srcObj->error) {
                     continue 2;
                 }
                 $srcData = $srcObj->getListviewData();
                 foreach ($srcObj->iterate() as $__id => $curTpl) {
                     switch ($curTpl['typeCat']) {
                         case 25:
                             $tabId = 15;
                             break;
                             // fishing node
                         // fishing node
                         case -3:
                             $tabId = 14;
                             break;
                             // herb
                         // herb
                         case -4:
                             $tabId = 13;
                             break;
                             // vein
                         // vein
                         default:
                             $tabId = 12;
                             break;
                             // general chest loot
                     }
                     $tabsFinal[$tabId][1][] = array_merge($srcData[$srcObj->id], $result[$srcObj->getField('lootId')]);
                     $tabsFinal[$tabId][4][] = 'Listview.extraCols.percent';
                     if ($tabId != 15) {
                         $tabsFinal[$tabId][6][] = 'skill';
                     }
                 }
                 continue 2;
             case LOOT_MAIL:
                 // quest part
                 $conditions = array(['rewardChoiceItemId1', $this->entry], ['rewardChoiceItemId2', $this->entry], ['rewardChoiceItemId3', $this->entry], ['rewardChoiceItemId4', $this->entry], ['rewardChoiceItemId5', $this->entry], ['rewardChoiceItemId6', $this->entry], ['rewardItemId1', $this->entry], ['rewardItemId2', $this->entry], ['rewardItemId3', $this->entry], ['rewardItemId4', $this->entry], 'OR');
                 if ($ids) {
                     $conditions[] = ['rewardMailTemplateId', $ids];
                 }
                 $srcObj = new QuestList($conditions);
                 if (!$srcObj->error) {
                     self::storeJSGlobals($srcObj->getJSGlobals(GLOBALINFO_SELF | GLOBALINFO_REWARDS));
                     $srcData = $srcObj->getListviewData();
                     foreach ($srcObj->iterate() as $_) {
                         $tabsFinal[10][1][] = array_merge($srcData[$srcObj->id], empty($result[$srcObj->id]) ? ['percent' => -1] : $result[$srcObj->id]);
                     }
                 }
                 // achievement part
                 $conditions = array(['itemExtra', $this->entry]);
                 if ($ar = DB::World()->selectCol('SELECT entry FROM achievement_reward WHERE item = ?d{ OR mailTemplate IN (?a)}', $this->entry, $ids ?: DBSIMPLE_SKIP)) {
                     array_push($conditions, ['id', $ar], 'OR');
                 }
                 $srcObj = new AchievementList($conditions);
                 if (!$srcObj->error) {
                     self::storeJSGlobals($srcObj->getJSGlobals(GLOBALINFO_SELF | GLOBALINFO_REWARDS));
                     $srcData = $srcObj->getListviewData();
                     foreach ($srcObj->iterate() as $_) {
                         $tabsFinal[17][1][] = array_merge($srcData[$srcObj->id], empty($result[$srcObj->id]) ? ['percent' => -1] : $result[$srcObj->id]);
                     }
                     $tabsFinal[17][5][] = 'rewards';
                     $tabsFinal[17][6][] = 'category';
                 }
                 continue 2;
             case LOOT_SPELL:
                 $conditions = array('OR', ['AND', ['effect1CreateItemId', $this->entry], ['OR', ['effect1Id', SpellList::$effects['itemCreate']], ['effect1AuraId', SpellList::$auras['itemCreate']]]], ['AND', ['effect2CreateItemId', $this->entry], ['OR', ['effect2Id', SpellList::$effects['itemCreate']], ['effect2AuraId', SpellList::$auras['itemCreate']]]], ['AND', ['effect3CreateItemId', $this->entry], ['OR', ['effect3Id', SpellList::$effects['itemCreate']], ['effect3AuraId', SpellList::$auras['itemCreate']]]]);
                 if ($ids) {
                     $conditions[] = ['id', $ids];
                 }
                 $srcObj = new SpellList($conditions);
                 if (!$srcObj->error) {
                     self::storeJSGlobals($srcObj->getJSGlobals(GLOBALINFO_SELF | GLOBALINFO_RELATED));
                     $srcData = $srcObj->getListviewData();
                     if (!empty($result)) {
                         $tabsFinal[16][4][] = 'Listview.extraCols.percent';
                     }
                     if ($srcObj->hasSetFields(['reagent1'])) {
                         $tabsFinal[16][6][] = 'reagents';
                     }
                     foreach ($srcObj->iterate() as $_) {
                         $tabsFinal[16][1][] = array_merge($srcData[$srcObj->id], empty($result[$srcObj->id]) ? ['percent' => -1] : $result[$srcObj->id]);
                     }
                 }
                 continue 2;
         }
         if (!$ids) {
             continue;
         }
         switch ($tabsFinal[abs($tabId)][0]) {
             case 'creature':
                 // new CreatureList
             // new CreatureList
             case 'item':
                 // new ItemList
             // new ItemList
             case 'zone':
                 // new ZoneList
                 $oName = ucFirst($tabsFinal[abs($tabId)][0]) . 'List';
                 $srcObj = new $oName(array([$field, $ids]));
                 if (!$srcObj->error) {
                     $srcData = $srcObj->getListviewData();
                     self::storeJSGlobals($srcObj->getJSGlobals(GLOBALINFO_SELF | GLOBALINFO_RELATED));
                     foreach ($srcObj->iterate() as $curTpl) {
                         if ($tabId < 0 && $curTpl['typeFlags'] & NPC_TYPEFLAG_HERBLOOT) {
                             $tabId = 9;
                         } else {
                             if ($tabId < 0 && $curTpl['typeFlags'] & NPC_TYPEFLAG_ENGINEERLOOT) {
                                 $tabId = 8;
                             } else {
                                 if ($tabId < 0 && $curTpl['typeFlags'] & NPC_TYPEFLAG_MININGLOOT) {
                                     $tabId = 7;
                                 } else {
                                     if ($tabId < 0) {
                                         $tabId = abs($tabId);
                                     }
                                 }
                             }
                         }
                         // general case (skinning)
                         $tabsFinal[$tabId][1][] = array_merge($srcData[$srcObj->id], $result[$srcObj->getField($field)]);
                         $tabsFinal[$tabId][4][] = 'Listview.extraCols.percent';
                     }
                 }
                 break;
         }
     }
     $this->results = $tabsFinal;
     return true;
 }
コード例 #10
0
ファイル: event.php プロジェクト: TrinityCore/aowow
 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'])];
         }
     }
 }
コード例 #11
0
ファイル: item.php プロジェクト: Carbenium/aowow
 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') . '&nbsp;([tooltip=tooltip_reqenchanting]' . $_ . '[/tooltip])';
         } else {
             $infobox[] = Lang::item('cantDisenchant');
         }
     }
     if ($_flags & ITEM_FLAG_MILLABLE && $this->subject->getField('requiredSkill') == 773) {
         $infobox[] = Lang::item('millable') . '&nbsp;([tooltip=tooltip_reqinscription]' . $this->subject->getField('requiredSkillRank') . '[/tooltip])';
     }
     if ($_flags & ITEM_FLAG_PROSPECTABLE && $this->subject->getField('requiredSkill') == 755) {
         $infobox[] = Lang::item('prospectable') . '&nbsp;([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
 }
コード例 #12
0
ファイル: quest.class.php プロジェクト: saqar/aowow
 public function renderTooltip()
 {
     if (!$this->curTpl) {
         return null;
     }
     $title = Util::jsEscape($this->getField('name', true));
     $level = $this->curTpl['level'];
     if ($level < 0) {
         $level = 0;
     }
     $x = '';
     if ($level) {
         $level = sprintf(Lang::quest('questLevel'), $level);
         if ($this->curTpl['flags'] & QUEST_FLAG_DAILY) {
             // daily
             $level .= ' ' . Lang::quest('daily');
         }
         $x .= '<table><tr><td><table width="100%"><tr><td><b class="q">' . $title . '</b></td><th><b class="q0">' . $level . '</b></th></tr></table></td></tr></table>';
     } else {
         $x .= '<table><tr><td><b class="q">' . $title . '</b></td></tr></table>';
     }
     $x .= '<table><tr><td><br />' . $this->parseText('objectives');
     $xReq = '';
     for ($i = 1; $i < 5; $i++) {
         $ot = $this->getField('objectiveText' . $i, true);
         $rng = $this->curTpl['reqNpcOrGo' . $i];
         $rngQty = $this->curTpl['reqNpcOrGoCount' . $i];
         if ($rngQty < 1 && (!$rng || $ot)) {
             continue;
         }
         if ($ot) {
             $name = $ot;
         } else {
             $name = $rng > 0 ? CreatureList::getName($rng) : GameObjectList::getName(-$rng);
         }
         $xReq .= '<br /> - ' . Util::jsEscape($name) . ($rngQty > 1 ? ' x ' . $rngQty : null);
     }
     for ($i = 1; $i < 7; $i++) {
         $ri = $this->curTpl['reqItemId' . $i];
         $riQty = $this->curTpl['reqItemCount' . $i];
         if (!$ri || $riQty < 1) {
             continue;
         }
         $xReq .= '<br /> - ' . Util::jsEscape(ItemList::getName($ri)) . ($riQty > 1 ? ' x ' . $riQty : null);
     }
     if ($et = $this->getField('end', true)) {
         $xReq .= '<br /> - ' . Util::jsEscape($et);
     }
     if ($_ = $this->getField('rewardOrReqMoney')) {
         if ($_ < 0) {
             $xReq .= '<br /> - ' . Lang::quest('money') . Lang::main('colon') . Util::formatMoney(abs($_));
         }
     }
     if ($xReq) {
         $x .= '<br /><br /><span class="q">' . Lang::quest('requirements') . Lang::main('colon') . '</span>' . $xReq;
     }
     $x .= '</td></tr></table>';
     return $x;
 }
コード例 #13
0
ファイル: zone.php プロジェクト: saqar/aowow
 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));
     }
 }