typeId = intVal($id); $this->contribute = Type::getClassAttrib($this->type, 'contribute') ?? CONTRIBUTE_NONE; } protected function generate() : void { $this->subject = new SkillList(array(['id', $this->typeId])); if ($this->subject->error) $this->generateNotFound(Lang::game('skill'), Lang::skill('notFound')); $this->h1 = $this->subject->getField('name', true); $this->gPageInfo += array( 'type' => $this->type, 'typeId' => $this->typeId, 'name' => $this->h1 ); $_cat = $this->subject->getField('typeCat'); /*************/ /* Menu Path */ /*************/ if (in_array($this->typeId, SKILLS_TRADE_PRIMARY) || in_array($this->typeId, SKILLS_TRADE_SECONDARY)) $this->breadcrumb[] = $this->typeId; else $this->breadcrumb[] = $_cat; /**************/ /* Page Title */ /**************/ array_unshift($this->title, $this->h1, Util::ucFirst(Lang::game('skill'))); /***********/ /* Infobox */ /***********/ $infobox = Lang::getInfoBoxForFlags($this->subject->getField('cuFlags')); // icon if ($_ = $this->subject->getField('iconId')) { $infobox[] = Util::ucFirst(Lang::game('icon')).Lang::main('colon').'[icondb='.$_.' name=true]'; $this->extendGlobalIds(Type::ICON, $_); } if ($infobox) $this->infobox = new InfoboxMarkup($infobox, ['allow' => Markup::CLASS_STAFF, 'dbpage' => true], 'infobox-contents0'); /****************/ /* Main Content */ /****************/ $this->headIcons = [$this->subject->getField('iconString')]; $this->redButtons = array( BUTTON_WOWHEAD => true, BUTTON_LINKS => ['type' => $this->type, 'typeId' => $this->typeId] ); if ($_ = $this->subject->getField('description', true)) $this->extraText = new Markup($_, ['dbpage' => true, 'allow' => Markup::CLASS_ADMIN], 'text-generic'); /**************/ /* Extra Tabs */ /**************/ parent::generate(); $this->lvTabs = new Tabs(['parent' => "\$\$WH.ge('tabs-generic')"], 'tabsRelated', true); if (in_array($_cat, [-5, 9, 11])) { // tab: recipes [spells] (crafted) $condition = array( ['OR', ['s.reagent1', 0, '>'], ['s.reagent2', 0, '>'], ['s.reagent3', 0, '>'], ['s.reagent4', 0, '>'], ['s.reagent5', 0, '>'], ['s.reagent6', 0, '>'], ['s.reagent7', 0, '>'], ['s.reagent8', 0, '>']], ['OR', ['s.skillLine1', $this->typeId], ['AND', ['s.skillLine1', 0, '>'], ['s.skillLine2OrMask', $this->typeId]]], Cfg::get('SQL_LIMIT_NONE') ); $recipes = new SpellList($condition); // also relevant for 3 if (!$recipes->error) { $this->extendGlobalData($recipes->getJSGlobals(GLOBALINFO_SELF | GLOBALINFO_RELATED)); $this->lvTabs->addListviewTab(new Listview(array( 'data' => $recipes->getListviewData(), 'id' => 'recipes', 'name' => '$LANG.tab_recipes', 'visibleCols' => ['reagents', 'source'], 'note' => sprintf(Util::$filterResultString, '?spells='.$_cat.'.'.$this->typeId.'&filter=cr=20;crs=1;crv=0') ), SpellList::$brickFile)); } // tab: recipe Items [items] (Books) $filterRecipe = [null, SKILL_LEATHERWORKING, SKILL_TAILORING, SKILL_ENGINEERING, SKILL_BLACKSMITHING, SKILL_COOKING, SKILL_ALCHEMY, SKILL_FIRST_AID, SKILL_ENCHANTING, SKILL_FISHING, SKILL_JEWELCRAFTING, SKILL_INSCRIPTION, SKILL_MINING, SKILL_HERBALISM]; $conditions = array( ['requiredSkill', $this->typeId], ['class', ITEM_CLASS_RECIPE], Cfg::get('SQL_LIMIT_NONE') ); $recipeItems = new ItemList($conditions); if (!$recipeItems->error) { $this->extendGlobalData($recipeItems->getJSGlobals(GLOBALINFO_SELF)); $tabData = array( 'data' => $recipeItems->getListviewData(), 'id' => 'recipe-items', 'name' => '$LANG.tab_recipeitems', ); if ($_ = array_search($this->typeId, $filterRecipe)) $tabData['note'] = sprintf(Util::$filterResultString, "?items=9.".$_); $this->lvTabs->addListviewTab(new Listview($tabData, ItemList::$brickFile)); } // tab: crafted items [items] $created = []; foreach ($recipes->iterate() as $__) if ($idx = $recipes->canCreateItem()) foreach ($idx as $i) $created[] = $recipes->getField('effect'.$i.'CreateItemId'); if ($created) { $created = new ItemList(array(['i.id', $created], Cfg::get('SQL_LIMIT_NONE'))); if (!$created->error) { $this->extendGlobalData($created->getJSGlobals(GLOBALINFO_SELF)); $tabData = array( 'data' => $created->getListviewData(), 'id' => 'crafted-items', 'name' => '$LANG.tab_crafteditems', ); if (!is_null($_ = ItemListFilter::getCriteriaIndex(86, $this->typeId))) $tabData['note'] = sprintf(Util::$filterResultString, "?items&filter=cr=86;crs=".$_.";crv=0"); $this->lvTabs->addListviewTab(new Listview($tabData, ItemList::$brickFile)); } } // tab: required by [item] $conditions = array( ['requiredSkill', $this->typeId], ['class', ITEM_CLASS_RECIPE, '!'], Cfg::get('SQL_LIMIT_NONE') ); $reqBy = new ItemList($conditions); if (!$reqBy->error) { $this->extendGlobalData($reqBy->getJSGlobals(GLOBALINFO_SELF)); $tabData = array( 'data' => $reqBy->getListviewData(), 'id' => 'required-by', 'name' => '$LANG.tab_requiredby', ); if (!is_null($_ = ItemListFilter::getCriteriaIndex(99, $this->typeId))) $tabData['note'] = sprintf(Util::$filterResultString, "?items&filter=cr=99:168;crs=".$_.":2;crv=0:0"); $this->lvTabs->addListviewTab(new Listview($tabData, ItemList::$brickFile)); } // tab: required by [itemset] $conditions = array( ['skillId', $this->typeId], Cfg::get('SQL_LIMIT_NONE') ); $reqBy = new ItemsetList($conditions); if (!$reqBy->error) { $this->extendGlobalData($reqBy->getJSGlobals(GLOBALINFO_SELF)); $this->lvTabs->addListviewTab(new Listview(array( 'data' => $reqBy->getListviewData(), 'id' => 'required-by-set', 'name' => '$LANG.tab_requiredby' ), ItemsetList::$brickFile)); } } // tab: spells [spells] (exclude first tab) $reqClass = 0x0; $reqRace = 0x0; $condition = array( ['AND', ['s.reagent1', 0], ['s.reagent2', 0], ['s.reagent3', 0], ['s.reagent4', 0], ['s.reagent5', 0], ['s.reagent6', 0], ['s.reagent7', 0], ['s.reagent8', 0]], ['OR', ['s.skillLine1', $this->typeId], ['AND', ['s.skillLine1', 0, '>'], ['s.skillLine2OrMask', $this->typeId]]], Cfg::get('SQL_LIMIT_NONE') ); foreach (Game::$skillLineMask as $line1 => $sets) foreach ($sets as $idx => [, $skillLineId]) if ($skillLineId == $this->typeId) { $condition[1][] = array('AND', ['s.skillLine1', $line1], ['s.skillLine2OrMask', 1 << $idx, '&']); break 2; } $spells = new SpellList($condition); if (!$spells->error) { foreach ($spells->iterate() as $__) { $reqClass |= $spells->getField('reqClassMask'); $reqRace |= $spells->getField('reqRaceMask'); } $this->extendGlobalData($spells->getJSGlobals(GLOBALINFO_SELF)); $tabData = array( 'data' => $spells->getListviewData(), 'visibleCols' => ['source'] ); if ($this->typeId != 769) // Internal $tabData['note'] = match ($_cat) { -4, 7 => sprintf(Util::$filterResultString, '?spells=-4'), 7 => sprintf(Util::$filterResultString, '?spells='.$_cat.'.'.ChrClass::fromMask($reqClass)[0].'.'.$this->typeId), // doesn't matter what spell; reqClass should be identical for all Class Spells 9, 11 => sprintf(Util::$filterResultString, '?spells='.$_cat.'.'.$this->typeId), default => null }; $this->lvTabs->addListviewTab(new Listview($tabData, SpellList::$brickFile)); } // tab: trainers [npcs] if (in_array($_cat, [-5, 6, 7, 8, 9, 11])) { $mask = 0; foreach (Game::$skillLineMask[-3] as $idx => [, $skillLineId]) if ($skillLineId == $this->typeId) $mask |= 1 << $idx; $spellIds = DB::Aowow()->selectCol( 'SELECT `id` FROM ?_spell WHERE (`skillLine1` = ?d OR (`skillLine1` > 0 AND `skillLine2OrMask` = ?d) {OR (`skillLine1` = -3 AND `skillLine2OrMask` = ?d)})', $this->typeId, $this->typeId, $mask ?: DBSIMPLE_SKIP ); $list = $spellIds ? DB::World()->selectCol('SELECT cdt.`CreatureId` FROM creature_default_trainer cdt JOIN trainer_spell ts ON ts.`TrainerId` = cdt.`TrainerId` WHERE ts.`SpellID` IN (?a)', $spellIds) : []; if ($list) { $trainer = new CreatureList(array(Cfg::get('SQL_LIMIT_NONE'), ['ct.id', $list], ['s.guid', NULL, '!'], ['ct.npcflag', 0x10, '&'])); if (!$trainer->error) { $this->extendGlobalData($trainer->getJSGlobals()); $this->addDataLoader('zones'); $this->lvTabs->addListviewTab(new Listview(array( 'data' => $trainer->getListviewData(), 'id' => 'trainer', 'name' => '$LANG.tab_trainers', ), CreatureList::$brickFile)); } } } // tab: quests [quests] // only for professions $sort = match ($this->typeId) { SKILL_HERBALISM => 24, SKILL_FISHING => 101, SKILL_BLACKSMITHING => 121, SKILL_ALCHEMY => 181, SKILL_LEATHERWORKING => 182, SKILL_ENGINEERING => 201, SKILL_TAILORING => 264, SKILL_COOKING => 304, SKILL_FIRST_AID => 324, SKILL_INSCRIPTION => 371, SKILL_JEWELCRAFTING => 373, default => 0 }; if ($sort) { $quests = new QuestList(array(['zoneOrSort', -$sort], Cfg::get('SQL_LIMIT_NONE'))); if (!$quests->error) { $this->extendGlobalData($quests->getJSGlobals()); $this->lvTabs->addListviewTab(new Listview(['data' => $quests->getListviewData()], QuestList::$brickFile)); } } // tab: related classes (apply classes from [spells]) if ($class = ChrClass::fromMask($reqClass)) { $classes = new CharClassList(array(['id', $class])); if (!$classes->error) $this->lvTabs->addListviewTab(new Listview(['data' => $classes->getListviewData()], CharClassList::$brickFile)); } // tab: related races (apply races from [spells]) if ($race = ChrRace::fromMask($reqRace)) { $races = new CharRaceList(array(['id', $race])); if (!$races->error) $this->lvTabs->addListviewTab(new Listview(['data' => $races->getListviewData()], CharRaceList::$brickFile)); } // tab: condition-for $cnd = new Conditions(); $cnd->getByCondition(Type::SKILL, $this->typeId)->prepare(); if ($tab = $cnd->toListviewTab('condition-for', '$LANG.tab_condition_for')) { $this->extendGlobalData($cnd->getJsGlobals()); $this->lvTabs->addDataTab(...$tab); } } } ?>