function events(array $ids = []) { $eventQuery = ' SELECT ge.eventEntry, holiday, 0, -- cuFlags UNIX_TIMESTAMP(start_time), UNIX_TIMESTAMP(end_time), occurence * 60, length * 60, IF (gep.eventEntry IS NOT NULL, GROUP_CONCAT(prerequisite_event SEPARATOR " "), NULL), description FROM game_event ge LEFT JOIN game_event_prerequisite gep ON gep.eventEntry = ge.eventEntry { WHERE ge.eventEntry IN (?a) } GROUP BY ge.eventEntry'; $events = DB::World()->select($eventQuery, $ids ?: DBSIMPLE_SKIP); foreach ($events as $e) { DB::Aowow()->query('REPLACE INTO ?_events VALUES (?a)', array_values($e)); } return true; }
function achievement(array $ids = []) { if ($ids) { DB::Aowow()->query('DELETE FROM ?_achievement WHERE id IN (?a)', $ids); } else { DB::Aowow()->query('REPLACE INTO ?_achievement SELECT a.id, 2 - a.faction, a.map, 0, 0, a.category, ac.parentCategory, a.points, a.orderInGroup, a.iconId, a.flags, a.reqCriteriaCount, a.refAchievement, 0, 0, a.name_loc0, a.name_loc2, a.name_loc3, a.name_loc4, a.name_loc6, a.name_loc8, a.description_loc0, a.description_loc2, a.description_loc3, a.description_loc4, a.description_loc6, a.description_loc8, a.reward_loc0, a.reward_loc2, a.reward_loc3, a.reward_loc4, a.reward_loc6, a.reward_loc8 FROM dbc_achievement a LEFT JOIN dbc_achievement_category ac ON ac.id = a.category'); } // serverside achievements $serverAchievements = DB::World()->select('SELECT ID, IF(requiredFaction = -1, 3, IF(requiredFaction = 0, 2, 1)) AS "faction", mapID, points, flags, count, refAchievement FROM achievement_dbc{ WHERE id IN (?a)}', $ids ?: DBSIMPLE_SKIP); foreach ($serverAchievements as $sa) { DB::Aowow()->query('REPLACE INTO ?_achievement (id, faction, map, points, flags, reqCriteriaCount, refAchievement, cuFlags, name_loc0, name_loc2, name_loc3, name_loc4, name_loc6, name_loc8) VALUES (?d, ?d, ?d, ?d, ?d, ?d, ?d, ?d, ?, ?, ?, ?, ?, ?)', $sa['ID'], $sa['faction'], $sa['mapID'], $sa['points'], $sa['flags'], $sa['count'], $sa['refAchievement'], CUSTOM_SERVERSIDE, 'Serverside - #' . $sa['ID'], 'Serverside - #' . $sa['ID'], 'Serverside - #' . $sa['ID'], 'Serverside - #' . $sa['ID'], 'Serverside - #' . $sa['ID'], 'Serverside - #' . $sa['ID']); } if ($ids) { return true; } // create chain of achievements $chainIdx = 0; $parents = DB::Aowow()->selectCol('SELECT a.id FROM dbc_achievement a JOIN dbc_achievement b ON b.previous = a.id WHERE a.previous = 0'); foreach ($parents as $chainId => $next) { $tree = [null, $next]; while ($next = DB::Aowow()->selectCell('SELECT id FROM dbc_achievement WHERE previous = ?d', $next)) { $tree[] = $next; } foreach ($tree as $idx => $aId) { if (!$aId) { continue; } DB::Aowow()->query('UPDATE ?_achievement SET cuFlags = cuFlags | ?d, chainId = ?d, chainPos = ?d WHERE id = ?d', $idx == 1 ? ACHIEVEMENT_CU_FIRST_SERIES : (count($tree) == $idx + 1 ? ACHIEVEMENT_CU_LAST_SERIES : 0), $chainId + 1, $idx, $aId); } } return true; }
function titles() { $questQuery = ' SELECT qt.RewardTitleId AS ARRAY_KEY, qt.RequiredRaces, ge.holiday FROM quest_template qt LEFT JOIN game_event_seasonal_questrelation sq ON sq.questId = qt.id LEFT JOIN game_event ge ON ge.eventEntry = sq.eventEntry WHERE qt.RewardTitleId <> 0'; DB::Aowow()->query('REPLACE INTO ?_titles SELECT Id, 0, 0, 0, 0, 0, 0, 0, male_loc0, male_loc2, male_loc3, male_loc6, male_loc8, female_loc0, female_loc2, female_loc3, female_loc6, female_loc8 FROM dbc_chartitles'); // hide unused titles DB::Aowow()->query('UPDATE ?_titles SET cuFlags = ?d WHERE id BETWEEN 85 AND 123 AND id NOT IN (113, 120, 121, 122)', CUSTOM_EXCLUDE_FOR_LISTVIEW); // set expansion DB::Aowow()->query('UPDATE ?_titles SET expansion = 2 WHERE id >= 72 AND id <> 80'); DB::Aowow()->query('UPDATE ?_titles SET expansion = 1 WHERE id >= 42 AND id <> 46 AND expansion = 0'); // set category DB::Aowow()->query('UPDATE ?_titles SET category = 1 WHERE id <= 28 OR id IN (42, 43, 44, 45, 47, 48, 62, 71, 72, 80, 82, 126, 127, 128, 157, 163, 167, 169, 177)'); DB::Aowow()->query('UPDATE ?_titles SET category = 5 WHERE id BETWEEN 96 AND 109 OR id IN (83, 84)'); DB::Aowow()->query('UPDATE ?_titles SET category = 2 WHERE id BETWEEN 144 AND 156 OR id IN (63, 77, 79, 113, 123, 130, 131, 132, 176)'); DB::Aowow()->query('UPDATE ?_titles SET category = 6 WHERE id IN (46, 74, 75, 76, 124, 133, 134, 135, 137, 138, 155, 168)'); DB::Aowow()->query('UPDATE ?_titles SET category = 4 WHERE id IN (81, 125)'); DB::Aowow()->query('UPDATE ?_titles SET category = 3 WHERE id IN (53, 64, 120, 121, 122, 129, 139, 140, 141, 142) OR (id >= 158 AND category = 0)'); // update side $questInfo = DB::World()->select($questQuery); $sideUpd = DB::World()->selectCol('SELECT IF (title_A, title_A, title_H) AS ARRAY_KEY, BIT_OR(IF(title_A, 1, 2)) AS side FROM achievement_reward WHERE (title_A <> 0 AND title_H = 0) OR (title_H <> 0 AND title_A = 0) GROUP BY ARRAY_KEY HAVING side <> 3'); foreach ($questInfo as $tId => $data) { if ($data['holiday']) { DB::Aowow()->query('UPDATE ?_titles SET holidayId = ?d WHERE id = ?d', $data['holiday'], $tId); } $side = Util::sideByRaceMask($data['RequiredRaces']); if ($side == 3) { continue; } if (!isset($sideUpd[$tId])) { $sideUpd[$tId] = $side; } else { $sideUpd[$tId] |= $side; } } foreach ($sideUpd as $tId => $side) { if ($side != 3) { DB::Aowow()->query("UPDATE ?_titles SET side = ?d WHERE id = ?d", $side, $tId); } } // update side - sourceless titles (maintain query order) DB::Aowow()->query('UPDATE ?_titles SET side = 2 WHERE id <= 28 OR id IN (118, 119, 116, 117, 110, 127)'); DB::Aowow()->query('UPDATE ?_titles SET side = 1 WHERE id <= 14 OR id IN (111, 115, 112, 114, 126)'); // ! src12Ext pendant in source-script ! $doubles = DB::World()->selectCol('SELECT IF(title_A, title_A, title_H) AS ARRAY_KEY, GROUP_CONCAT(entry SEPARATOR " "), count(1) FROM achievement_reward WHERE title_A <> 0 OR title_H <> 0 GROUP BY ARRAY_KEY HAVING count(1) > 1'); foreach ($doubles as $tId => $acvIds) { DB::Aowow()->query('UPDATE ?_titles SET src12Ext = ?d WHERE id = ?d', explode(' ', $acvIds)[1], $tId); } return true; }
function spelldifficulty(array $ids = []) { // has no unique keys.. DB::Aowow()->query('TRUNCATE TABLE ?_spelldifficulty'); DB::Aowow()->query('INSERT INTO ?_spelldifficulty SELECT * FROM dbc_spelldifficulty'); $rows = DB::World()->select('SELECT spellid0, spellid1, spellid2, spellid3 FROM spelldifficulty_dbc'); foreach ($rows as $r) { DB::Aowow()->query('INSERT INTO ?_spelldifficulty VALUES (?a)', array_values($r)); } return true; }
protected function generateContent() { /***********/ /* Infobox */ /***********/ $infobox = Lang::getInfoBoxForFlags($this->subject->getField('cuFlags')); if ($this->subject->getField('side') == SIDE_ALLIANCE) { $infobox[] = Lang::main('side') . Lang::main('colon') . '[span class=icon-alliance]' . Lang::game('si', SIDE_ALLIANCE) . '[/span]'; } else { if ($this->subject->getField('side') == SIDE_HORDE) { $infobox[] = Lang::main('side') . Lang::main('colon') . '[span class=icon-horde]' . Lang::game('si', SIDE_HORDE) . '[/span]'; } else { $infobox[] = Lang::main('side') . Lang::main('colon') . Lang::game('si', SIDE_BOTH); } } if ($g = $this->subject->getField('gender')) { $infobox[] = Lang::main('gender') . Lang::main('colon') . '[span class=icon-' . ($g == 2 ? 'female' : 'male') . ']' . Lang::main('sex', $g) . '[/span]'; } if ($eId = $this->subject->getField('eventId')) { $this->extendGlobalIds(TYPE_WORLDEVENT, $eId); $infobox[] = Lang::game('eventShort') . Lang::main('colon') . '[event=' . $eId . ']'; } /****************/ /* Main Content */ /****************/ $this->infobox = $infobox ? '[ul][li]' . implode('[/li][li]', $infobox) . '[/li][/ul]' : null; $this->expansion = Util::$expansionString[$this->subject->getField('expansion')]; $this->redButtons = array(BUTTON_WOWHEAD => true, BUTTON_LINKS => ['name' => $this->nameFixed]); // factionchange-equivalent if ($pendant = DB::World()->selectCell('SELECT IF(horde_id = ?d, alliance_id, -horde_id) FROM player_factionchange_titles WHERE alliance_id = ?d OR horde_id = ?d', $this->typeId, $this->typeId, $this->typeId)) { $altTitle = new TitleList(array(['id', abs($pendant)])); if (!$altTitle->error) { $this->transfer = sprintf(Lang::title('_transfer'), $altTitle->id, $altTitle->getHtmlizedName(), $pendant > 0 ? 'alliance' : 'horde', $pendant > 0 ? Lang::game('si', 1) : Lang::game('si', 2)); } } /**************/ /* Extra Tabs */ /**************/ // tab: quest source $quests = new QuestList(array(['rewardTitleId', $this->typeId])); if (!$quests->error) { $this->extendGlobalData($quests->getJSGlobals(GLOBALINFO_REWARDS)); $this->lvTabs[] = ['quest', array('data' => array_values($quests->getListviewData()), 'id' => 'reward-from-quest', 'name' => '$LANG.tab_rewardfrom', 'hiddenCols' => ['experience', 'money'], 'visibleCols' => ['category'])]; } // tab: achievement source if ($aIds = DB::World()->selectCol('SELECT entry FROM achievement_reward WHERE title_A = ?d OR title_H = ?d', $this->typeId, $this->typeId)) { $acvs = new AchievementList(array(['id', $aIds])); if (!$acvs->error) { $this->extendGlobalData($acvs->getJSGlobals()); $this->lvTabs[] = ['achievement', array('data' => array_values($acvs->getListviewData()), 'id' => 'reward-from-achievement', 'name' => '$LANG.tab_rewardfrom', 'visibleCols' => ['category'], 'sort' => ['reqlevel', 'name'])]; } } // tab: criteria of (to be added by TC) }
public function __construct($conditions = [], $miscData = null) { parent::__construct($conditions, $miscData); if ($this->error) { return; } // post processing $rewards = DB::World()->select(' SELECT ar.entry AS ARRAY_KEY, ar.*, lar.* FROM achievement_reward ar LEFT JOIN locales_achievement_reward lar ON lar.entry = ar.entry WHERE ar.entry IN (?a)', $this->getFoundIDs()); foreach ($this->iterate() as $_id => &$_curTpl) { $_curTpl['rewards'] = []; if (!empty($rewards[$_id])) { $_curTpl = array_merge($rewards[$_id], $_curTpl); if ($rewards[$_id]['mailTemplate']) { // using class Loot creates an inifinite loop cirling between Loot, ItemList and SpellList or something // $mailSrc = new Loot(); // $mailSrc->getByContainer(LOOT_MAIL, $rewards[$_id]['mailTemplate']); // foreach ($mailSrc->iterate() as $loot) // $_curTpl['rewards'][] = [TYPE_ITEM, $loot['id']]; // lets just assume for now, that mailRewards for achievements do not contain references $mailRew = DB::World()->selectCol('SELECT Item FROM mail_loot_template WHERE Reference <= 0 AND entry = ?d', $rewards[$_id]['mailTemplate']); foreach ($mailRew as $mr) { $_curTpl['rewards'][] = [TYPE_ITEM, $mr]; } } } //"rewards":[[11,137],[3,138]] [type, typeId] if (!empty($_curTpl['item'])) { $_curTpl['rewards'][] = [TYPE_ITEM, $_curTpl['item']]; } if (!empty($_curTpl['itemExtra'])) { $_curTpl['rewards'][] = [TYPE_ITEM, $_curTpl['itemExtra']]; } if (!empty($_curTpl['title_A'])) { $_curTpl['rewards'][] = [TYPE_TITLE, $_curTpl['title_A']]; } if (!empty($_curTpl['title_H'])) { if (empty($_curTpl['title_A']) || $_curTpl['title_A'] != $_curTpl['title_H']) { $_curTpl['rewards'][] = [TYPE_TITLE, $_curTpl['title_H']]; } } // icon $_curTpl['iconString'] = $_curTpl['iconString'] ?: 'trade_engineering'; } }
private static function PerformItemsSearch() { if (!isset(self::$m_results['items'])) { self::$m_results['items'] = array(); } // Find item IDs $items = DB::World()->select("\n SELECT\n `a`.`entry`\n FROM `%s` AS `a`\n WHERE %s LIKE '%s' LIMIT 200", WoW_Locale::GetLocaleID() != LOCALE_EN ? 'locales_item' : 'item_template', WoW_Locale::GetLocaleID() != LOCALE_EN ? '`a`.`name_loc' . WoW_Locale::GetLocaleID() . '`' : '`a`.`name`', '%' . self::$m_query . '%'); if (!$items) { return; } $item_id = array(); foreach ($items as $item) { // Generate IDs array $item_id[] = $item['entry']; } // Request items self::$m_results['items'] = WoW_Items::GetExtendedItemInfo($item_id); }
function itemenchantment() { $baseQuery = ' REPLACE INTO ?_itemenchantment SELECT Id, charges, 0, 0, 0, type1, type2, type3, amount1, amount2, amount3, object1, object2, object3, name_loc0, name_loc2, name_loc3, name_loc6, name_loc8, conditionId, skillLine, skillLevel, requiredLevel FROM dbc_spellitemenchantment'; DB::Aowow()->query($baseQuery); $cuProcs = DB::World()->select('SELECT entry AS ARRAY_KEY, customChance AS procChance, PPMChance AS ppmRate FROM spell_enchant_proc_data'); foreach ($cuProcs as $id => $vals) { DB::Aowow()->query('UPDATE ?_itemenchantment SET ?a WHERE id = ?d', $vals, $id); } // hide strange stuff DB::Aowow()->query('UPDATE ?_itemenchantment SET cuFlags = ?d WHERE type1 = 0 AND type2 = 0 AND type3 = 0', CUSTOM_EXCLUDE_FOR_LISTVIEW); DB::Aowow()->query('UPDATE ?_itemenchantment SET cuFlags = ?d WHERE name_loc0 LIKE "%test%"', CUSTOM_EXCLUDE_FOR_LISTVIEW); return true; }
function quests_startend() { $query['creature'] = ' SELECT 1 AS type, id AS typeId, quest AS questId, 1 AS method, 0 AS eventId FROM creature_queststarter UNION SELECT 1 AS type, id AS typeId, quest AS questId, 2 AS method, 0 AS eventId FROM creature_questender UNION SELECT 1 AS type, id AS typeId, quest AS questId, 1 AS method, eventEntry AS eventId FROM game_event_creature_quest'; $query['object'] = ' SELECT 2 AS type, id AS typeId, quest AS questId, 1 AS method, 0 AS eventId FROM gameobject_queststarter UNION SELECT 2 AS type, id AS typeId, quest AS questId, 2 AS method, 0 AS eventId FROM gameobject_questender UNION SELECT 2 AS type, id AS typeId, quest AS questId, 1 AS method, eventEntry AS eventId FROM game_event_gameobject_quest'; $query['item'] = 'SELECT 3 AS type, entry AS typeId, startquest AS questId, 1 AS method, 0 AS eventId FROM item_template WHERE startquest <> 0'; // always rebuild this table from scratch // or how would i know what to fetch specifically DB::Aowow()->query('TRUNCATE TABLE ?_quests_startend'); foreach ($query as $q) { $data = DB::World()->select($q); foreach ($data as $d) { DB::Aowow()->query('INSERT INTO ?_quests_startend (?#) VALUES (?a) ON DUPLICATE KEY UPDATE method = method | VALUES(method), eventId = IF(eventId = 0, VALUES(eventId), eventId)', array_keys($d), array_values($d)); } } return true; }
function currencies(array $ids = []) { if (!$ids) { DB::Aowow()->query('REPLACE INTO ?_currencies (id, category, itemId) SELECT Id, category, itemId FROM dbc_currencytypes'); } $moneyItems = DB::Aowow()->selectCol('SELECT id AS ARRAY_KEY, itemId FROM dbc_currencytypes{ WHERE id IN (?a)}', $ids ?: DBSIMPLE_SKIP); // apply names $moneyNames = DB::World()->select('SELECT it.entry AS ARRAY_KEY, name AS name_loc0, name_loc2, name_loc3, name_loc6, name_loc8 FROM item_template it LEFT JOIN locales_item li ON li.entry = it.entry WHERE it.entry IN (?a)', $moneyItems); foreach ($moneyItems as $cId => $itemId) { if (!empty($moneyNames[$itemId])) { $strings = $moneyNames[$itemId]; } else { CLISetup::log('item #' . $itemId . ' required by currency #' . $cId . ' not in item_template', CLISetup::LOG_WARN); $strings = ['name_loc0' => 'Item #' . $itemId . ' not in DB', 'iconId' => -1240, 'cuFlags' => CUSTOM_EXCLUDE_FOR_LISTVIEW, 'category' => 3]; } DB::Aowow()->query('UPDATE ?_currencies SET ?a WHERE itemId = ?d', $strings, $itemId); } // apply icons $displayIds = DB::World()->selectCol('SELECT entry AS ARRAY_KEY, displayid FROM item_template WHERE entry IN (?a)', $moneyItems); foreach ($displayIds as $itemId => $iconId) { DB::Aowow()->query('UPDATE ?_currencies SET iconId = ?d WHERE itemId = ?d', -$iconId, $itemId); } return true; }
private function createEffects(&$infobox, &$redButtons) { // proc data .. maybe use more information..? $procData = DB::World()->selectRow('SELECT IF(ppmRate > 0, -ppmRate, customChance) AS chance, cooldown FROM spell_proc_event WHERE entry = ?d', $this->typeId); if (!isset($procData['cooldown'])) { $procData['cooldown'] = 0; } $effects = []; $spellIdx = array_unique(array_merge($this->subject->canTriggerSpell(), $this->subject->canTeachSpell())); $itemIdx = $this->subject->canCreateItem(); // Iterate through all effects: for ($i = 1; $i < 4; $i++) { if ($this->subject->getField('effect' . $i . 'Id') <= 0) { continue; } $effId = (int) $this->subject->getField('effect' . $i . 'Id'); $effMV = (int) $this->subject->getField('effect' . $i . 'MiscValue'); $effBP = (int) $this->subject->getField('effect' . $i . 'BasePoints'); $effDS = (int) $this->subject->getField('effect' . $i . 'DieSides'); $effRPPL = $this->subject->getField('effect' . $i . 'RealPointsPerLevel'); $effAura = (int) $this->subject->getField('effect' . $i . 'AuraId'); $foo =& $effects[]; // Icons: // .. from item if (in_array($i, $itemIdx)) { $_ = $this->subject->getField('effect' . $i . 'CreateItemId'); foreach ($this->subject->relItems->iterate() as $itemId => $__) { if ($itemId != $_) { continue; } $foo['icon'] = array('id' => $this->subject->relItems->id, 'name' => $this->subject->relItems->getField('name', true), 'quality' => $this->subject->relItems->getField('quality'), 'count' => $effDS + $effBP, 'icon' => $this->subject->relItems->getField('iconString')); break; } if ($effDS > 1) { $foo['icon']['count'] = "'" . ($effBP + 1) . '-' . $foo['icon']['count'] . "'"; } } else { if (in_array($i, $spellIdx) || $effId == 133) { $_ = $this->subject->getField('effect' . $i . 'TriggerSpell'); if (!$_) { $_ = $this->subject->getField('effect' . $i . 'MiscValue'); } $trig = new SpellList(array(['s.id', (int) $_])); $foo['icon'] = array('id' => $_, 'name' => $trig->error ? Util::ucFirst(Lang::game('spell')) . ' #' . $_ : $trig->getField('name', true), 'count' => 0); $this->extendGlobalData($trig->getJSGlobals(GLOBALINFO_SELF | GLOBALINFO_RELATED)); } } // Effect Name $foo['name'] = (User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, 'EffectId: ' . $effId, Util::$spellEffectStrings[$effId]) : Util::$spellEffectStrings[$effId]) . Lang::main('colon'); if ($this->subject->getField('effect' . $i . 'RadiusMax') > 0) { $foo['radius'] = $this->subject->getField('effect' . $i . 'RadiusMax'); } if (!in_array($i, $itemIdx) && !in_array($i, $spellIdx) && !in_array($effAura, [225, 227])) { $foo['value'] = ($effDS && $effDS != 1 ? $effBP + 1 . Lang::game('valueDelim') : null) . ($effBP + $effDS); } if ($effRPPL != 0) { $foo['value'] = (isset($foo['value']) ? $foo['value'] : '0') . sprintf(Lang::spell('costPerLevel'), $effRPPL); } if ($this->subject->getField('effect' . $i . 'Periode') > 0) { $foo['interval'] = Util::formatTime($this->subject->getField('effect' . $i . 'Periode')); } if ($_ = $this->subject->getField('effect' . $i . 'Mechanic')) { $foo['mechanic'] = Lang::game('me', $_); } if (!empty($procData['chance'])) { $foo['procData'] = array($procData['chance'], $procData['cooldown'] ? Util::formatTime($procData['cooldown'] * 1000, true) : null); } else { if (in_array($i, $this->subject->canTriggerSpell()) && $this->subject->getField('procChance')) { $foo['procData'] = array($this->subject->getField('procChance'), $procData['cooldown'] ? Util::formatTime($procData['cooldown'] * 1000, true) : null); } } // parse masks and indizes switch ($effId) { case 8: // Power Drain // Power Drain case 30: // Energize // Energize case 137: // Energize Pct $_ = Lang::spell('powerTypes', $effMV); if ($_ && User::isInGroup(U_GROUP_EMPLOYEE)) { $_ = sprintf(Util::$dfnString, Lang::spell('_value') . Lang::main('colon') . $effMV, $_); } else { if (!$_) { $_ = $effMV; } } if ($effMV == POWER_RAGE || $effMV == POWER_RUNIC_POWER) { $foo['value'] = ($effDS && $effDS != 1 ? ($effBP + 1) / 10 . Lang::game('valueDelim') : null) . ($effBP + $effDS) / 10; } $foo['name'] .= ' (' . $_ . ')'; break; case 16: // QuestComplete if ($_ = QuestList::getName($effMV)) { $foo['name'] .= '(<a href="?quest=' . $effMV . '">' . $_ . '</a>)'; } else { $foo['name'] .= Util::ucFirst(Lang::game('quest')) . ' #' . $effMV; } break; case 28: // Summon // Summon case 90: // Kill Credit // Kill Credit case 134: // Kill Credit2 $_ = Lang::game('npc') . ' #' . $effMV; if ($summon = $this->subject->getModelInfo($this->typeId, $i)) { $_ = $summon['typeId'] ? ' (<a href="?npc=' . $summon['typeId'] . '">' . $summon['displayName'] . '</a>)' : ' (#0)'; $redButtons[BUTTON_VIEW3D] = ['type' => TYPE_NPC, 'displayId' => $summon['displayId']]; } $foo['name'] .= $_; break; case 33: // Open Lock $_ = $effMV ? Lang::spell('lockType', $effMV) : $effMV; if ($_ && User::isInGroup(U_GROUP_EMPLOYEE)) { $_ = sprintf(Util::$dfnString, Lang::spell('_value') . Lang::main('colon') . $effMV, $_); } else { if (!$_) { $_ = $effMV; } } $foo['name'] .= ' (' . $_ . ')'; break; case 53: // Enchant Item Perm // Enchant Item Perm case 54: // Enchant Item Temp // Enchant Item Temp case 92: // Enchant Held Item // Enchant Held Item case 156: // Enchant Item Prismatic if ($_ = DB::Aowow()->selectRow('SELECT * FROM ?_itemenchantment WHERE id = ?d', $effMV)) { $foo['name'] .= ' (<a href="?enchantment=' . $effMV . '" class="q2">' . Util::localizedString($_, 'name') . '</a>)'; } else { $foo['name'] .= ' #' . $effMV; } break; case 38: // Dispel [miscValue => Types] // Dispel [miscValue => Types] case 126: // Steal Aura $_ = Lang::game('dt', $effMV); if ($_ && User::isInGroup(U_GROUP_EMPLOYEE)) { $_ = sprintf(Util::$dfnString, Lang::spell('_value') . Lang::main('colon') . $effMV, $_); } else { if (!$_) { $_ = $effMV; } } $foo['name'] .= ' (' . $_ . ')'; break; case 39: // Learn Language $_ = Lang::game('languages', $effMV); if ($_ && User::isInGroup(U_GROUP_EMPLOYEE)) { $_ = sprintf(Util::$dfnString, Lang::spell('_value') . Lang::main('colon') . $effMV, $_); } else { if (!$_) { $_ = $effMV; } } $foo['name'] .= ' (' . $_ . ')'; break; case 50: // Trans Door // Trans Door case 76: // Summon Object (Wild) // case 86: // Activate Object // Summon Object (Wild) // case 86: // Activate Object case 104: // Summon Object (slot 1) // Summon Object (slot 1) case 105: // Summon Object (slot 2) // Summon Object (slot 2) case 106: // Summon Object (slot 3) // Summon Object (slot 3) case 107: // Summon Object (slot 4) $_ = Util::ucFirst(Lang::game('object')) . ' #' . $effMV; if ($summon = $this->subject->getModelInfo($this->typeId, $i)) { $_ = $summon['typeId'] ? ' (<a href="?object=' . $summon['typeId'] . '">' . $summon['displayName'] . '</a>)' : ' (#0)'; $redButtons[BUTTON_VIEW3D] = ['type' => TYPE_OBJECT, 'displayId' => $summon['displayId']]; } $foo['name'] .= $_; break; case 74: // Apply Glyph if ($_ = DB::Aowow()->selectCell('SELECT spellId FROM ?_glyphproperties WHERE id = ?d', $effMV)) { if ($n = SpellList::getName($_)) { $foo['name'] .= '(<a href="?spell=' . $_ . '">' . $n . '</a>)'; } else { $foo['name'] .= Util::ucFirst(Lang::game('spell')) . ' #' . $effMV; } } else { $foo['name'] .= ' #' . $effMV; } break; case 95: // Skinning switch ($effMV) { case 0: $_ = Lang::game('ct', 1) . ', ' . Lang::game('ct', 2); break; // Beast, Dragonkin // Beast, Dragonkin case 1: case 2: $_ = Lang::game('ct', 4); break; // Elemental (nature based, earth based) // Elemental (nature based, earth based) case 3: $_ = Lang::game('ct', 9); break; // Mechanic // Mechanic default: $_ = ''; } if (User::isInGroup(U_GROUP_EMPLOYEE)) { $_ = sprintf(Util::$dfnString, Lang::spell('_value') . Lang::main('colon') . $effMV, $_); } else { $_ = $effMV; } $foo['name'] .= ' (' . $_ . ')'; break; case 108: // Dispel Mechanic $_ = Lang::game('me', $effMV); if ($_ && User::isInGroup(U_GROUP_EMPLOYEE)) { $_ = sprintf(Util::$dfnString, Lang::spell('_value') . Lang::main('colon') . $effMV, $_); } else { if (!$_) { $_ = $effMV; } } $foo['name'] .= ' (' . $_ . ')'; break; case 118: // Require Skill if ($_ = SkillList::getName($effMV)) { $foo['name'] .= '(<a href="?skill=' . $effMV . '">' . $_ . '</a>)'; } else { $foo['name'] .= Util::ucFirst(Lang::game('skill')) . ' #' . $effMV; } break; case 146: // Activate Rune $_ = Lang::spell('powerRunes', $effMV); if ($_ && User::isInGroup(U_GROUP_EMPLOYEE)) { $_ = sprintf(Util::$dfnString, Lang::spell('_value') . Lang::main('colon') . $effMV, $_); } else { if (!$_) { $_ = $effMV; } } $foo['name'] .= ' (' . $_ . ')'; break; case 123: // Send Taxi - effMV is taxiPathId. We only use paths for flightmasters for now, so spell-triggered paths are not in the table // Send Taxi - effMV is taxiPathId. We only use paths for flightmasters for now, so spell-triggered paths are not in the table default: if (($effMV || $effId == 97) && $effId != 155) { $foo['name'] .= ' (' . $effMV . ')'; } // Aura // Aura case 6: // Simple // Simple case 27: // AA Persistent // AA Persistent case 35: // AA Party // AA Party case 65: // AA Raid // AA Raid case 119: // AA Pet // AA Pet case 128: // AA Friend // AA Friend case 129: // AA Enemy // AA Enemy case 143: if ($effAura > 0 && isset(Util::$spellAuraStrings[$effAura])) { $foo['name'] .= User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, 'AuraId: ' . $effAura, Util::$spellAuraStrings[$effAura]) : Util::$spellAuraStrings[$effAura]; $bar = $effMV; switch ($effAura) { case 17: // Mod Stealth Detection if ($_ = Lang::spell('stealthType', $effMV)) { $bar = User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, Lang::spell('_value') . Lang::main('colon') . $effMV, $_) : $_; } break; case 19: // Mod Invisibility Detection if ($_ = Lang::spell('invisibilityType', $effMV)) { $bar = User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, Lang::spell('_value') . Lang::main('colon') . $effMV, $_) : $_; } break; case 24: // Periodic Energize // Periodic Energize case 21: // Obsolete Mod Power // Obsolete Mod Power case 35: // Mod Increase Power // Mod Increase Power case 85: // Mod Power Regeneration // Mod Power Regeneration case 110: // Mod Power Regeneration Pct if ($_ = Lang::spell('powerTypes', $effMV)) { $bar = User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, Lang::spell('_value') . Lang::main('colon') . $effMV, $_) : $_; } break; case 29: // Mod Stat // Mod Stat case 80: // Mod Stat % // Mod Stat % case 137: // Mod Total Stat % // Mod Total Stat % case 175: // Mod Spell Healing Of Stat Percent // Mod Spell Healing Of Stat Percent case 212: // Mod Ranged Attack Power Of Stat Percent // Mod Ranged Attack Power Of Stat Percent case 219: // Mod Mana Regeneration from Stat // Mod Mana Regeneration from Stat case 268: // Mod Attack Power Of Stat Percent $mask = $effMV == -1 ? 0x1f : 1 << $effMV; $_ = []; for ($j = 0; $j < 5; $j++) { if ($mask & 1 << $j) { $_[] = Lang::game('stats', $j); } } if ($_ = implode(', ', $_)) { } $bar = User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, Lang::spell('_value') . Lang::main('colon') . $effMV, $_) : $_; break; case 36: // Shapeshift if ($st = $this->subject->getModelInfo($this->typeId, $i)) { $redButtons[BUTTON_VIEW3D] = array('type' => TYPE_NPC, 'displayId' => $st['displayId']); if ($st['creatureType'] > 0) { $infobox[] = Lang::game('type') . Lang::main('colon') . Lang::game('ct', $st['creatureType']); } if ($_ = $st['displayName']) { $bar = User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, Lang::spell('_value') . Lang::main('colon') . $effMV, $_) : $_; } } break; case 37: // Effect immunity if (isset(Util::$spellEffectStrings[$effMV])) { $_ = Util::$spellEffectStrings[$effMV]; $bar = User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, Lang::spell('_value') . Lang::main('colon') . $effMV, $_) : $_; } break; case 38: // Aura immunity if (isset(Util::$spellAuraStrings[$effMV])) { $_ = Util::$spellAuraStrings[$effMV]; $bar = User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, Lang::spell('_value') . Lang::main('colon') . $effMV, $_) : $_; } break; case 41: // Dispel Immunity // Dispel Immunity case 178: // Mod Debuff Resistance // Mod Debuff Resistance case 245: // Mod Aura Duration By Dispel if ($_ = Lang::game('dt', $effMV)) { $bar = User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, Lang::spell('_value') . Lang::main('colon') . $effMV, $_) : $_; } break; case 44: // Track Creature if ($_ = Lang::game('ct', $effMV)) { $bar = User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, Lang::spell('_value') . Lang::main('colon') . $effMV, $_) : $_; } break; case 45: // Track Resource if ($_ = Lang::spell('lockType', $effMV)) { $bar = User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, Lang::spell('_value') . Lang::main('colon') . $effMV, $_) : $_; } break; case 75: // Language if ($_ = Lang::game('languages', $effMV)) { $bar = User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, Lang::spell('_value') . Lang::main('colon') . $effMV, $_) : $_; } break; case 77: // Mechanic Immunity // Mechanic Immunity case 117: // Mod Mechanic Resistance // Mod Mechanic Resistance case 232: // Mod Mechanic Duration // Mod Mechanic Duration case 234: // Mod Mechanic Duration (no stack) // Mod Mechanic Duration (no stack) case 255: // Mod Mechanic Damage Taken Pct // Mod Mechanic Damage Taken Pct case 276: // Mod Mechanic Damage Done Percent if ($_ = Lang::game('me', $effMV)) { $bar = User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, Lang::spell('_value') . Lang::main('colon') . Util::asHex($effMV), $_) : $_; } break; case 147: // Mechanic Immunity Mask $_ = []; foreach (Lang::game('me') as $k => $str) { if ($effMV & 1 << $k - 1) { $_[] = $str; } } if ($_ = implode(', ', $_)) { $bar = User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, Lang::spell('_value') . Lang::main('colon') . Util::asHex($effMV), $_) : $_; } break; case 10: // Mod Threat // Mod Threat case 13: // Mod Damage Done // Mod Damage Done case 14: // Mod Damage Taken // Mod Damage Taken case 22: // Mod Resistance // Mod Resistance case 39: // School Immunity // School Immunity case 40: // Damage Immunity // Damage Immunity case 50: // Mod Critical Healing Amount // Mod Critical Healing Amount case 57: // Mod Spell Crit Chance // Mod Spell Crit Chance case 69: // School Absorb // School Absorb case 71: // Mod Spell Crit Chance School // Mod Spell Crit Chance School case 72: // Mod Power Cost School Percent // Mod Power Cost School Percent case 73: // Mod Power Cost School Flat // Mod Power Cost School Flat case 74: // Reflect Spell School // Reflect Spell School case 79: // Mod Damage Done Pct // Mod Damage Done Pct case 81: // Split Damage Pct // Split Damage Pct case 83: // Mod Base Resistance // Mod Base Resistance case 87: // Mod Damage Taken Pct // Mod Damage Taken Pct case 97: // Mana Shield // Mana Shield case 101: // Mod Resistance Pct // Mod Resistance Pct case 115: // Mod Healing Taken // Mod Healing Taken case 118: // Mod Healing Taken Pct // Mod Healing Taken Pct case 123: // Mod Target Resistance // Mod Target Resistance case 135: // Mod Healing Done // Mod Healing Done case 136: // Mod Healing Done Pct // Mod Healing Done Pct case 142: // Mod Base Resistance Pct // Mod Base Resistance Pct case 143: // Mod Resistance Exclusive // Mod Resistance Exclusive case 149: // Reduce Pushback // Reduce Pushback case 163: // Mod Crit Damage Bonus // Mod Crit Damage Bonus case 174: // Mod Spell Damage Of Stat Percent // Mod Spell Damage Of Stat Percent case 182: // Mod Resistance Of Stat Percent // Mod Resistance Of Stat Percent case 186: // Mod Attacker Spell Hit Chance // Mod Attacker Spell Hit Chance case 194: // Mod Target Absorb School // Mod Target Absorb School case 195: // Mod Target Ability Absorb School // Mod Target Ability Absorb School case 199: // Mod Increases Spell Percent to Hit // Mod Increases Spell Percent to Hit case 229: // Mod AoE Damage Avoidance // Mod AoE Damage Avoidance case 271: // Mod Damage Percent Taken Form Caster // Mod Damage Percent Taken Form Caster case 310: // Mod Creature AoE Damage Avoidance if ($_ = Lang::getMagicSchools($effMV)) { $bar = User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, Lang::spell('_value') . Lang::main('colon') . Util::asHex($effMV), $_) : $_; } break; case 30: // Mod Skill // Mod Skill case 98: // Mod Skill Value if ($_ = SkillList::getName($effMV)) { $bar = ' (<a href="?skill=' . $effMV . '">' . SkillList::getName($effMV) . '</a>)'; } else { $bar = Lang::main('colon') . Util::ucFirst(Lang::game('skill')) . ' #' . $effMV; } break; case 107: // Flat Modifier // Flat Modifier case 108: // Pct Modifier if ($_ = Lang::spell('spellModOp', $effMV)) { $bar = User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, Lang::spell('_value') . Lang::main('colon') . $effMV, $_) : $_; } break; case 189: // Mod Rating // Mod Rating case 220: // Combat Rating From Stat $_ = []; foreach (Lang::spell('combatRating') as $k => $str) { if (1 << $k & $effMV) { $_[] = $str; } } if ($_ = implode(', ', $_)) { $bar = User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, Lang::spell('_value') . Lang::main('colon') . Util::asHex($effMV), $_) : $_; } break; case 168: // Mod Damage Done Versus // Mod Damage Done Versus case 59: // Mod Damage Done Versus Creature // Mod Damage Done Versus Creature case 102: // Mod Melee Attack Power Versus // Mod Melee Attack Power Versus case 131: // Mod Ranged Attack Power Versus // Mod Ranged Attack Power Versus case 180: // Mod Spell Damage Versus $_ = []; foreach (Lang::game('ct') as $k => $str) { if ($effMV & 1 << $k - 1) { $_[] = $str; } } if ($_ = implode(', ', $_)) { $bar = User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, Lang::spell('_value') . Lang::main('colon') . Util::asHex($effMV), $_) : $_; } break; case 249: // Convert Rune $x = $this->subject->getField('effect' . $i . 'MiscValueB'); if ($_ = Lang::spell('powerRunes', $x)) { $bar = User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, Lang::spell('_value') . Lang::main('colon') . $x, $_) : $_; } break; case 78: // Mounted // Mounted case 56: // Transform if ($transform = $this->subject->getModelInfo($this->typeId, $i)) { $redButtons[BUTTON_VIEW3D] = ['type' => TYPE_NPC, 'displayId' => $transform['displayId']]; $bar = $transform['typeId'] ? ' (<a href="?npc=' . $transform['typeId'] . '">' . $transform['displayName'] . '</a>)' : ' (#0)'; } else { $bar = Lang::main('colon') . Lang::game('npc') . ' #' . $effMV; } break; case 139: // Force Reaction $foo['value'] = sprintf(Util::$dfnString, $foo['value'], Lang::game('rep', $foo['value'])); // DO NOT BREAK // DO NOT BREAK case 190: // Mod Faction Reputation Gain $bar = ' (<a href="?faction=' . $effMV . '">' . FactionList::getName($effMV) . '</a>)'; break; // also breaks for 139 } $foo['name'] .= strstr($bar, 'href') || strstr($bar, '#') ? $bar : ($bar ? ' (' . $bar . ')' : null); if (in_array($effAura, [174, 220, 182])) { $foo['name'] .= ' [' . sprintf(Util::$dfnString, Lang::game('stats', $this->subject->getField('effect' . $i . 'MiscValueB')), $this->subject->getField('effect' . $i . 'MiscValueB')) . ']'; } else { if ($this->subject->getField('effect' . $i . 'MiscValueB') > 0) { $foo['name'] .= ' [' . $this->subject->getField('effect' . $i . 'MiscValueB') . ']'; } } } else { if ($effAura > 0) { $foo['name'] .= Lang::main('colon') . 'Unknown Aura (' . $effAura . ')'; } } break; } // cases where we dont want 'Value' to be displayed if (in_array($effAura, [11, 12, 36, 77]) || in_array($effId, []) || empty($foo['value'])) { unset($foo['value']); } } unset($foo); // clear reference return $effects; }
protected function generateContent() { /****************/ /* Main Content */ /****************/ $this->headIcons = [$this->subject->getField('iconString')]; $this->redButtons = array(BUTTON_WOWHEAD => true, BUTTON_LINKS => true); if ($_ = $this->subject->getField('description', true)) { $this->extraText = $_; } /**************/ /* Extra Tabs */ /**************/ if (in_array($this->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_SQL_LIMIT_NONE); $recipes = new SpellList($condition); // also relevant for 3 if (!$recipes->error) { $this->extendGlobalData($recipes->getJSGlobals(GLOBALINFO_SELF | GLOBALINFO_RELATED)); $this->lvTabs[] = array('file' => 'spell', 'data' => $recipes->getListviewData(), 'params' => array('id' => 'recipes', 'name' => '$LANG.tab_recipes', 'visibleCols' => "\$['reagents', 'source']", 'note' => sprintf(Util::$filterResultString, '?spells=' . $this->cat . '.' . $this->typeId . '&filter=cr=20;crs=1;crv=0'))); } // tab: recipe Items [items] (Books) $filterRecipe = [null, 165, 197, 202, 164, 185, 171, 129, 333, 356, 755, 773, 186, 182]; $conditions = array(['requiredSkill', $this->typeId], ['class', ITEM_CLASS_RECIPE], CFG_SQL_LIMIT_NONE); $recipeItems = new ItemList($conditions); if (!$recipeItems->error) { $this->extendGlobalData($recipeItems->getJSGlobals(GLOBALINFO_SELF)); if ($_ = array_search($this->typeId, $filterRecipe)) { $_ = sprintf(Util::$filterResultString, "?items=9." . $_); } $this->lvTabs[] = array('file' => 'item', 'data' => $recipeItems->getListviewData(), 'params' => array('id' => 'recipe-items', 'name' => '$LANG.tab_recipeitems', 'note' => $_)); } // tab: crafted items [items] $filterItem = [null, 171, 164, 185, 333, 202, 129, 755, 165, 186, 197, null, null, 356, 182, 773]; $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_SQL_LIMIT_NONE)); if (!$created->error) { $this->extendGlobalData($created->getJSGlobals(GLOBALINFO_SELF)); if ($_ = array_search($this->typeId, $filterItem)) { $_ = sprintf(Util::$filterResultString, "?items&filter=cr=86;crs=" . $_ . ";crv=0"); } $this->lvTabs[] = array('file' => 'item', 'data' => $created->getListviewData(), 'params' => array('id' => 'crafted-items', 'name' => '$LANG.tab_crafteditems', 'note' => $_)); } } // tab: required by [item] $conditions = array(['requiredSkill', $this->typeId], ['class', ITEM_CLASS_RECIPE, '!'], CFG_SQL_LIMIT_NONE); $reqBy = new ItemList($conditions); if (!$reqBy->error) { $this->extendGlobalData($reqBy->getJSGlobals(GLOBALINFO_SELF)); if ($_ = array_search($this->typeId, $filterItem)) { $_ = sprintf(Util::$filterResultString, "?items&filter=cr=99:168;crs=" . $_ . ":2;crv=0:0"); } $this->lvTabs[] = array('file' => 'item', 'data' => $reqBy->getListviewData(), 'params' => array('id' => 'required-by', 'name' => '$LANG.tab_requiredby', 'note' => $_)); } // tab: required by [itemset] $conditions = array(['skillId', $this->typeId], CFG_SQL_LIMIT_NONE); $reqBy = new ItemsetList($conditions); if (!$reqBy->error) { $this->extendGlobalData($reqBy->getJSGlobals(GLOBALINFO_SELF)); $this->lvTabs[] = array('file' => 'itemset', 'data' => $reqBy->getListviewData(), 'params' => array('id' => 'required-by-set', 'name' => '$LANG.tab_requiredby')); } } // 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_SQL_LIMIT_NONE); foreach (Util::$skillLineMask as $line1 => $sets) { foreach ($sets as $idx => $set) { if ($set[1] == $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)); $lv = array('file' => 'spell', 'data' => $spells->getListviewData(), 'params' => ['visibleCols' => "\$['source']"]); switch ($this->cat) { case -4: $lv['params']['note'] = sprintf(Util::$filterResultString, '?spells=-4'); break; case 7: if ($this->typeId != 769) { // Internal $lv['params']['note'] = sprintf(Util::$filterResultString, '?spells=' . $this->cat . '.' . (log($reqClass, 2) + 1) . '.' . $this->typeId); } // doesn't matter what spell; reqClass should be identical for all Class Spells break; case 9: case 11: $lv['params']['note'] = sprintf(Util::$filterResultString, '?spells=' . $this->cat . '.' . $this->typeId); break; } $this->lvTabs[] = $lv; } // tab: trainers [npcs] if (in_array($this->cat, [-5, 6, 7, 8, 9, 11])) { $list = []; if (!empty(Util::$trainerTemplates[TYPE_SKILL][$this->typeId])) { $list = DB::World()->selectCol('SELECT DISTINCT entry FROM npc_trainer WHERE spell IN (?a) AND entry < 200000', Util::$trainerTemplates[TYPE_SKILL][$this->typeId]); } else { $mask = 0; foreach (Util::$skillLineMask[-3] as $idx => $pair) { if ($pair[1] == $this->typeId) { $mask |= 1 << $idx; } } $spellIds = DB::Aowow()->selectCol('SELECT id FROM ?_spell WHERE typeCat IN (-11, 9) AND (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 IF(t1.entry > 200000, t2.entry, t1.entry) FROM npc_trainer t1 LEFT JOIN npc_trainer t2 ON t2.spell = -t1.entry WHERE t1.spell IN (?a)', $spellIds) : []; } if ($list) { $this->addJS('?data=zones&locale=' . User::$localeId . '&t=' . $_SESSION['dataKey']); $trainer = new CreatureList(array(CFG_SQL_LIMIT_NONE, ['ct.id', $list], ['s.guid', NULL, '!'], ['ct.npcflag', 0x10, '&'])); if (!$trainer->error) { $this->extendGlobalData($trainer->getJSGlobals()); $this->lvTabs[] = array('file' => 'creature', 'data' => $trainer->getListviewData(), 'params' => array('id' => 'trainer', 'name' => '$LANG.tab_trainers')); } } } // tab: quests [quests] if (in_array($this->cat, [9, 11])) { $sort = 0; switch ($this->typeId) { case 182: $sort = 24; break; // Herbalism // Herbalism case 356: $sort = 101; break; // Fishing // Fishing case 164: $sort = 121; break; // Blacksmithing // Blacksmithing case 171: $sort = 181; break; // Alchemy // Alchemy case 165: $sort = 182; break; // Leatherworking // Leatherworking case 202: $sort = 201; break; // Engineering // Engineering case 197: $sort = 264; break; // Tailoring // Tailoring case 185: $sort = 304; break; // Cooking // Cooking case 129: $sort = 324; break; // First Aid // First Aid case 773: $sort = 371; break; // Inscription // Inscription case 755: $sort = 373; break; // Jewelcrafting } if ($sort) { $quests = new QuestList(array(['zoneOrSort', -$sort], CFG_SQL_LIMIT_NONE)); if (!$quests->error) { $this->extendGlobalData($quests->getJSGlobals()); $this->lvTabs[] = array('file' => 'quest', 'data' => $quests->getListviewData(), 'params' => []); } } } // tab: related classes (apply classes from [spells]) $class = []; for ($i = 0; $i < 11; $i++) { if ($reqClass & 1 << $i) { $class[] = $i + 1; } } if ($class) { $classes = new CharClassList(array(['id', $class])); if (!$classes->error) { $this->lvTabs[] = array('file' => 'class', 'data' => $classes->getListviewData(), 'params' => []); } } // tab: related races (apply races from [spells]) $race = []; for ($i = 0; $i < 12; $i++) { if ($reqRace & 1 << $i) { $race[] = $i + 1; } } if ($race) { $races = new CharRaceList(array(['id', $race])); if (!$races->error) { $this->lvTabs[] = array('file' => 'race', 'data' => $races->getListviewData(), 'params' => []); } } }
function objects(array $ids = []) { $baseQuery = ' SELECT go.entry, `type`, IF(`type` = 2, -2, -- quests 1 IF(`type` = 8 AND Data0 IN (1, 2, 3, 4, 1552), -6, -- tools IF(`type` = 3 AND IFNULL(gqi.ItemId, 0) <> 0, -2, -- quests 2 IF(`type` IN (3, 9, 25), `type`, 0)))), -- regular chests, books, pools 0 AS event, -- linked worldevent displayId, go.name, gtl2.`name` AS name_loc2, gtl3.`name` AS name_loc3, gtl6.`name` AS name_loc6, gtl8.`name` AS name_loc8, faction, flags, 0 AS cuFlags, -- custom Flags IF(`type` IN (3, 25), Data1, 0), -- lootId IF(`type` IN (2, 3, 6, 10, 13, 24, 26), Data0, IF(`type` IN (0, 1), Data1, 0)), -- lockId 0 AS reqSkill, -- reqSkill IF(`type` = 9, Data0, IF(`type` = 10, Data7, 0)), -- pageTextId IF(`type` = 1, Data3, -- linkedTrapIds IF(`type` = 3, Data7, IF(`type` = 10, Data12, IF(`type` = 8, Data2, 0)))), IF(`type` = 5, Data5, -- reqQuest IF(`type` = 3, Data8, IF(`type` = 10, Data1, IF(`type` = 8, Data4, 0)))), IF(`type` = 8, Data0, 0), -- spellFocusId IF(`type` = 10, Data10, -- onUseSpell IF(`type` IN (18, 24), Data1, IF(`type` = 26, Data2, IF(`type` = 22, Data0, 0)))), IF(`type` = 18, Data4, 0), -- onSuccessSpell IF(`type` = 18, Data2, IF(`type` = 24, Data3, 0)), -- auraSpell IF(`type` = 30, Data2, IF(`type` = 24, Data4, IF(`type` = 6, Data3, 0))), -- triggeredSpell IF(`type` = 29, CONCAT_WS(" ", Data14, Data15, Data16, Data17, Data0), -- miscInfo: capturePoint IF(`type` = 3, CONCAT_WS(" ", Data4, Data5, Data2), -- miscInfo: loot v IF(`type` = 25, CONCAT_WS(" ", Data2, Data3, 0), IF(`type` = 23, CONCAT_WS(" ", Data0, Data1, Data2), "")))), -- miscInfo: meetingStone IF(ScriptName <> "", ScriptName, AIName) FROM gameobject_template go LEFT JOIN gameobject_template_locale gtl2 ON go.entry = gtl2.entry AND gtl2.`locale` = "frFR" LEFT JOIN gameobject_template_locale gtl3 ON go.entry = gtl3.entry AND gtl3.`locale` = "deDE" LEFT JOIN gameobject_template_locale gtl6 ON go.entry = gtl6.entry AND gtl6.`locale` = "esES" LEFT JOIN gameobject_template_locale gtl8 ON go.entry = gtl8.entry AND gtl8.`locale` = "ruRU" LEFT JOIN gameobject_questitem gqi ON gqi.GameObjectEntry = go.entry { WHERE go.entry IN (?a) } GROUP BY go.entry LIMIT ?d, ?d'; $updateQuery = ' UPDATE ?_objects o LEFT JOIN dbc_lock l ON l.id = IF(o.`type` = 3, lockId, null) SET typeCat = IF(`type` = 3 AND (l.properties1 = 1 OR l.properties2 = 1), -5, -- footlocker IF(`type` = 3 AND (l.properties1 = 2), -3, -- herb IF(`type` = 3 AND (l.properties1 = 3), -4, typeCat))), -- ore reqSkill = IF(`type` = 3 AND l.properties1 IN (1, 2, 3), IF(l.reqSkill1 > 1, l.reqSkill1, 1), IF(`type` = 3 AND l.properties2 = 1, IF(l.reqSkill2 > 1, l.reqSkill2, 1), 0)) { WHERE o.id IN (?a) }'; $offset = 0; while ($objects = DB::World()->select($baseQuery, $ids ?: DBSIMPLE_SKIP, $offset, SqlGen::$stepSize)) { CLISetup::log(' * sets ' . ($offset + 1) . ' - ' . ($offset + count($objects))); $offset += SqlGen::$stepSize; foreach ($objects as $o) { DB::Aowow()->query('REPLACE INTO ?_objects VALUES (?a)', array_values($o)); } } // apply typeCat and reqSkill depending on locks DB::Aowow()->query($updateQuery, $ids ?: DBSIMPLE_SKIP); return true; }
private static function GetRandomTitle() { $title = DB::World()->selectRow("SELECT `title_en` AS `originalTitle`%s FROM `DBPREFIX_site_titles` ORDER BY RAND() LIMIT 1", WoW_Locale::GetLocaleID() == LOCALE_EN ? null : sprintf(', `title_%s` AS `localizedTitle`', WoW_Locale::GetLocale())); if (!$title) { return false; } if (isset($title['localizedTitle']) && $title['localizedTitle'] != '') { return $title['localizedTitle']; } return $title['originalTitle']; }
function spawns() { $alphaMapCache = []; $alphaMapCheck = function ($areaId, array &$set) use(&$alphaMapCache) { $file = 'setup/generated/alphaMaps/' . $areaId . '.png'; if (!file_exists($file)) { // file does not exist (probably instanced area) return false; } // invalid and corner cases (literally) if (!is_array($set) || empty($set['posX']) || empty($set['posY']) || $set['posX'] >= 100 || $set['posY'] >= 100) { $set = null; return true; } if (empty($alphaMapCache[$areaId])) { $alphaMapCache[$areaId] = imagecreatefrompng($file); } // alphaMaps are 1000 x 1000, adapt points [black => valid point] if (!imagecolorat($alphaMapCache[$areaId], $set['posX'] * 10, $set['posY'] * 10)) { $set = null; } return true; }; $checkCoords = function ($points) use($alphaMapCheck) { $result = []; $capitals = array(1497, 1637, 1638, 3487, 1519, 1537, 1657, 3557, 3703, 4395); foreach ($points as $res) { if ($alphaMapCheck($res['areaId'], $res)) { if (!$res) { continue; } // some rough measure how central the spawn is on the map (the lower the number, the better) // 0: perfect center; 1: touches a border $q = abs(($res['posX'] - 50) / 50 * (($res['posY'] - 50) / 50)); if (empty($result) || $result[0] > $q) { $result = [$q, $res]; } } else { if (in_array($res['areaId'], $capitals)) { // capitals (auto-discovered) and no hand-made alphaMap available return $res; } else { if (empty($result)) { // add with lowest quality if alpha map is missing $result = [1.0, $res]; } } } } // spawn does not really match on a map, but we need at least one result if (!$result) { usort($points, function ($a, $b) { return $a['quality'] < $b['quality'] ? -1 : 1; }); $result = [1.0, $points[0]]; } return $result[1]; }; $query[1] = ['SELECT c.guid, 1 AS "type", c.id AS typeId, c.spawntimesecs AS respawn, c.phaseMask, c.zoneId AS areaId, c.map, IFNULL(ca.path_id, 0) AS pathId, c.position_y AS `posX`, c.position_x AS `posY` ' . 'FROM creature c LEFT JOIN creature_addon ca ON ca.guid = c.guid', ' - assembling ' . CLISetup::bold('creature') . ' spawns']; $query[2] = ['SELECT c.guid, 2 AS "type", c.id AS typeId, ABS(c.spawntimesecs) AS respawn, c.phaseMask, c.zoneId AS areaId, c.map, 0 as pathId, c.position_y AS `posX`, c.position_x AS `posY` ' . 'FROM gameobject c', ' - assembling ' . CLISetup::bold('gameobject') . ' spawns']; $query[3] = ['SELECT c.guid, w.entry AS "npcOrPath", w.pointId AS "point", c.zoneId AS areaId, c.map, w.waittime AS "wait", w.location_y AS `posX`, w.location_x AS `posY` ' . 'FROM creature c JOIN script_waypoint w ON c.id = w.entry', ' - assembling waypoints from ' . CLISetup::bold('script_waypoint')]; $query[4] = ['SELECT c.guid, w.entry AS "npcOrPath", w.pointId AS "point", c.zoneId AS areaId, c.map, 0 AS "wait", w.position_y AS `posX`, w.position_x AS `posY` ' . 'FROM creature c JOIN waypoints w ON c.id = w.entry', ' - assembling waypoints from ' . CLISetup::bold('waypoints')]; $query[5] = ['SELECT c.guid, -w.id AS "npcOrPath", w.point, c.zoneId AS areaId, c.map, w.delay AS "wait", w.position_y AS `posX`, w.position_x AS `posY` ' . 'FROM creature c JOIN creature_addon ca ON ca.guid = c.guid JOIN waypoint_data w ON w.id = ca.path_id', ' - assembling waypoints from ' . CLISetup::bold('waypoint_data')]; $queryPost = 'SELECT dm.Id, wma.areaId, IFNULL(dm.floor, 0) AS floor, ' . '100 - ROUND(IF(dm.Id IS NOT NULL, (?f - dm.minY) * 100 / (dm.maxY - dm.minY), (?f - wma.right) * 100 / (wma.left - wma.right)), 1) AS `posX`, ' . '100 - ROUND(IF(dm.Id IS NOT NULL, (?f - dm.minX) * 100 / (dm.maxX - dm.minX), (?f - wma.bottom) * 100 / (wma.top - wma.bottom)), 1) AS `posY`, ' . '((abs(IF(dm.Id IS NOT NULL, (?f - dm.minY) * 100 / (dm.maxY - dm.minY), (?f - wma.right) * 100 / (wma.left - wma.right)) - 50) / 50) * ' . ' (abs(IF(dm.Id IS NOT NULL, (?f - dm.minX) * 100 / (dm.maxX - dm.minX), (?f - wma.bottom) * 100 / (wma.top - wma.bottom)) - 50) / 50)) AS quality ' . 'FROM dbc_worldmaparea wma ' . 'LEFT JOIN dbc_dungeonmap dm ON dm.mapId = IF(?d AND wma.mapId NOT IN (0, 1, 530), wma.mapId, -1) ' . 'WHERE wma.mapId = ?d AND IF(?d, wma.areaId = ?d, wma.areaId <> 0) ' . 'HAVING (`posX` BETWEEN 0.1 AND 99.9 AND `posY` BETWEEN 0.1 AND 99.9) AND (dm.Id IS NULL OR ?d) ' . 'ORDER BY quality ASC'; /*********************/ /* truncate old data */ /*********************/ DB::Aowow()->query('TRUNCATE TABLE ?_spawns'); DB::Aowow()->query('TRUNCATE TABLE ?_creature_waypoints'); /**************************/ /* offsets for transports */ /**************************/ $transports = DB::World()->selectCol('SELECT Data0 AS pathId, Data6 AS ARRAY_KEY FROM gameobject_template WHERE type = 15 AND Data6 <> 0'); foreach ($transports as &$t) { $t = DB::Aowow()->selectRow('SELECT posX, posY, mapId FROM dbc_taxipathnode tpn WHERE tpn.pathId = ?d AND nodeIdx = 0', $t); } /**************/ /* perform... */ /**************/ foreach ($query as $idx => $q) { CLISetup::log($q[1]); $n = 0; $sum = 0; foreach (DB::World()->select($q[0]) as $spawn) { if (!$n) { CLISetup::log(' * sets ' . ($sum + 1) . ' - ' . ($sum += SqlGen::$stepSize)); } if ($n++ > SqlGen::$stepSize) { $n = 0; } // npc/object is on a transport -> apply offsets to path of transport // note, that the coordinates are mixed up .. again // also note, that transport DO spawn outside of displayable area maps .. another todo i guess.. if (isset($transports[$spawn['map']])) { $spawn['posX'] += $transports[$spawn['map']]['posY']; $spawn['posY'] += $transports[$spawn['map']]['posX']; $spawn['map'] = $transports[$spawn['map']]['mapId']; } $points = DB::Aowow()->select($queryPost, $spawn['posX'], $spawn['posX'], $spawn['posY'], $spawn['posY'], $spawn['posX'], $spawn['posX'], $spawn['posY'], $spawn['posY'], 1, $spawn['map'], $spawn['areaId'], $spawn['areaId'], $spawn['areaId'] ? 1 : 0); if (!$points) { // retry: TC counts pre-instance subareas as instance-maps .. which have no map file $points = DB::Aowow()->select($queryPost, $spawn['posX'], $spawn['posX'], $spawn['posY'], $spawn['posY'], $spawn['posX'], $spawn['posX'], $spawn['posY'], $spawn['posY'], 0, $spawn['map'], 0, 0, 1); } if (!$points) { CLISetup::log('GUID ' . $spawn['guid'] . ($idx < 3 ? '' : ' on path/point ' . $spawn['npcOrPath'] . '/' . $spawn['point']) . ' could not be matched to displayable area [A:' . $spawn['areaId'] . '; X:' . $spawn['posY'] . '; Y:' . $spawn['posX'] . ']', CLISetup::LOG_WARN); continue; } // if areaId is set, area was determined by TC .. we're fine .. mostly $final = $spawn['areaId'] ? $points[0] : $checkCoords($points); if ($idx < 3) { $set = array('guid' => $spawn['guid'], 'type' => $spawn['type'], 'typeId' => $spawn['typeId'], 'respawn' => $spawn['respawn'], 'phaseMask' => $spawn['phaseMask'], 'pathId' => $spawn['pathId'], 'areaId' => $final['areaId'], 'floor' => $final['floor'], 'posX' => $final['posX'], 'posY' => $final['posY']); DB::Aowow()->query('REPLACE INTO ?_spawns (?#) VALUES (?a)', array_keys($set), array_values($set)); } else { $set = array('creatureOrPath' => $spawn['npcOrPath'], 'point' => $spawn['point'], 'wait' => $spawn['wait'], 'areaId' => $final['areaId'], 'floor' => $final['floor'], 'posX' => $final['posX'], 'posY' => $final['posY']); DB::Aowow()->query('REPLACE INTO ?_creature_waypoints (?#) VALUES (?a)', array_keys($set), array_values($set)); } } } /*****************************/ /* spawn vehicle accessories */ /*****************************/ // get vehicle template accessories $accessories = DB::World()->select(' SELECT vta.accessory_entry AS typeId, c.guid, vta.entry, count(1) AS nSeats FROM vehicle_template_accessory vta LEFT JOIN creature c ON c.id = vta.entry GROUP BY accessory_entry, c.guid UNION SELECT va.accessory_entry AS typeId, va.guid, 0 AS entry, count(1) AS nSeats FROM vehicle_accessory va GROUP BY accessory_entry, va.guid'); // accessories may also be vehicles (e.g. "Kor'kron Infiltrator" is seated on "Kor'kron Suppression Turret" is seated on "Kor'kron Troop Transport") // so we will retry finding a spawned vehicle if none were found on the previous pass and a change occured $vGuid = 0; // not really used, but we need some kind of index $n = 0; $matches = -1; while ($matches) { $matches = 0; foreach ($accessories as $idx => $data) { $vehicles = []; if ($data['guid']) { // vehicle already spawned $vehicles = DB::Aowow()->select('SELECT s.areaId, s.posX, s.posY, s.floor FROM ?_spawns s WHERE s.guid = ?d AND s.type = ?d', $data['guid'], TYPE_NPC); } else { if ($data['entry']) { // vehicle on unspawned vehicle action $vehicles = DB::Aowow()->select('SELECT s.areaId, s.posX, s.posY, s.floor FROM ?_spawns s WHERE s.typeId = ?d AND s.type = ?d', $data['entry'], TYPE_NPC); } } if ($vehicles) { $matches++; foreach ($vehicles as $v) { // if there is more than one vehicle, its probably due to overlapping zones for ($i = 0; $i < $data['nSeats']; $i++) { DB::Aowow()->query(' REPLACE INTO ?_spawns (`guid`, `type`, `typeId`, `respawn`, `spawnMask`, `phaseMask`, `areaId`, `floor`, `posX`, `posY`, `pathId`) VALUES (?d, ?d, ?d, 0, 0, 1, ?d, ?d, ?d, ?d, 0)', --$vGuid, TYPE_NPC, $data['typeId'], $v['areaId'], $v['floor'], $v['posX'], $v['posY']); } } unset($accessories[$idx]); } } if ($matches) { CLISetup::log(' * assigned ' . $matches . ' accessories on ' . ++$n . '. pass on vehicle accessories'); } } if ($accessories) { CLISetup::log(count($accessories) . ' accessories could not be fitted onto a spawned vehicle.', CLISetup::LOG_WARN); } /********************************/ /* restrict difficulty displays */ /********************************/ DB::Aowow()->query('UPDATE ?_spawns s, dbc_worldmaparea wma, dbc_map m SET s.spawnMask = 0 WHERE s.areaId = wma.areaId AND wma.mapId = m.Id AND m.areaType IN (0, 3, 4)'); return true; }
public function CalculateDurabilityCost() { if (!$this->IsCorrect()) { return 0; } if ($this->durability_cost >= 0) { return $this->durability_cost; } // Ported from MaNGOS: // uint32 Player::DurabilityRepair(uint16 pos, bool cost, float discountMod, bool guildBank); $totalCost = 0; $discountMod = 1; // No faction $maxDurability = $this->MaxDurability; if ($maxDurability == 0) { return 0; } $curDurability = 1; $lostDurability = $maxDurability - $curDurability; $dcost = DB::World()->selectRow("SELECT * FROM `DBPREFIX_durability_costs` WHERE `ItemLevel` = %d", $this->ItemLevel); if (!$dcost) { WoW_Log::WriteError('%s : wrong item level %d', __METHOD__, $this->ItemLevel); return 0; } $dQualitymodEntryId = ($this->Quality + 1) * 2; $dQualitymodEntry = DB::World()->selectRow("SELECT * FROM `DBPREFIX_durability_quality` WHERE `id` = %d", $dQualitymodEntryId); if (!$dQualitymodEntry) { WoW_Log::WriteError('%s : wrong dQualityModEntry %d', __METHOD__, $dQualitymodEntryId); return 0; } $dmultiplier = $dcost['multiplier_' . ($this->ItemSubClassToDurabilityMultiplierId() + 1)]; $costs = (int) ($lostDurability * $dmultiplier * (double) $dQualitymodEntry['qualityMod']); $costs = (int) $costs * $discountMod; if ($costs == 0) { $costs = 1; } $this->durability_cost = abs($costs); return $this->durability_cost; }
public function error() { $this->path = null; $this->tabId = null; $this->type = -99; // get error-article $this->typeId = 0; $this->title[] = Lang::main('errPageTitle'); $this->name = Lang::main('errPageTitle'); $this->addArticle(); Util::arraySumByKey($this->mysql, DB::Aowow()->getStatistics(), DB::World()->getStatistics()); $this->display('text-page-generic'); exit; }
function zones() { // base query DB::Aowow()->query(' REPLACE INTO ?_zones SELECT a.id, IFNULL(wmt.targetMapId, a.mapId), -- map a.mapId, -- mapBak a.areaTable, -- parentArea IFNULL(wmt.targetMapId, -- g_zone_categories IF(m.areaType = 1, 2, IF(m.areaType = 2, 3, IF(m.areaType = 4, 9, IF(m.isBG = 1, 6, IF(a.mapId = 571, 10, IF(a.mapId = 530, 8, a.mapId))))))), a.flags, IF(wma.id IS NULL AND m.areaType <> 4, ?d, 0), -- cuFlags, IF(a.flags & 0x01000000, 5, -- g_zone_territories IF(m.isBG = 1, 4, IF(m.areaType = 4, 4, IF(a.flags & 0x00000800, 3, IF(a.factionGroupMask = 6, 2, IF(a.factionGroupMask > 0, LOG2(a.factionGroupMask) - 1, 2)))))), m.expansion, IF(m.areaType = 0, 0, -- g_zone_instancetypes IF(m.isBG = 1, 4, IF(m.areaType = 4, 6, IF(md.modeMask & 0xC, 8, IF(md.minPl = 10 AND md.maxPL = 25, 7, IF(m.areaType = 2, 3, IF(m.areaType = 1 AND md.modeMask & 0x2, 5, 2))))))), IF (md.minPl = 10 AND md.maxPl = 25, -2, IFNULL(bm.maxPlayers, IFNULL(md.maxPl, m.maxPlayers))), 0, -- itemLevelN 0, -- itemLevelH 0, -- levelReq IFNULL(lfgIni.levelLFG, 0), -- levelReqLFG 0, -- levelHeroic IF(a.flags & 0x8, 1, -- levelMin IFNULL(bm.minLevel, IFNULL(lfgIni.levelMin, IFNULL(lfgOpen.levelMin, 0)))), IF(a.flags & 0x8, ?d, -- levelMax IFNULL(bm.maxLevel, IFNULL(lfgIni.levelMax, IFNULL(lfgOpen.levelMax, 0)))), "", -- attunements "", -- heroic attunements IFNULL(pa.areaId, 0), IFNULL(pa.posX, 0), IFNULL(pa.posY, 0), IF(wma.id IS NULL OR m.areaType = 0 OR a.mapId IN (269, 560) OR a.areaTable, a.name_loc0, m.name_loc0), IF(wma.id IS NULL OR m.areaType = 0 OR a.mapId IN (269, 560) OR a.areaTable, a.name_loc2, m.name_loc2), IF(wma.id IS NULL OR m.areaType = 0 OR a.mapId IN (269, 560) OR a.areaTable, a.name_loc3, m.name_loc3), IF(wma.id IS NULL OR m.areaType = 0 OR a.mapId IN (269, 560) OR a.areaTable, a.name_loc6, m.name_loc6), IF(wma.id IS NULL OR m.areaType = 0 OR a.mapId IN (269, 560) OR a.areaTable, a.name_loc8, m.name_loc8) FROM dbc_areatable a JOIN dbc_map m ON a.mapId = m.id LEFT JOIN ( SELECT mapId, BIT_OR(1 << difficulty) AS modeMask, MIN(nPlayer) AS minPl, MAX(nPlayer) AS maxPl FROM dbc_mapdifficulty GROUP BY mapId ) md ON md.mapId = a.mapId LEFT JOIN dbc_lfgdungeons lfgOpen ON a.mapId IN (0, 1, 530, 571) AND a.name_loc0 LIKE CONCAT("%", lfgOpen.name_loc0) AND lfgOpen.type = 4 LEFT JOIN ( SELECT mapId, m.id, `left`, `right`, `top`, `bottom`, IF((abs(((m.parentY - `right`) * 100 / (`left` - `right`)) - 50)) > abs(((m.parentX - `bottom`) * 100 / (`top` - `bottom`)) - 50), (abs(((m.parentY - `right`) * 100 / (`left` - `right`)) - 50)), (abs(((m.parentX - `bottom`) * 100 / (`top` - `bottom`)) - 50))) AS diff, areaId, -- parentArea 100 - ROUND((m.parentY - `right`) * 100 / (`left` - `right`), 1) as posX, 100 - ROUND((m.parentX - `bottom`) * 100 / (`top` - `bottom`), 1) as posY FROM dbc_worldmaparea wma JOIN dbc_map m ON m.parentMapId = wma.mapid WHERE m.parentMapId IN (0, 1, 530, 571) AND areaId <> 0 AND m.parentY BETWEEN `right` AND `left` AND m.parentX BETWEEN bottom AND top ORDER BY diff ASC ) pa ON pa.id = m.id AND m.parentMapId > -1 AND m.parentX <> 0 AND m.parentY <> 0 AND m.parentMapId = pa.mapId AND m.parentY BETWEEN pa.`right` AND pa.`left` AND m.parentX BETWEEN pa.bottom AND pa.top LEFT JOIN ( SELECT mapId, MIN(IF(targetLevelMin, targetLevelMin, levelMin)) AS levelMin, MAX(IF(targetLevelMax, targetLevelMax, targetLevel)) AS levelMax, MIN(IF(levelMin, levelMin, targetLevel)) AS levelLFG FROM dbc_lfgdungeons WHERE type NOT IN (4, 6) AND groupId <> 11 GROUP BY mapId ) lfgIni ON lfgIni.mapId = a.mapId LEFT JOIN dbc_battlemasterlist bm ON bm.mapId = a.mapId AND bm.moreMapId < 0 LEFT JOIN dbc_worldmaparea wma ON wma.areaId = a.id LEFT JOIN dbc_worldmaptransforms wmt ON wmt.targetMapId <> wmt.sourceMapId AND wma.mapId = wmt.sourceMapId AND wma.left < wmt.maxY AND wma.right > wmt.minY AND wma.top < wmt.maxX AND wma.bottom > wmt.minX GROUP BY a.id ', CUSTOM_EXCLUDE_FOR_LISTVIEW, MAX_LEVEL); // get requirements from world.access_requirement $zoneReq = DB::World()->select(' SELECT mapId AS ARRAY_KEY, MIN(level_min) AS reqLevel, MAX(IF(difficulty > 0, level_min, 0)) AS heroicLevel, MAX(IF(difficulty = 0, item_level, 0)) AS reqItemLevelN, MAX(IF(difficulty > 0, item_level, 0)) AS reqItemLevelH, CONCAT_WS(" ", GROUP_CONCAT(IF(difficulty = 0 AND item, item, NULL) SEPARATOR " "), GROUP_CONCAT(IF(difficulty = 0 AND item2 AND item2 <> item, item2, NULL) SEPARATOR " ")) AS reqItemN, CONCAT_WS(" ", GROUP_CONCAT(IF(difficulty > 0 AND item, item, NULL) SEPARATOR " "), GROUP_CONCAT(IF(difficulty > 0 AND item2 AND item2 <> item, item2, NULL) SEPARATOR " ")) AS reqItemH, CONCAT_WS(" ", GROUP_CONCAT(IF(difficulty = 0 AND quest_done_A, quest_done_A, NULL) SEPARATOR " "), GROUP_CONCAT(IF(difficulty = 0 AND quest_done_H AND quest_done_H <> quest_done_A, quest_done_H, NULL) SEPARATOR " ")) AS reqQuestN, CONCAT_WS(" ", GROUP_CONCAT(IF(difficulty > 0 AND quest_done_A, quest_done_A, NULL) SEPARATOR " "), GROUP_CONCAT(IF(difficulty > 0 AND quest_done_H AND quest_done_H <> quest_done_A, quest_done_H, NULL) SEPARATOR " ")) AS reqQuestH, CONCAT_WS(" ", GROUP_CONCAT(IF(difficulty = 0 AND completed_achievement, completed_achievement, NULL) SEPARATOR " ")) AS reqAchievementN, CONCAT_WS(" ", GROUP_CONCAT(IF(difficulty > 0 AND completed_achievement, completed_achievement, NULL) SEPARATOR " ")) AS reqAchievementH FROM access_requirement GROUP BY mapId '); foreach ($zoneReq as $mapId => $req) { $update = ['levelReq' => $req['reqLevel']]; $aN = $aH = []; if ($req['heroicLevel']) { $update['levelHeroic'] = $req['heroicLevel']; } if ($req['reqItemLevelN']) { $update['itemLevelReqN'] = $req['reqItemLevelN']; } if ($req['reqItemLevelH'] && $req['reqItemLevelH'] > $req['reqItemLevelN']) { $update['itemLevelReqH'] = $req['reqItemLevelH']; } if ($req['reqItemN'] && ($entries = explode(' ', $req['reqItemN']))) { foreach ($entries as $_) { $aN[TYPE_ITEM][] = $_; } } if ($req['reqItemH'] && ($entries = explode(' ', $req['reqItemH']))) { if ($entries = array_diff($entries, @(array) $aN[TYPE_ITEM])) { foreach ($entries as $_) { $aH[TYPE_ITEM][] = $_; } } } if ($req['reqQuestN'] && ($entries = explode(' ', $req['reqQuestN']))) { foreach ($entries as $_) { $aN[TYPE_QUEST][] = $_; } } if ($req['reqQuestH'] && ($entries = explode(' ', $req['reqQuestH']))) { if ($entries = array_diff($entries, @(array) $aN[TYPE_QUEST])) { foreach ($entries as $_) { $aH[TYPE_QUEST][] = $_; } } } if ($req['reqAchievementN'] && ($entries = explode(' ', $req['reqAchievementN']))) { foreach ($entries as $_) { $aN[TYPE_ACHIEVEMENT][] = $_; } } if ($req['reqAchievementH'] && ($entries = explode(' ', $req['reqAchievementH']))) { if ($entries = array_diff($entries, @(array) $aN[TYPE_ACHIEVEMENT])) { foreach ($entries as $_) { $aH[TYPE_ACHIEVEMENT][] = $_; } } } if ($aN) { foreach ($aN as $type => $entries) { $aN[$type] = $type . ':' . implode(' ' . $type . ':', $entries); } $update['attunementsN'] = implode(' ', $aN); } if ($aH) { foreach ($aH as $type => $entries) { $aH[$type] = $type . ':' . implode(' ' . $type . ':', $entries); } $update['attunementsH'] = implode(' ', $aH); } DB::Aowow()->query('UPDATE ?_zones SET ?a WHERE mapId = ?d', $update, $mapId); } return true; }
protected function generateContent() { $this->addJS('?data=zones&locale=' . User::$localeId . '&t=' . $_SESSION['dataKey']); /***********/ /* Infobox */ /***********/ $infobox = Lang::getInfoBoxForFlags($this->subject->getField('cuFlags')); // Quartermaster if any if ($ids = $this->subject->getField('qmNpcIds')) { $this->extendGlobalIds(TYPE_NPC, $ids); $qmStr = Lang::faction('quartermaster') . Lang::main('colon'); if (count($ids) == 1) { $qmStr .= '[npc=' . $ids[0] . ']'; } else { if (count($ids) > 1) { $qmStr .= '[ul]'; foreach ($ids as $id) { $qmStr .= '[li][npc=' . $id . '][/li]'; } $qmStr .= '[/ul]'; } } $infobox[] = $qmStr; } // side if any if ($_ = $this->subject->getField('side')) { $infobox[] = Lang::main('side') . Lang::main('colon') . '[span class=icon-' . ($_ == 1 ? 'alliance' : 'horde') . ']' . Lang::game('si', $_) . '[/span]'; } /****************/ /* Main Content */ /****************/ $this->extraText = ''; $this->infobox = $infobox ? '[ul][li]' . implode('[/li][li]', $infobox) . '[/li][/ul]' : null; $this->redButtons = array(BUTTON_WOWHEAD => true, BUTTON_LINKS => true); // Spillover Effects /* todo (low): also check on reputation_spillover_template (but its data is identical to calculation below $rst = DB::World()->selectRow('SELECT CONCAT_WS(" ", faction1, faction2, faction3, faction4) AS faction, CONCAT_WS(" ", rate_1, rate_2, rate_3, rate_4) AS rate, CONCAT_WS(" ", rank_1, rank_2, rank_3, rank_4) AS rank FROM reputation_spillover_template WHERE faction = ?d', $this->typeId); */ $conditions = array(['id', $this->typeId, '!'], ['repIdx', -1, '!']); if ($p = $this->subject->getField('parentFactionId')) { // linked via parent $conditions[] = ['OR', ['id', $p], ['parentFactionId', $p]]; } else { // self as parent $conditions[] = ['parentFactionId', $this->typeId]; } $spillover = new FactionList($conditions); $this->extendGlobalData($spillover->getJSGlobals()); $buff = ''; foreach ($spillover->iterate() as $spillId => $__) { if ($val = $spillover->getField('spilloverRateIn') * $this->subject->getField('spilloverRateOut') * 100) { $buff .= '[tr][td][faction=' . $spillId . '][/td][td][span class=q' . ($val > 0 ? '2]+' : '10]') . $val . '%[/span][/td][td]' . Lang::game('rep', $spillover->getField('spilloverMaxRank')) . '[/td][/tr]'; } } if ($buff) { $this->extraText .= '[h3 class=clear]' . Lang::faction('spillover') . '[/h3][div margin=15px]' . Lang::faction('spilloverDesc') . '[/div][table class=grid width=400px][tr][td width=150px][b]' . Util::ucFirst(Lang::game('faction')) . '[/b][/td][td width=100px][b]' . Lang::spell('_value') . '[/b][/td][td width=150px][b]' . Lang::faction('maxStanding') . '[/b][/td][/tr]' . $buff . '[/table]'; } // reward rates (ultimately this should be calculated into each reward display) if ($rates = DB::World()->selectRow('SELECT * FROM reputation_reward_rate WHERE faction = ?d', $this->typeId)) { $buff = ''; foreach ($rates as $k => $v) { if ($v == 1) { continue; } switch ($k) { case 'quest_rate': $buff .= '[tr][td]' . Lang::game('quests') . Lang::main('colon') . '[/td]'; break; case 'quest_daily_rate': $buff .= '[tr][td]' . Lang::game('quests') . ' (' . Lang::quest('daily') . ')' . Lang::main('colon') . '[/td]'; break; case 'quest_weekly_rate': $buff .= '[tr][td]' . Lang::game('quests') . ' (' . Lang::quest('weekly') . ')' . Lang::main('colon') . '[/td]'; break; case 'quest_monthly_rate': $buff .= '[tr][td]' . Lang::game('quests') . ' (' . Lang::quest('monthly') . ')' . Lang::main('colon') . '[/td]'; break; case 'creature_rate': $buff .= '[tr][td]' . Lang::game('npcs') . Lang::main('colon') . '[/td]'; break; case 'spell_rate': $buff .= '[tr][td]' . Lang::game('spells') . Lang::main('colon') . '[/td]'; break; } $buff .= '[td width=35px align=right][span class=q' . ($v < 1 ? '10]' : '2]+') . intVal(($v - 1) * 100) . '%[/span][/td][/tr]'; } if ($buff) { $this->extraText .= '[h3 class=clear]' . Lang::faction('customRewRate') . '[/h3][table]' . $buff . '[/table]'; } } // factionchange-equivalent if ($pendant = DB::World()->selectCell('SELECT IF(horde_id = ?d, alliance_id, -horde_id) FROM player_factionchange_reputations WHERE alliance_id = ?d OR horde_id = ?d', $this->typeId, $this->typeId, $this->typeId)) { $altFac = new FactionList(array(['id', abs($pendant)])); if (!$altFac->error) { $this->transfer = sprintf(Lang::faction('_transfer'), $altFac->id, $altFac->getField('name', true), $pendant > 0 ? 'alliance' : 'horde', $pendant > 0 ? Lang::game('si', 1) : Lang::game('si', 2)); } } /**************/ /* Extra Tabs */ /**************/ // tab: items $items = new ItemList(array(['requiredFaction', $this->typeId])); if (!$items->error) { $this->extendGlobalData($items->getJSGlobals(GLOBALINFO_SELF)); $tabData = array('data' => array_values($items->getListviewData()), 'extraCols' => '$_', 'sort' => ['standing', 'name']); if ($items->getMatches() > CFG_SQL_LIMIT_DEFAULT) { $tabData['note'] = sprintf(Util::$filterResultString, '?items&filter=cr=17;crs=' . $this->typeId . ';crv=0'); } $this->lvTabs[] = ['item', $tabData, 'itemStandingCol']; } // tab: creatures with onKill reputation if ($this->subject->getField('reputationIndex') != -1) { // inherit siblings/children from $spillover $cRep = DB::World()->selectCol('SELECT DISTINCT creature_id AS ARRAY_KEY, qty FROM ( SELECT creature_id, RewOnKillRepValue1 as qty FROM creature_onkill_reputation WHERE RewOnKillRepValue1 > 0 AND (RewOnKillRepFaction1 = ?d{ OR (RewOnKillRepFaction1 IN (?a) AND IsTeamAward1 <> 0)}) UNION SELECT creature_id, RewOnKillRepValue2 as qty FROM creature_onkill_reputation WHERE RewOnKillRepValue2 > 0 AND (RewOnKillRepFaction2 = ?d{ OR (RewOnKillRepFaction2 IN (?a) AND IsTeamAward2 <> 0)}) ) x', $this->typeId, $spillover->getFoundIDs() ?: DBSIMPLE_SKIP, $this->typeId, $spillover->getFoundIDs() ?: DBSIMPLE_SKIP); if ($cRep) { $killCreatures = new CreatureList(array(['id', array_keys($cRep)])); if (!$killCreatures->error) { $data = $killCreatures->getListviewData(); foreach ($data as $id => &$d) { $d['reputation'] = $cRep[$id]; } $tabData = array('data' => array_values($data), 'extraCols' => '$_', 'sort' => ['-reputation', 'name']); if ($killCreatures->getMatches() > CFG_SQL_LIMIT_DEFAULT) { $tabData['note'] = sprintf(Util::$filterResultString, '?npcs&filter=cr=42;crs=' . $this->typeId . ';crv=0'); } $this->lvTabs[] = ['creature', $tabData, 'npcRepCol']; } } } // tab: members if ($_ = $this->subject->getField('templateIds')) { $members = new CreatureList(array(['faction', $_])); if (!$members->error) { $tabData = array('data' => array_values($members->getListviewData()), 'id' => 'member', 'name' => '$LANG.tab_members'); if ($members->getMatches() > CFG_SQL_LIMIT_DEFAULT) { $tabData['note'] = sprintf(Util::$filterResultString, '?npcs&filter=cr=3;crs=' . $this->typeId . ';crv=0'); } $this->lvTabs[] = ['creature', $tabData]; } } // tab: objects if ($_ = $this->subject->getField('templateIds')) { $objects = new GameObjectList(array(['faction', $_])); if (!$objects->error) { $this->lvTabs[] = ['object', ['data' => array_values($objects->getListviewData())]]; } } // tab: quests $conditions = array(['AND', ['rewardFactionId1', $this->typeId], ['rewardFactionValue1', 0, '>']], ['AND', ['rewardFactionId2', $this->typeId], ['rewardFactionValue2', 0, '>']], ['AND', ['rewardFactionId3', $this->typeId], ['rewardFactionValue3', 0, '>']], ['AND', ['rewardFactionId4', $this->typeId], ['rewardFactionValue4', 0, '>']], ['AND', ['rewardFactionId5', $this->typeId], ['rewardFactionValue5', 0, '>']], 'OR'); $quests = new QuestList($conditions); if (!$quests->error) { $this->extendGlobalData($quests->getJSGlobals(GLOBALINFO_ANY)); $tabData = array('data' => array_values($quests->getListviewData($this->typeId)), 'extraCols' => '$_'); if ($quests->getMatches() > CFG_SQL_LIMIT_DEFAULT) { $tabData['note'] = sprintf(Util::$filterResultString, '?quests&filter=cr=1;crs=' . $this->typeId . ';crv=0'); } $this->lvTabs[] = ['quest', $tabData, 'questRepCol']; } // tab: achievements $conditions = array(['ac.type', ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION], ['ac.value1', $this->typeId]); $acvs = new AchievementList($conditions); if (!$acvs->error) { $this->extendGlobalData($acvs->getJSGlobals(GLOBALINFO_ANY)); $this->lvTabs[] = ['achievement', array('data' => array_values($acvs->getListviewData()), 'id' => 'criteria-of', 'name' => '$LANG.tab_criteriaof', 'visibleCols' => ['category'])]; } }
protected function generateContent() { $this->addJS('?data=zones&locale=' . User::$localeId . '&t=' . $_SESSION['dataKey']); /***********/ /* Infobox */ /***********/ $infobox = Lang::getInfoBoxForFlags($this->subject->getField('cuFlags')); // 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 fucking point..? $sameModel = new GameObjectList(array(['displayId', $this->subject->getField('displayId')], ['id', $this->typeId, '!'])); if (!$sameModel->error) { $this->extendGlobalData($sameModel->getJSGlobals()); $this->lvTabs[] = array('file' => 'object', 'data' => $sameModel->getListviewData(), 'params' => array('name' => '$LANG.tab_samemodelas', 'id' => 'same-model-as')); } }
protected function generateContent() { /***********/ /* Infobox */ /***********/ $infobox = Lang::getInfoBoxForFlags($this->subject->getField('cuFlags')); // reqLevel if ($_ = $this->subject->getField('requiredLevel')) { $infobox[] = sprintf(Lang::game('reqLevel'), $_); } // reqskill if ($_ = $this->subject->getField('skillLine')) { $this->extendGlobalIds(TYPE_SKILL, $_); $foo = sprintf(Lang::game('requires'), ' [skill=' . $_ . ']'); if ($_ = $this->subject->getField('skillLevel')) { $foo .= ' (' . $_ . ')'; } $infobox[] = $foo; } /****************/ /* Main Content */ /****************/ $this->infobox = $infobox ? '[ul][li]' . implode('[/li][li]', $infobox) . '[/li][/ul]' : null; $this->effects = []; // 3 effects for ($i = 1; $i < 4; $i++) { $_ty = $this->subject->getField('type' . $i); $_qty = $this->subject->getField('amount' . $i); $_obj = $this->subject->getField('object' . $i); switch ($_ty) { case 1: case 3: case 7: $sArr = $this->subject->getField('spells')[$i]; $spl = $this->subject->getRelSpell($sArr[0]); $this->effects[$i]['name'] = User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, 'Type: ' . $_ty, Lang::item('trigger', $sArr[1])) : Lang::item('trigger', $sArr[1]); $this->effects[$i]['proc'] = $sArr[3]; $this->effects[$i]['value'] = $_qty ?: null; $this->effects[$i]['icon'] = array('name' => !$spl ? Util::ucFirst(Lang::game('spell')) . ' #' . $sArr[0] : Util::localizedString($spl, 'name'), 'id' => $sArr[0], 'count' => $sArr[2]); break; case 5: if ($_obj < 2) { // [mana, health] are on [0, 1] respectively and are expected on [1, 2] .. $_obj++; } // 0 is weaponDmg .. ehh .. i messed up somewhere $this->effects[$i]['tip'] = [$_obj, Util::$itemMods[$_obj]]; // DO NOT BREAK! // DO NOT BREAK! case 2: case 6: case 8: case 4: $this->effects[$i]['name'] = User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, 'Type: ' . $_ty, Lang::enchantment('types', $_ty)) : Lang::enchantment('types', $_ty); $this->effects[$i]['value'] = $_qty; if ($_ty == 4) { $this->effects[$i]['name'] .= Lang::main('colon') . '(' . (User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, 'Object: ' . $_obj, Lang::getMagicSchools(1 << $_obj)) : Lang::getMagicSchools(1 << $_obj)) . ')'; } } } // activation conditions if ($_ = $this->subject->getField('conditionId')) { $x = ''; if ($gemCnd = DB::Aowow()->selectRow('SELECT * FROM ?_itemenchantmentcondition WHERE id = ?d', $_)) { for ($i = 1; $i < 6; $i++) { if (!$gemCnd['color' . $i]) { continue; } $fiColors = function ($idx) { $foo = ''; switch ($idx) { case 2: $foo = '0:3:5'; break; // red // red case 3: $foo = '2:4:5'; break; // yellow // yellow case 4: $foo = '1:3:4'; break; // blue } return $foo; }; $bLink = $gemCnd['color' . $i] ? '<a href="?items=3&filter=ty=' . $fiColors($gemCnd['color' . $i]) . '">' . Lang::item('gemColors', $gemCnd['color' . $i] - 1) . '</a>' : ''; $cLink = $gemCnd['cmpColor' . $i] ? '<a href="?items=3&filter=ty=' . $fiColors($gemCnd['cmpColor' . $i]) . '">' . Lang::item('gemColors', $gemCnd['cmpColor' . $i] - 1) . '</a>' : ''; switch ($gemCnd['comparator' . $i]) { case 2: // requires less <color> than (<value> || <comparecolor>) gems // requires less <color> than (<value> || <comparecolor>) gems case 5: // requires at least <color> than (<value> || <comparecolor>) gems $sp = (int) $gemCnd['value' . $i] > 1; $x .= '<span class="q0">' . Lang::achievement('reqNumCrt') . ' ' . sprintf(Lang::item('gemConditions', $gemCnd['comparator' . $i], $sp), $gemCnd['value' . $i], $bLink) . '</span><br />'; break; case 3: // requires more <color> than (<value> || <comparecolor>) gems $link = '<a href="?items=3&filter=ty=' . $fiColors($gemCnd['cmpColor' . $i]) . '">' . Lang::item('gemColors', $gemCnd['cmpColor' . $i] - 1) . '</a>'; $x .= '<span class="q0">' . Lang::achievement('reqNumCrt') . ' ' . sprintf(Lang::item('gemConditions', 3), $bLink, $cLink) . '</span><br />'; break; } } } $this->activateCondition = $x; } /**************/ /* Extra Tabs */ /**************/ // used by gem $gemList = new ItemList(array(['gemEnchantmentId', $this->typeId])); if (!$gemList->error) { $this->lvTabs[] = ['item', array('data' => array_values($gemList->getListviewData()), 'name' => '$LANG.tab_usedby + \' \' + LANG.gems', 'id' => 'used-by-gem')]; $this->extendGlobalData($gemList->getJsGlobals()); } // used by socket bonus $socketsList = new ItemList(array(['socketBonus', $this->typeId])); if (!$socketsList->error) { $this->lvTabs[] = ['item', array('data' => array_values($socketsList->getListviewData()), 'name' => '$LANG.tab_usedby + \' \' + \'' . Lang::item('socketBonus') . '\'', 'id' => 'used-by-socketbonus')]; $this->extendGlobalData($socketsList->getJsGlobals()); } // used by spell // used by useItem $cnd = array('OR', ['AND', ['effect1Id', [53, 54, 156, 92]], ['effect1MiscValue', $this->typeId]], ['AND', ['effect2Id', [53, 54, 156, 92]], ['effect2MiscValue', $this->typeId]], ['AND', ['effect3Id', [53, 54, 156, 92]], ['effect3MiscValue', $this->typeId]]); $spellList = new SpellList($cnd); if (!$spellList->error) { $spellData = $spellList->getListviewData(); $this->extendGlobalData($spellList->getJsGlobals()); $spellIds = $spellList->getFoundIDs(); $conditions = array('OR', ['AND', ['spellTrigger1', [0, 5]], ['spellId1', $spellIds]], ['AND', ['spellTrigger2', [0, 5]], ['spellId2', $spellIds]], ['AND', ['spellTrigger3', [0, 5]], ['spellId3', $spellIds]], ['AND', ['spellTrigger4', [0, 5]], ['spellId4', $spellIds]], ['AND', ['spellTrigger5', [0, 5]], ['spellId5', $spellIds]]); $ubItems = new ItemList($conditions); if (!$ubItems->error) { $this->lvTabs[] = ['item', array('data' => array_values($ubItems->getListviewData()), 'name' => '$LANG.tab_usedby + \' \' + LANG.types[3][0]', 'id' => 'used-by-item')]; $this->extendGlobalData($ubItems->getJSGlobals(GLOBALINFO_SELF)); } // remove found spells if they are used by an item if (!$ubItems->error) { foreach ($spellList->iterate() as $sId => $__) { // if Perm. Enchantment has a createItem its a Scroll of Enchantment (display both) for ($i = 1; $i < 4; $i++) { if ($spellList->getField('effect' . $i . 'Id') == 53 && $spellList->getField('effect' . $i . 'CreateItemId')) { continue 2; } } foreach ($ubItems->iterate() as $__) { for ($i = 1; $i < 6; $i++) { if ($ubItems->getField('spellId' . $i) == $sId) { unset($spellData[$sId]); break 2; } } } } } $this->lvTabs[] = ['spell', array('data' => array_values($spellData), 'name' => '$LANG.tab_usedby + \' \' + LANG.types[6][0]', 'id' => 'used-by-spell')]; } // used by randomAttrItem $ire = DB::Aowow()->select('SELECT *, ABS(id) AS ARRAY_KEY FROM ?_itemrandomenchant WHERE enchantId1 = ?d OR enchantId2 = ?d OR enchantId3 = ?d OR enchantId4 = ?d OR enchantId5 = ?d', $this->typeId, $this->typeId, $this->typeId, $this->typeId, $this->typeId); if ($ire) { if ($iet = DB::World()->select('SELECT entry AS ARRAY_KEY, ench, chance FROM item_enchantment_template WHERE ench IN (?a)', array_keys($ire))) { $randIds = []; // transform back to signed format foreach ($iet as $tplId => $data) { $randIds[$ire[$data['ench']]['id'] > 0 ? $tplId : -$tplId] = $ire[$data['ench']]['id']; } $randItems = new ItemList(array(CFG_SQL_LIMIT_NONE, ['randomEnchant', array_keys($randIds)])); if (!$randItems->error) { $data = $randItems->getListviewData(); foreach ($randItems->iterate() as $iId => $__) { $re = $randItems->getField('randomEnchant'); $data[$iId]['percent'] = $iet[abs($re)]['chance']; $data[$iId]['count'] = 1; // expected by js or the pct-col becomes unsortable $data[$iId]['rel'] = 'rand=' . $ire[$iet[abs($re)]['ench']]['id']; $data[$iId]['name'] .= ' ' . Util::localizedString($ire[$iet[abs($re)]['ench']], 'name'); } $this->lvTabs[] = ['item', array('data' => array_values($data), 'id' => 'used-by-rand', 'name' => '$LANG.tab_usedby + \' \' + \'' . Lang::item('_rndEnchants') . '\'', 'extraCols' => ['$Listview.extraCols.percent'])]; $this->extendGlobalData($randItems->getJSGlobals(GLOBALINFO_SELF)); } } } }
protected function createSQLForCriterium(&$cr) { if (in_array($cr[0], array_keys($this->genericFilter))) { if ($genCr = $this->genericCriterion($cr)) { return $genCr; } unset($cr); $this->error = true; return [1]; } switch ($cr[0]) { case 2: // bindonpickup [yn] if ($this->int2Bool($cr[1])) { return ['bonding', 1, $cr[1] ? null : '!']; } break; case 3: // bindonequip [yn] if ($this->int2Bool($cr[1])) { return ['bonding', 2, $cr[1] ? null : '!']; } break; case 4: // bindonuse [yn] if ($this->int2Bool($cr[1])) { return ['bonding', 3, $cr[1] ? null : '!']; } break; case 5: // questitem [yn] if ($this->int2Bool($cr[1])) { return ['bonding', [4, 5], $cr[1] ? null : '!']; } break; case 168: // teachesspell [yn] 483: learn recipe; 55884: learn mount/pet if ($this->int2Bool($cr[1])) { return ['spellId1', [483, 55884], $cr[1] ? null : '!']; } break; case 15: // unique [yn] if ($this->int2Bool($cr[1])) { return ['maxCount', 1, $cr[1] ? null : '!']; } break; case 161: // availabletoplayers [yn] if ($this->int2Bool($cr[1])) { return [['cuFlags', CUSTOM_UNAVAILABLE, '&'], 0, $cr[1] ? null : '!']; } break; case 80: // has sockets [enum] switch ($cr[1]) { case 5: // Yes return ['is.nsockets', 0, '!']; case 6: // No return ['is.nsockets', 0]; case 1: // Meta // Meta case 2: // Red // Red case 3: // Yellow // Yellow case 4: // Blue $mask = 1 << $cr[1] - 1; return ['OR', ['socketColor1', $mask], ['socketColor2', $mask], ['socketColor3', $mask]]; } break; case 81: // fits gem slot [enum] switch ($cr[1]) { case 5: // Yes return ['gemEnchantmentId', 0, '!']; case 6: // No return ['gemEnchantmentId', 0]; case 1: // Meta // Meta case 2: // Red // Red case 3: // Yellow // Yellow case 4: // Blue $mask = 1 << $cr[1] - 1; return ['AND', ['gemEnchantmentId', 0, '!'], ['gemColorMask', $mask, '&']]; } break; case 107: // effecttext [str] not yet parsed ['effectsParsed_loc'.User::$localeId, $cr[2]] /* todo */ return [1]; case 132: // glyphtype [enum] switch ($cr[1]) { case 1: // Major // Major case 2: // Minor return ['AND', ['class', 16], ['subSubClass', $cr[1]]]; } break; case 124: // randomenchants [str] $randIds = DB::Aowow()->selectCol('SELECT id AS ARRAY_KEY, ABS(id) FROM ?_itemrandomenchant WHERE name_loc?d LIKE ?', User::$localeId, '%' . $cr[2] . '%'); $tplIds = $randIds ? DB::World()->select('SELECT entry, ench FROM item_enchantment_template WHERE ench IN (?a)', $randIds) : []; foreach ($tplIds as $k => &$set) { if (array_search($set['ench'], $randIds) < 0) { $set['entry'] *= -1; } } if ($tplIds) { return ['randomEnchant', array_column($tplIds, 'entry')]; } else { return [0]; } // no results aren't really input errors // no results aren't really input errors case 125: // reqarenartng [op] [int] todo (low): find out, why "IN (W, X, Y) AND IN (X, Y, Z)" doesn't result in "(X, Y)" if (!$this->isSaneNumeric($cr[2]) || !$this->int2Op($cr[1])) { break; } $this->formData['extraCols'][] = $cr[0]; $costs = DB::Aowow()->selectCol('SELECT id FROM ?_itemextendedcost WHERE reqPersonalrating ' . $cr[1] . ' ' . $cr[2]); $items = DB::World()->selectCol($this->extCostQuery, $costs, $costs); return ['id', $items]; case 160: // relatedevent [enum] like 169 .. crawl though npc_vendor and loot_templates of event-related spawns /* todo */ return [1]; case 152: // classspecific [enum] $_ = isset($this->enums[$cr[0]][$cr[1]]) ? $this->enums[$cr[0]][$cr[1]] : null; if ($_ !== null) { if (is_bool($_)) { return $_ ? ['AND', [['requiredClass', CLASS_MASK_ALL, '&'], CLASS_MASK_ALL, '!'], ['requiredClass', 0, '>']] : ['OR', [['requiredClass', CLASS_MASK_ALL, '&'], CLASS_MASK_ALL], ['requiredClass', 0]]; } else { if (is_int($_)) { return ['AND', [['requiredClass', CLASS_MASK_ALL, '&'], CLASS_MASK_ALL, '!'], ['requiredClass', 1 << $_ - 1, '&']]; } } } break; case 153: // racespecific [enum] $_ = isset($this->enums[$cr[0]][$cr[1]]) ? $this->enums[$cr[0]][$cr[1]] : null; if ($_ !== null) { if (is_bool($_)) { return $_ ? ['AND', [['requiredRace', RACE_MASK_ALL, '&'], RACE_MASK_ALL, '!'], ['requiredRace', 0, '>']] : ['OR', [['requiredRace', RACE_MASK_ALL, '&'], RACE_MASK_ALL], ['requiredRace', 0]]; } else { if (is_int($_)) { return ['AND', [['requiredRace', RACE_MASK_ALL, '&'], RACE_MASK_ALL, '!'], ['requiredRace', 1 << $_ - 1, '&']]; } } } break; case 35: // damagetype [enum] if (!$this->isSaneNumeric($cr[1]) || $cr[1] > 6 || $cr[1] < 0) { break; } return ['OR', ['dmgType1', $cr[1]], ['dmgType2', $cr[1]]]; case 109: // armorbonus [op] [int] if (!$this->isSaneNumeric($cr[2], false) || !$this->int2Op($cr[1])) { break; } $this->formData['extraCols'][] = $cr[0]; return ['AND', ['armordamagemodifier', $cr[2], $cr[1]], ['class', ITEM_CLASS_ARMOR]]; case 86: // craftedprof [enum] $_ = isset($this->enums[99][$cr[1]]) ? $this->enums[99][$cr[1]] : null; if (is_bool($_)) { return ['src.src1', null, $_ ? '!' : null]; } else { if (is_int($_)) { return ['s.skillLine1', $_]; } } break; case 16: // dropsin [zone] /* todo */ return [1]; case 105: // dropsinnormal [heroicdungeon-any] /* todo */ return [1]; case 106: // dropsinheroic [heroicdungeon-any] /* todo */ return [1]; case 147: // dropsinnormal10 [multimoderaid-any] /* todo */ return [1]; case 148: // dropsinnormal25 [multimoderaid-any] /* todo */ return [1]; case 149: // dropsinheroic10 [heroicraid-any] /* todo */ return [1]; case 150: // dropsinheroic25 [heroicraid-any] /* todo */ return [1]; case 68: // otdisenchanting [yn] // otdisenchanting [yn] case 69: // otfishing [yn] // otfishing [yn] case 70: // otherbgathering [yn] // case 71: // otitemopening [yn] [implemented via cuFlags] // otherbgathering [yn] // case 71: // otitemopening [yn] [implemented via cuFlags] case 72: // otlooting [yn] // otlooting [yn] case 73: // otmining [yn] // case 74: // otobjectopening [yn] [implemented via cuFlags] // otmining [yn] // case 74: // otobjectopening [yn] [implemented via cuFlags] case 75: // otpickpocketing [yn] // otpickpocketing [yn] case 76: // otskinning [yn] // otskinning [yn] case 88: // otprospecting [yn] // otprospecting [yn] case 93: // otpvp [pvp] // otpvp [pvp] case 143: // otmilling [yn] // otmilling [yn] case 171: // otredemption [yn] // otredemption [yn] case 172: // rewardedbyachievement [yn] // rewardedbyachievement [yn] case 92: // soldbyvendor [yn] if ($this->int2Bool($cr[1])) { return ['src.src' . $this->otFields[$cr[0]], null, $cr[1] ? '!' : null]; } break; case 18: // rewardedbyfactionquest [side] $field = 'src.src' . $this->otFields[$cr[0]]; switch ($cr[1]) { case 1: // Yes return [$field, null, '!']; case 2: // Alliance return [$field, 1]; case 3: // Horde return [$field, 2]; case 4: // Both return [$field, 3]; case 5: // No return [$field, null]; } break; case 126: // rewardedbyquestin [zone-any] if (in_array($cr[1], $this->enums[$cr[0]])) { return ['AND', ['src.src4', null, '!'], ['src.moreZoneId', $cr[1]]]; } else { if ($cr[1] == FILTER_ENUM_ANY) { return ['src.src4', null, '!']; } } // well, this seems a bit redundant.. break; case 158: // purchasablewithcurrency [enum] // purchasablewithcurrency [enum] case 118: // purchasablewithitem [enum] if (in_array($cr[1], $this->enums[$cr[0]])) { $_ = (array) $cr[1]; } else { if ($cr[1] == FILTER_ENUM_ANY) { $_ = $this->enums[$cr[0]]; } else { break; } } $costs = DB::Aowow()->selectCol('SELECT id FROM ?_itemextendedcost WHERE reqItemId1 IN (?a) OR reqItemId2 IN (?a) OR reqItemId3 IN (?a) OR reqItemId4 IN (?a) OR reqItemId5 IN (?a)', $_, $_, $_, $_, $_); if ($items = DB::World()->selectCol($this->extCostQuery, $costs, $costs)) { return ['id', $items]; } break; case 144: // purchasablewithhonor [yn] if ($this->int2Bool($cr[1])) { $costs = DB::Aowow()->selectCol('SELECT id FROM ?_itemextendedcost WHERE reqHonorPoints > 0'); if ($items = DB::World()->selectCol($this->extCostQuery, $costs, $costs)) { return ['id', $items, $cr[1] ? null : '!']; } } break; case 145: // purchasablewitharena [yn] if ($this->int2Bool($cr[1])) { $costs = DB::Aowow()->selectCol('SELECT id FROM ?_itemextendedcost WHERE reqArenaPoints > 0'); if ($items = DB::World()->selectCol($this->extCostQuery, $costs, $costs)) { return ['id', $items, $cr[1] ? null : '!']; } } break; case 129: // soldbynpc [str-small] if (!$this->isSaneNumeric($cr[2], true)) { break; } if ($iIds = DB::World()->selectCol('SELECT item FROM npc_vendor WHERE entry = ?d UNION SELECT item FROM game_event_npc_vendor v JOIN creature c ON c.guid = v.guid WHERE c.id = ?d', $cr[2], $cr[2])) { return ['i.id', $iIds]; } else { return [0]; } case 90: // avgbuyout [op] [int] if (!$this->isSaneNumeric($cr[2]) || !$this->int2Op($cr[1])) { break; } foreach (Util::getRealms() as $rId => $__) { // todo: do something sensible.. // // todo (med): get the avgbuyout into the listview // if ($_ = DB::Characters()->select('SELECT ii.itemEntry AS ARRAY_KEY, AVG(ah.buyoutprice / ii.count) AS buyout FROM auctionhouse ah JOIN item_instance ii ON ah.itemguid = ii.guid GROUP BY ii.itemEntry HAVING avgbuyout '.$cr[1].' ?f', $c[1])) // return ['i.id', array_keys($_)]; // else // return [0]; return [1]; } return [0]; case 65: // avgmoney [op] [int] if (!$this->isSaneNumeric($cr[2]) || !$this->int2Op($cr[1])) { break; } $this->formData['extraCols'][] = $cr[0]; return ['AND', ['flags', ITEM_FLAG_OPENABLE, '&'], ['((minMoneyLoot + maxMoneyLoot) / 2)', $cr[2], $cr[1]]]; case 62: // cooldown [op] [int] fuck it .. too complex atm if (!$this->isSaneNumeric($cr[2]) || !$this->int2Op($cr[1])) { break; } $cr[2] *= 1000; // field supplied in milliseconds $this->formData['extraCols'][] = $cr[0]; $this->extraOpts['is']['s'][] = ', IF(spellCooldown1 > 1, spellCooldown1, IF(spellCooldown2 > 1, spellCooldown2, IF(spellCooldown3 > 1, spellCooldown3, IF(spellCooldown4 > 1, spellCooldown4, IF(spellCooldown5 > 1, spellCooldown5,))))) AS cooldown'; return ['OR', ['AND', ['spellTrigger1', 0], ['spellId1', 0, '!'], ['spellCooldown1', 0, '>'], ['spellCooldown1', $cr[2], $cr[1]]], ['AND', ['spellTrigger2', 0], ['spellId2', 0, '!'], ['spellCooldown2', 0, '>'], ['spellCooldown2', $cr[2], $cr[1]]], ['AND', ['spellTrigger3', 0], ['spellId3', 0, '!'], ['spellCooldown3', 0, '>'], ['spellCooldown3', $cr[2], $cr[1]]], ['AND', ['spellTrigger4', 0], ['spellId4', 0, '!'], ['spellCooldown4', 0, '>'], ['spellCooldown4', $cr[2], $cr[1]]], ['AND', ['spellTrigger5', 0], ['spellId5', 0, '!'], ['spellCooldown5', 0, '>'], ['spellCooldown5', $cr[2], $cr[1]]]]; case 163: // disenchantsinto [disenchanting] if (!$this->isSaneNumeric($cr[1])) { break; } if (!in_array($cr[1], $this->enums[$cr[0]])) { break; } $refResults = []; $newRefs = DB::World()->selectCol('SELECT entry FROM ?# WHERE item = ?d AND reference = 0', LOOT_REFERENCE, $cr[1]); while ($newRefs) { $refResults += $newRefs; $newRefs = DB::World()->selectCol('SELECT entry FROM ?# WHERE reference IN (?a)', LOOT_REFERENCE, $newRefs); } $lootIds = DB::World()->selectCol('SELECT entry FROM ?# WHERE {reference IN (?a) OR }(reference = 0 AND item = ?d)', LOOT_DISENCHANT, $refResults ?: DBSIMPLE_SKIP, $cr[1]); return $lootIds ? ['disenchantId', $lootIds] : [0]; case 85: // objectivequest [side] $w = ''; switch ($cr[1]) { case 1: // Yes // Yes case 5: // No $w = 1; break; case 2: // Alliance $w = 'reqRaceMask & ' . RACE_MASK_ALLIANCE . ' AND (reqRaceMask & ' . RACE_MASK_HORDE . ') = 0'; break; case 3: // Horde $w = 'reqRaceMask & ' . RACE_MASK_HORDE . ' AND (reqRaceMask & ' . RACE_MASK_ALLIANCE . ') = 0'; break; case 4: // Both $w = '(reqRaceMask & ' . RACE_MASK_ALLIANCE . ' AND reqRaceMask & ' . RACE_MASK_HORDE . ') OR reqRaceMask = 0'; break; default: break 2; } $itemIds = DB::Aowow()->selectCol(sprintf(' SELECT reqItemId1 FROM ?_quests WHERE %1$s UNION SELECT reqItemId2 FROM ?_quests WHERE %1$s UNION SELECT reqItemId3 FROM ?_quests WHERE %1$s UNION SELECT reqItemId4 FROM ?_quests WHERE %1$s UNION SELECT reqItemId5 FROM ?_quests WHERE %1$s UNION SELECT reqItemId6 FROM ?_quests WHERE %1$s', $w)); if ($itemIds) { return ['id', $itemIds, $cr[1] == 5 ? '!' : null]; } return [0]; case 87: // reagentforability [enum] $_ = isset($this->enums[99][$cr[1]]) ? $this->enums[99][$cr[1]] : null; if ($_ !== null) { $ids = []; $spells = DB::Aowow()->select('SELECT reagent1, reagent2, reagent3, reagent4, reagent5, reagent6, reagent7, reagent8, reagentCount1, reagentCount2, reagentCount3, reagentCount4, reagentCount5, reagentCount6, reagentCount7, reagentCount8 FROM ?_spell WHERE skillLine1 IN (?a)', is_bool($_) ? array_filter($this->enums[99], "is_numeric") : $_); foreach ($spells as $spell) { for ($i = 1; $i < 9; $i++) { if ($spell['reagent' . $i] > 0 && $spell['reagentCount' . $i] > 0) { $ids[] = $spell['reagent' . $i]; } } } if (empty($ids)) { return [0]; } else { if ($_) { return ['id', $ids]; } else { return ['id', $ids, '!']; } } } break; case 6: // startsquest [side] switch ($cr[1]) { case 1: // any return ['startQuest', 0, '>']; case 2: // exclude horde only return ['AND', ['startQuest', 0, '>'], [['flagsExtra', 0x3, '&'], 2]]; case 3: // exclude alliance only return ['AND', ['startQuest', 0, '>'], [['flagsExtra', 0x3, '&'], 1]]; case 4: // both return ['AND', ['startQuest', 0, '>'], [['flagsExtra', 0x3, '&'], 0]]; case 5: // none return ['startQuest', 0]; } break; case 128: // source [enum] $_ = isset($this->enums[$cr[0]][$cr[1]]) ? $this->enums[$cr[0]][$cr[1]] : null; if ($_ !== null) { if (is_int($_)) { // specific return ['src.src' . $_, null, '!']; } else { if ($_) { $foo = ['OR']; foreach ($this->enums[$cr[0]] as $bar) { if (is_int($bar)) { $foo[] = ['src.src' . $bar, null, '!']; } } return $foo; } else { if (!$_) { $foo = ['AND']; foreach ($this->enums[$cr[0]] as $bar) { if (is_int($bar)) { $foo[] = ['src.src' . $bar, null]; } } return $foo; } } } } break; } unset($cr); $this->error = 1; return [1]; }
function source(array $ids = []) { $insBasic = 'INSERT INTO ?_source (`type`, typeId, src?d) VALUES [V] ON DUPLICATE KEY UPDATE moreType = NULL, moreTypeId = NULL, src?d = VALUES(src?d)'; $insMore = 'INSERT INTO ?_source (`type`, typeId, src?d, moreType, moreTypeId) VALUES [V] ON DUPLICATE KEY UPDATE moreType = NULL, moreTypeId = NULL, src?d = VALUES(src?d)'; $insSub = 'INSERT INTO ?_source (`type`, typeId, src?d, moreType, moreTypeId) ?s ON DUPLICATE KEY UPDATE moreType = NULL, moreTypeId = NULL, src?d = VALUES(src?d)'; // please note, this workes without checks, because we do not use strings here function queryfy($ph, array $data, $query) { $buff = []; array_walk_recursive($data, function (&$item) { if ($item === null) { $item = 'NULL'; } }); foreach ($data as $d) { $buff[] = '(' . implode(', ', $d ?: 'NULL') . ')'; } return str_replace($ph, implode(', ', $buff), $query); } function pushBuffer(&$buff, $type, $typeId, $mType = 0, $mTypeId = 0, $src = 1) { $b =& $buff[$typeId]; if (isset($b) && $b[3] === null) { return; } else { if (isset($b) && $b[1] != $typeId) { $b[3] = $b[4] = null; $b[2] |= $src; // only quests atm } else { if ($mType && $mTypeId) { $b = [$type, $typeId, $src, $mType, $mTypeId]; } else { $b = [$type, $typeId, $src, null, null]; } } } } function taughtSpell($item) { # spelltrigger_X (0: onUse; 6: onLearnSpell) # spell: 483 & 55884 are learn spells // should not be able to teach spells (recipe || mount || vanityPet) if ($item['class'] != ITEM_CLASS_RECIPE && ($item['class'] != ITEM_CLASS_MISC || $item['subclass'] != 2 && $item['subclass'] != 5)) { return 0; } // wotlk system if (($item['spellid_1'] == 483 || $item['spellid_1'] == 55884) && $item['spelltrigger_1'] == 0 && $item['spellid_2'] > 0 && $item['spelltrigger_2'] == 6) { return $item['spellid_2']; } // deprecated system if ($item['spellid_1'] != 483 && $item['spellid_1'] != 55884 && $item['spellid_1'] > 0 && $item['spelltrigger_1'] == 0) { return $item['spellid_1']; } return 0; } // cant update existing rows if ($ids) { DB::Aowow()->query('DELETE FROM ?_source WHERE `type` = ?d AND typeId IN (?a)', $well, $wellll); } else { DB::Aowow()->query('TRUNCATE TABLE ?_source'); } /***************************/ /* Item & inherited Spells */ /***************************/ CLISetup::log(' - Items & Spells [inherited]'); # also everything from items that teach spells, is src of spell # todo: check if items have learn-spells (effect: 36) CLISetup::log(' * resolve ref-loot tree'); $refLoot = DB::World()->select(' SELECT rlt.Entry AS ARRAY_KEY, IF(Reference, -Reference, Item) AS ARRAY_KEY2, it.entry, it.class, it.subclass, it.spellid_1, it.spelltrigger_1, it.spellid_2, it.spelltrigger_2, COUNT(1) AS qty FROM reference_loot_template rlt LEFT JOIN item_template it ON rlt.Reference = 0 AND rlt.Item = it.entry GROUP BY ARRAY_KEY, ARRAY_KEY2 '); $hasChanged = true; while ($hasChanged) { $hasChanged = false; foreach ($refLoot as $entry => &$refData) { foreach ($refData as $itemOrRef => $data) { if ($itemOrRef > 0) { continue; } if (!empty($refLoot[-$itemOrRef])) { foreach ($refLoot[-$itemOrRef] as $key => $data) { if (!empty($refData[$key])) { $refData[$key]['qty'] += $data['qty']; } else { $refLoot[-$itemOrRef][$key] = $data; } } } unset($refData[$itemOrRef]); $hasChanged = true; } } } ############### # 1: Crafted # ############### CLISetup::log(' * #1 Crafted'); $spellBuff = []; $itemBuff = []; $itemSpells = DB::Aowow()->selectCol(' SELECT effect1CreateItemId AS ARRAY_KEY, s.id AS spell FROM dbc_spell s JOIN dbc_skilllineability sla ON s.id = sla.spellId WHERE effect1CreateItemId > 0 AND sla.skillLineId IN (?a) GROUP BY ARRAY_KEY', [164, 165, 171, 182, 186, 197, 202, 333, 393, 755, 773, 129, 185, 356, 762]); $spellItems = DB::World()->select('SELECT entry AS ARRAY_KEY, class, subclass, spellid_1, spelltrigger_1, spellid_2, spelltrigger_2 FROM item_template WHERE entry IN (?a)', array_keys($itemSpells)); foreach ($spellItems as $iId => $si) { if ($_ = taughtSpell($si)) { $spellBuff[$_] = [TYPE_SPELL, $_, 1, TYPE_SPELL, $itemSpells[$iId]]; } $itemBuff[$iId] = [TYPE_ITEM, $iId, 1, TYPE_SPELL, $itemSpells[$iId]]; } if ($itemBuff) { DB::Aowow()->query(queryfy('[V]', $itemBuff, $insMore), 1, 1, 1); } if ($spellBuff) { DB::Aowow()->query(queryfy('[V]', $spellBuff, $insMore), 1, 1, 1); } ############ # 2: Drop # ############ CLISetup::log(' * #2 Drop'); $spellBuff = []; $itemBuff = []; $creatureLoot = DB::World()->select(' SELECT IF(clt.Reference > 0, -clt.Reference, clt.Item) AS ARRAY_KEY, ct.entry, it.class, it.subclass, it.spellid_1, it.spelltrigger_1, it.spellid_2, it.spelltrigger_2, count(1) AS qty FROM creature_loot_template clt JOIN creature_template ct ON clt.entry = ct.lootid LEFT JOIN item_template it ON it.entry = clt.Item AND clt.Reference <= 0 WHERE ct.lootid > 0 GROUP BY ARRAY_KEY '); foreach ($creatureLoot as $roi => $l) { if ($roi < 0 && !empty($refLoot[-$roi])) { foreach ($refLoot[-$roi] as $iId => $r) { if ($_ = taughtSpell($r)) { pushBuffer($spellBuff, TYPE_SPELL, $_, $r['qty'] > 1 ? 0 : TYPE_NPC, $l['entry']); } pushBuffer($itemBuff, TYPE_ITEM, $iId, $r['qty'] > 1 ? 0 : TYPE_NPC, $l['entry']); } continue; } if ($_ = taughtSpell($l)) { pushBuffer($spellBuff, TYPE_SPELL, $_, $l['qty'] > 1 ? 0 : TYPE_NPC, $l['entry']); } pushBuffer($itemBuff, TYPE_ITEM, $roi, $l['qty'] > 1 ? 0 : TYPE_NPC, $l['entry']); } $objectOT = []; $exclLocks = DB::Aowow()->selectCol('SELECT id FROM dbc_lock WHERE properties1 IN (2, 3)'); $objectLoot = DB::World()->select(' SELECT IF(glt.Reference > 0, -glt.Reference, glt.Item) AS ARRAY_KEY, gt.entry, it.class, it.subclass, it.spellid_1, it.spelltrigger_1, it.spellid_2, it.spelltrigger_2, count(1) AS qty FROM gameobject_loot_template glt JOIN gameobject_template gt ON glt.entry = gt.Data1 LEFT JOIN item_template it ON it.entry = glt.Item AND glt.Reference <= 0 WHERE `type` = 3 AND gt.Data1 > 0 AND gt.Data0 NOT IN (?a) GROUP BY ARRAY_KEY', $exclLocks); foreach ($objectLoot as $roi => $l) { if ($roi < 0 && !empty($refLoot[-$roi])) { foreach ($refLoot[-$roi] as $iId => $r) { if ($_ = taughtSpell($r)) { pushBuffer($spellBuff, TYPE_SPELL, $_, $r['qty'] > 1 ? 0 : TYPE_OBJECT, $l['entry']); } $objectOT[] = $iId; pushBuffer($itemBuff, TYPE_ITEM, $iId, $r['qty'] > 1 ? 0 : TYPE_OBJECT, $l['entry']); } continue; } if ($_ = taughtSpell($l)) { pushBuffer($spellBuff, TYPE_SPELL, $_, $l['qty'] > 1 ? 0 : TYPE_OBJECT, $l['entry']); } $objectOT[] = $roi; pushBuffer($itemBuff, TYPE_ITEM, $roi, $l['qty'] > 1 ? 0 : TYPE_OBJECT, $l['entry']); } $itemOT = []; $itemLoot = DB::World()->select(' SELECT IF(ilt.Reference > 0, -ilt.Reference, ilt.Item) AS ARRAY_KEY, itA.entry, itB.class, itB.subclass, itB.spellid_1, itB.spelltrigger_1, itB.spellid_2, itB.spelltrigger_2, count(1) AS qty FROM item_loot_template ilt JOIN item_template itA ON ilt.entry = itA.entry LEFT JOIN item_template itB ON itB.entry = ilt.Item AND ilt.Reference <= 0 WHERE itA.flags & 0x4 GROUP BY ARRAY_KEY '); foreach ($itemLoot as $roi => $l) { if ($roi < 0 && !empty($refLoot[-$roi])) { foreach ($refLoot[-$roi] as $iId => $r) { if ($_ = taughtSpell($r)) { pushBuffer($spellBuff, TYPE_SPELL, $_, $r['qty'] > 1 ? 0 : TYPE_ITEM, $l['entry']); } $itemOT[] = $iId; pushBuffer($itemBuff, TYPE_ITEM, $iId, $r['qty'] > 1 ? 0 : TYPE_ITEM, $l['entry']); } continue; } if ($_ = taughtSpell($l)) { pushBuffer($spellBuff, TYPE_SPELL, $_, $l['qty'] > 1 ? 0 : TYPE_ITEM, $l['entry']); } $itemOT[] = $roi; pushBuffer($itemBuff, TYPE_ITEM, $roi, $l['qty'] > 1 ? 0 : TYPE_ITEM, $l['entry']); } if ($itemBuff) { DB::Aowow()->query(queryfy('[V]', $itemBuff, $insMore), 2, 2, 2); } if ($spellBuff) { DB::Aowow()->query(queryfy('[V]', $spellBuff, $insMore), 2, 2, 2); } DB::Aowow()->query('UPDATE ?_items SET cuFLags = cuFlags | ?d WHERE id IN (?a)', ITEM_CU_OT_ITEMLOOT, $itemOT); DB::Aowow()->query('UPDATE ?_items SET cuFLags = cuFlags | ?d WHERE id IN (?a)', ITEM_CU_OT_OBJECTLOOT, $objectOT); ########### # 3: PvP # (Vendors w/ xCost Arena/Honor) ########### CLISetup::log(' * #3 PvP'); // var g_sources_pvp = { // 1: 'Arena', // 2: 'Battleground', // 4: 'World' basicly the tokens you get for openPvP .. manual data // }; $spellBuff = []; $itemBuff = []; $xCostH = DB::Aowow()->selectCol('SELECT Id FROM dbc_itemextendedcost WHERE reqHonorPoints > 0 AND reqArenaPoints = 0'); $xCostA = DB::Aowow()->selectCol('SELECT Id FROM dbc_itemextendedcost WHERE reqArenaPoints > 0'); $vendorQuery = 'SELECT n.item AS ARRAY_KEY, SUM(n.qty) AS qty, it.class, it.subclass, it.spellid_1, it.spelltrigger_1, it.spellid_2, it.spelltrigger_2 FROM ( SELECT item, COUNT(1) AS qty FROM npc_vendor WHERE ExtendedCost IN (?a) GROUP BY item UNION SELECT item, COUNT(1) AS qty FROM game_event_npc_vendor genv JOIN creature c ON c.guid = genv.guid WHERE ExtendedCost IN (?a) GROUP BY item ) n JOIN item_template it ON it.entry = n.item GROUP BY item'; foreach (DB::World()->select($vendorQuery, $xCostA, $xCostA) as $iId => $v) { if ($_ = taughtSpell($v)) { $spellBuff[$_] = [TYPE_SPELL, $_, 1]; } $itemBuff[$iId] = [TYPE_ITEM, $iId, 1]; } foreach (DB::World()->select($vendorQuery, $xCostH, $xCostH) as $iId => $v) { if ($_ = taughtSpell($v)) { $spellBuff[$_] = [TYPE_SPELL, $_, 2]; } $itemBuff[$iId] = [TYPE_ITEM, $iId, 2]; } if ($itemBuff) { DB::Aowow()->query(queryfy('[V]', $itemBuff, $insBasic), 3, 3, 3); } if ($spellBuff) { DB::Aowow()->query(queryfy('[V]', $spellBuff, $insBasic), 3, 3, 3); } ############# # 4: Quest # ############# CLISetup::log(' * #4 Quest'); $spellBuff = []; $itemBuff = []; $quests = DB::World()->select('SELECT n.item AS ARRAY_KEY, n.ID AS quest, SUM(n.qty) AS qty, BIT_OR(n.side) AS side, it.class, it.subclass, it.spellid_1, it.spelltrigger_1, it.spellid_2, it.spelltrigger_2 FROM ( SELECT RewardChoiceItemID1 AS item, ID, COUNT(1) AS qty, IF(RequiredRaces & 0x2B2 AND !(RequiredRaces & 0x44D), 2, IF(RequiredRaces & 0x44D AND !(RequiredRaces & 0x2B2), 1, 3)) AS side FROM quest_template WHERE RewardChoiceItemID1 > 0 GROUP BY item UNION SELECT RewardChoiceItemID2 AS item, ID, COUNT(1) AS qty, IF(RequiredRaces & 0x2B2 AND !(RequiredRaces & 0x44D), 2, IF(RequiredRaces & 0x44D AND !(RequiredRaces & 0x2B2), 1, 3)) AS side FROM quest_template WHERE RewardChoiceItemID2 > 0 GROUP BY item UNION SELECT RewardChoiceItemID3 AS item, ID, COUNT(1) AS qty, IF(RequiredRaces & 0x2B2 AND !(RequiredRaces & 0x44D), 2, IF(RequiredRaces & 0x44D AND !(RequiredRaces & 0x2B2), 1, 3)) AS side FROM quest_template WHERE RewardChoiceItemID3 > 0 GROUP BY item UNION SELECT RewardChoiceItemID4 AS item, ID, COUNT(1) AS qty, IF(RequiredRaces & 0x2B2 AND !(RequiredRaces & 0x44D), 2, IF(RequiredRaces & 0x44D AND !(RequiredRaces & 0x2B2), 1, 3)) AS side FROM quest_template WHERE RewardChoiceItemID4 > 0 GROUP BY item UNION SELECT RewardChoiceItemID5 AS item, ID, COUNT(1) AS qty, IF(RequiredRaces & 0x2B2 AND !(RequiredRaces & 0x44D), 2, IF(RequiredRaces & 0x44D AND !(RequiredRaces & 0x2B2), 1, 3)) AS side FROM quest_template WHERE RewardChoiceItemID5 > 0 GROUP BY item UNION SELECT RewardChoiceItemID6 AS item, ID, COUNT(1) AS qty, IF(RequiredRaces & 0x2B2 AND !(RequiredRaces & 0x44D), 2, IF(RequiredRaces & 0x44D AND !(RequiredRaces & 0x2B2), 1, 3)) AS side FROM quest_template WHERE RewardChoiceItemID6 > 0 GROUP BY item UNION SELECT RewardItem1 AS item, ID, COUNT(1) AS qty, IF(RequiredRaces & 0x2B2 AND !(RequiredRaces & 0x44D), 2, IF(RequiredRaces & 0x44D AND !(RequiredRaces & 0x2B2), 1, 3)) AS side FROM quest_template WHERE RewardItem1 > 0 GROUP BY item UNION SELECT RewardItem2 AS item, ID, COUNT(1) AS qty, IF(RequiredRaces & 0x2B2 AND !(RequiredRaces & 0x44D), 2, IF(RequiredRaces & 0x44D AND !(RequiredRaces & 0x2B2), 1, 3)) AS side FROM quest_template WHERE RewardItem2 > 0 GROUP BY item UNION SELECT RewardItem3 AS item, ID, COUNT(1) AS qty, IF(RequiredRaces & 0x2B2 AND !(RequiredRaces & 0x44D), 2, IF(RequiredRaces & 0x44D AND !(RequiredRaces & 0x2B2), 1, 3)) AS side FROM quest_template WHERE RewardItem3 > 0 GROUP BY item UNION SELECT RewardItem4 AS item, ID, COUNT(1) AS qty, IF(RequiredRaces & 0x2B2 AND !(RequiredRaces & 0x44D), 2, IF(RequiredRaces & 0x44D AND !(RequiredRaces & 0x2B2), 1, 3)) AS side FROM quest_template WHERE RewardItem4 > 0 GROUP BY item ) n JOIN item_template it ON it.entry = n.item GROUP BY item'); foreach ($quests as $iId => $q) { if ($_ = taughtSpell($q)) { pushBuffer($spellBuff, TYPE_SPELL, $_, $q['qty'] > 1 ? 0 : TYPE_QUEST, $q['quest'], $q['side']); } pushBuffer($itemBuff, TYPE_ITEM, $iId, $q['qty'] > 1 ? 0 : TYPE_QUEST, $q['quest'], $q['side']); } $mailLoot = DB::World()->select(' SELECT IF(mlt.Reference > 0, -mlt.Reference, mlt.Item) AS ARRAY_KEY, qt.ID AS entry, it.class, it.subclass, it.spellid_1, it.spelltrigger_1, it.spellid_2, it.spelltrigger_2, count(1) AS qty, BIT_OR(IF(qt.RequiredRaces & 0x2B2 AND !(qt.RequiredRaces & 0x44D), 2, IF(qt.RequiredRaces & 0x44D AND !(qt.RequiredRaces & 0x2B2), 1, 3))) AS side FROM mail_loot_template mlt JOIN quest_template qt ON qt.RewardMailTemplateId = mlt.entry LEFT JOIN item_template it ON it.entry = mlt.Item AND mlt.Reference <= 0 WHERE qt.RewardMailTemplateId > 0 GROUP BY ARRAY_KEY '); foreach ($mailLoot as $roi => $l) { if ($roi < 0 && !empty($refLoot[-$roi])) { foreach ($refLoot[-$roi] as $iId => $r) { if ($_ = taughtSpell($r)) { pushBuffer($spellBuff, TYPE_SPELL, $_, $r['qty'] > 1 ? 0 : TYPE_QUEST, $l['entry'], $l['side']); } $itemOT[] = $iId; pushBuffer($itemBuff, TYPE_ITEM, $iId, $r['qty'] > 1 ? 0 : TYPE_QUEST, $l['entry'], $l['side']); } continue; } if ($_ = taughtSpell($l)) { pushBuffer($spellBuff, TYPE_SPELL, $_, $l['qty'] > 1 ? 0 : TYPE_QUEST, $l['entry'], $l['side']); } $itemOT[] = $roi; pushBuffer($itemBuff, TYPE_ITEM, $roi, $l['qty'] > 1 ? 0 : TYPE_QUEST, $l['entry'], $l['side']); } if ($itemBuff) { DB::Aowow()->query(queryfy('[V]', $itemBuff, $insMore), 4, 4, 4); } if ($spellBuff) { DB::Aowow()->query(queryfy('[V]', $spellBuff, $insMore), 4, 4, 4); } ############## # 5: Vendor # (w/o xCost Arena/Honor) ############## CLISetup::log(' * #5 Vendor'); $spellBuff = []; $itemBuff = []; $xCostIds = DB::Aowow()->selectCol('SELECT Id FROM dbc_itemextendedcost WHERE reqHonorPoints <> 0 OR reqArenaPoints <> 0'); $vendors = DB::World()->select('SELECT n.item AS ARRAY_KEY, n.npc, SUM(n.qty) AS qty, it.class, it.subclass, it.spellid_1, it.spelltrigger_1, it.spellid_2, it.spelltrigger_2 FROM ( SELECT item, entry AS npc, COUNT(1) AS qty FROM npc_vendor WHERE ExtendedCost NOT IN (?a) GROUP BY item UNION SELECT item, c.id AS npc, COUNT(1) AS qty FROM game_event_npc_vendor genv JOIN creature c ON c.guid = genv.guid WHERE ExtendedCost NOT IN (?a) GROUP BY item ) n JOIN item_template it ON it.entry = n.item GROUP BY item', $xCostIds, $xCostIds); foreach ($vendors as $iId => $v) { if ($_ = taughtSpell($v)) { pushBuffer($spellBuff, TYPE_SPELL, $_, $v['qty'] > 1 ? 0 : TYPE_NPC, $v['npc']); } pushBuffer($itemBuff, TYPE_ITEM, $iId, $v['qty'] > 1 ? 0 : TYPE_NPC, $v['npc']); } if ($itemBuff) { DB::Aowow()->query(queryfy('[V]', $itemBuff, $insMore), 5, 5, 5); } if ($spellBuff) { DB::Aowow()->query(queryfy('[V]', $spellBuff, $insMore), 5, 5, 5); } ############### # 10: Starter # ############### CLISetup::log(' * #10 Starter'); if ($pcii = DB::World()->select('SELECT ?d, itemid, 1 FROM playercreateinfo_item', TYPE_ITEM)) { DB::Aowow()->query(queryfy('[V]', $pcii, $insBasic), 10, 10, 10); } for ($i = 1; $i < 21; $i++) { DB::Aowow()->query($insSub, 10, DB::Aowow()->subquery('SELECT ?d, item?d, 1, NULL AS m, NULL AS mt FROM dbc_charstartoutfit WHERE item?d > 0', TYPE_ITEM, $i, $i), 10, 10); } ################### # 12: Achievement # ################### CLISetup::log(' * #12 Achievement'); $spellBuff = []; $itemBuff = []; $xItems = DB::Aowow()->select('SELECT id AS entry, itemExtra AS ARRAY_KEY, COUNT(1) AS qty FROM ?_achievement WHERE itemExtra > 0 GROUP BY itemExtra'); $rewItems = DB::World()->select(' SELECT src.item AS ARRAY_KEY, src.entry, it.class, it.subclass, it.spellid_1, it.spelltrigger_1, it.spellid_2, it.spelltrigger_2, COUNT(1) AS qty FROM ( SELECT IFNULL(IF(mlt.Reference > 0, -mlt.Reference, mlt.Item), ar.item) AS item, ar.entry FROM achievement_reward ar LEFT JOIN mail_loot_template mlt ON mlt.entry = ar.mailTemplate WHERE ar.mailTemplate > 0 OR ar.item > 0 ) src LEFT JOIN item_template it ON src.item = it.entry GROUP BY ARRAY_KEY '); $extraItems = DB::World()->select('SELECT entry AS ARRAY_KEY, class, subclass, spellid_1, spelltrigger_1, spellid_2, spelltrigger_2 FROM item_template WHERE entry IN (?a)', array_keys($xItems)); foreach ($extraItems as $iId => $l) { if ($_ = taughtSpell($l)) { pushBuffer($spellBuff, TYPE_SPELL, $_, $xItems[$iId]['qty'] > 1 ? 0 : TYPE_ACHIEVEMENT, $xItems[$iId]['entry']); } pushBuffer($itemBuff, TYPE_ITEM, $iId, $xItems[$iId]['qty'] > 1 ? 0 : TYPE_ACHIEVEMENT, $xItems[$iId]['entry']); } foreach ($rewItems as $iId => $l) { if ($roi < 0 && !empty($refLoot[-$roi])) { foreach ($refLoot[-$roi] as $iId => $r) { if ($_ = taughtSpell($r)) { pushBuffer($spellBuff, TYPE_SPELL, $_, $l['qty'] > 1 ? 0 : TYPE_ACHIEVEMENT, $l['entry']); } pushBuffer($itemBuff, TYPE_ITEM, $iId, $l['qty'] > 1 ? 0 : TYPE_ACHIEVEMENT, $l['entry']); } continue; } if ($_ = taughtSpell($l)) { pushBuffer($spellBuff, TYPE_SPELL, $_, $l['qty'] > 1 ? 0 : TYPE_ACHIEVEMENT, $l['entry']); } pushBuffer($itemBuff, TYPE_ITEM, $iId, $l['qty'] > 1 ? 0 : TYPE_ACHIEVEMENT, $l['entry']); } if ($itemBuff) { DB::Aowow()->query(queryfy('[V]', $itemBuff, $insMore), 12, 12, 12); } if ($spellBuff) { DB::Aowow()->query(queryfy('[V]', $spellBuff, $insMore), 12, 12, 12); } #################### # 15: Disenchanted # #################### CLISetup::log(' * #15 Disenchanted'); $spellBuff = []; $itemBuff = []; $deLoot = DB::World()->select(' SELECT IF(dlt.Reference > 0, -dlt.Reference, dlt.Item) AS ARRAY_KEY, itA.entry, itB.class, itB.subclass, itB.spellid_1, itB.spelltrigger_1, itB.spellid_2, itB.spelltrigger_2, count(1) AS qty FROM disenchant_loot_template dlt JOIN item_template itA ON dlt.entry = itA.DisenchantId LEFT JOIN item_template itB ON itB.entry = dlt.Item AND dlt.Reference <= 0 WHERE itA.DisenchantId > 0 GROUP BY ARRAY_KEY '); foreach ($deLoot as $roi => $l) { if ($roi < 0 && !empty($refLoot[-$roi])) { foreach ($refLoot[-$roi] as $iId => $r) { if ($_ = taughtSpell($r)) { pushBuffer($spellBuff, TYPE_SPELL, $_); } pushBuffer($itemBuff, TYPE_ITEM, $iId); } continue; } if ($_ = taughtSpell($l)) { pushBuffer($spellBuff, TYPE_SPELL, $_); } pushBuffer($itemBuff, TYPE_ITEM, $roi); } if ($itemBuff) { DB::Aowow()->query(queryfy('[V]', $itemBuff, $insMore), 15, 15, 15); } if ($spellBuff) { DB::Aowow()->query(queryfy('[V]', $spellBuff, $insMore), 15, 15, 15); } ############## # 16: Fished # ############## CLISetup::log(' * #16 Fished'); $spellBuff = []; $itemBuff = []; $fishLoot = DB::World()->select(' SELECT src.itemOrRef AS ARRAY_KEY, src.entry, it.class, it.subclass, it.spellid_1, it.spelltrigger_1, it.spellid_2, it.spelltrigger_2, count(1) AS qty FROM ( SELECT 0 AS entry, IF(flt.Reference > 0, -flt.Reference, flt.Item) itemOrRef FROM fishing_loot_template flt UNION SELECT gt.entry, IF(glt.Reference > 0, -glt.Reference, glt.Item) itemOrRef FROM gameobject_template gt JOIN gameobject_loot_template glt ON glt.entry = gt.Data1 WHERE `type` = 25 AND gt.Data1 > 0 ) src LEFT JOIN item_template it ON src.itemOrRef > 0 AND src.itemOrRef = it.entry GROUP BY ARRAY_KEY '); foreach ($fishLoot as $roi => $l) { if ($roi < 0 && !empty($refLoot[-$roi])) { foreach ($refLoot[-$roi] as $iId => $r) { if ($_ = taughtSpell($r)) { pushBuffer($spellBuff, TYPE_SPELL, $_, $r['qty'] > 1 ? 0 : TYPE_OBJECT, $l['entry']); } pushBuffer($itemBuff, TYPE_ITEM, $iId, $r['qty'] > 1 ? 0 : TYPE_OBJECT, $l['entry']); } continue; } if ($_ = taughtSpell($l)) { pushBuffer($spellBuff, TYPE_SPELL, $_, $l['qty'] > 1 ? 0 : TYPE_OBJECT, $l['entry']); } pushBuffer($itemBuff, TYPE_ITEM, $roi, $l['qty'] > 1 ? 0 : TYPE_OBJECT, $l['entry']); } if ($itemBuff) { DB::Aowow()->query(queryfy('[V]', $itemBuff, $insMore), 16, 16, 16); } if ($spellBuff) { DB::Aowow()->query(queryfy('[V]', $spellBuff, $insMore), 16, 16, 16); } ################ # 17: Gathered # ################ CLISetup::log(' * #17 Gathered'); $spellBuff = []; $itemBuff = []; $herbLocks = DB::Aowow()->selectCol('SELECT id FROM dbc_lock WHERE properties1 = 2'); $herbLoot = DB::World()->select(' SELECT src.itemOrRef AS ARRAY_KEY, src.entry, it.class, it.subclass, it.spellid_1, it.spelltrigger_1, it.spellid_2, it.spelltrigger_2, count(1) AS qty, src.srcType FROM ( SELECT ct.entry, IF(slt.Reference > 0, -slt.Reference, slt.Item) itemOrRef, ?d AS srcType FROM creature_template ct JOIN skinning_loot_template slt ON slt.entry = ct.skinloot WHERE (type_flags & ?d) AND ct.skinloot > 0 UNION SELECT gt.entry, IF(glt.Reference > 0, -glt.Reference, glt.Item) itemOrRef, ?d AS srcType FROM gameobject_template gt JOIN gameobject_loot_template glt ON glt.entry = gt.Data1 WHERE gt.`type` = 3 AND gt.Data1 > 0 AND Data0 IN (?a) ) src LEFT JOIN item_template it ON src.itemOrRef > 0 AND src.itemOrRef = it.entry GROUP BY ARRAY_KEY', TYPE_NPC, NPC_TYPEFLAG_HERBLOOT, TYPE_OBJECT, $herbLocks); foreach ($herbLoot as $roi => $l) { if ($roi < 0 && !empty($refLoot[-$roi])) { foreach ($refLoot[-$roi] as $iId => $r) { if ($_ = taughtSpell($r)) { pushBuffer($spellBuff, TYPE_SPELL, $_, $r['qty'] > 1 ? 0 : $l['srcType'], $l['entry']); } pushBuffer($itemBuff, TYPE_ITEM, $iId, $r['qty'] > 1 ? 0 : $l['srcType'], $l['entry']); } continue; } if ($_ = taughtSpell($l)) { pushBuffer($spellBuff, TYPE_SPELL, $_, $l['qty'] > 1 ? 0 : $l['srcType'], $l['entry']); } pushBuffer($itemBuff, TYPE_ITEM, $roi, $l['qty'] > 1 ? 0 : $l['srcType'], $l['entry']); } if ($itemBuff) { DB::Aowow()->query(queryfy('[V]', $itemBuff, $insMore), 17, 17, 17); } if ($spellBuff) { DB::Aowow()->query(queryfy('[V]', $spellBuff, $insMore), 17, 17, 17); } ############## # 18: Milled # ############## CLISetup::log(' * #18 Milled'); $spellBuff = []; $itemBuff = []; $millLoot = DB::World()->select(' SELECT IF(mlt.Reference > 0, -mlt.Reference, mlt.Item) AS ARRAY_KEY, itA.entry, itB.class, itB.subclass, itB.spellid_1, itB.spelltrigger_1, itB.spellid_2, itB.spelltrigger_2, count(1) AS qty FROM milling_loot_template mlt JOIN item_template itA ON mlt.entry = itA.entry LEFT JOIN item_template itB ON itB.entry = mlt.Item AND mlt.Reference <= 0 GROUP BY ARRAY_KEY '); foreach ($millLoot as $roi => $l) { if ($roi < 0 && !empty($refLoot[-$roi])) { foreach ($refLoot[-$roi] as $iId => $r) { if ($_ = taughtSpell($r)) { pushBuffer($spellBuff, TYPE_SPELL, $_); } pushBuffer($itemBuff, TYPE_ITEM, $iId); } continue; } if ($_ = taughtSpell($l)) { pushBuffer($spellBuff, TYPE_SPELL, $_); } pushBuffer($itemBuff, TYPE_ITEM, $roi); } if ($itemBuff) { DB::Aowow()->query(queryfy('[V]', $itemBuff, $insMore), 18, 18, 18); } if ($spellBuff) { DB::Aowow()->query(queryfy('[V]', $spellBuff, $insMore), 18, 18, 18); } ############# # 19: Mined # ############# CLISetup::log(' * #19 Mined'); $spellBuff = []; $itemBuff = []; $mineLocks = DB::Aowow()->selectCol('SELECT id FROM dbc_lock WHERE properties1 = 3'); $mineLoot = DB::World()->select(' SELECT src.itemOrRef AS ARRAY_KEY, src.entry, it.class, it.subclass, it.spellid_1, it.spelltrigger_1, it.spellid_2, it.spelltrigger_2, count(1) AS qty, src.srcType FROM ( SELECT ct.entry, IF(slt.Reference > 0, -slt.Reference, slt.Item) itemOrRef, ?d AS srcType FROM creature_template ct JOIN skinning_loot_template slt ON slt.entry = ct.skinloot WHERE (type_flags & ?d) AND ct.skinloot > 0 UNION SELECT gt.entry, IF(glt.Reference > 0, -glt.Reference, glt.Item) itemOrRef, ?d AS srcType FROM gameobject_template gt JOIN gameobject_loot_template glt ON glt.entry = gt.Data1 WHERE gt.`type` = 3 AND gt.Data1 > 0 AND Data0 IN (?a) ) src LEFT JOIN item_template it ON src.itemOrRef > 0 AND src.itemOrRef = it.entry GROUP BY ARRAY_KEY', TYPE_NPC, NPC_TYPEFLAG_MININGLOOT, TYPE_OBJECT, $mineLocks); foreach ($mineLoot as $roi => $l) { if ($roi < 0 && !empty($refLoot[-$roi])) { foreach ($refLoot[-$roi] as $iId => $r) { if ($_ = taughtSpell($r)) { pushBuffer($spellBuff, TYPE_SPELL, $_, $r['qty'] > 1 ? 0 : $l['srcType'], $l['entry']); } pushBuffer($itemBuff, TYPE_ITEM, $iId, $r['qty'] > 1 ? 0 : $l['srcType'], $l['entry']); } continue; } if ($_ = taughtSpell($l)) { pushBuffer($spellBuff, TYPE_SPELL, $_, $l['qty'] > 1 ? 0 : $l['srcType'], $l['entry']); } pushBuffer($itemBuff, TYPE_ITEM, $roi, $l['qty'] > 1 ? 0 : $l['srcType'], $l['entry']); } if ($itemBuff) { DB::Aowow()->query(queryfy('[V]', $itemBuff, $insMore), 19, 19, 19); } if ($spellBuff) { DB::Aowow()->query(queryfy('[V]', $spellBuff, $insMore), 19, 19, 19); } ################## # 20: Prospected # ################## CLISetup::log(' * #20 Prospected'); $spellBuff = []; $itemBuff = []; $prospectLoot = DB::World()->select(' SELECT IF(plt.Reference > 0, -plt.Reference, plt.Item) AS ARRAY_KEY, itA.entry, itB.class, itB.subclass, itB.spellid_1, itB.spelltrigger_1, itB.spellid_2, itB.spelltrigger_2, count(1) AS qty FROM prospecting_loot_template plt JOIN item_template itA ON plt.entry = itA.entry LEFT JOIN item_template itB ON itB.entry = plt.Item AND plt.Reference <= 0 GROUP BY ARRAY_KEY '); foreach ($prospectLoot as $roi => $l) { if ($roi < 0 && !empty($refLoot[-$roi])) { foreach ($refLoot[-$roi] as $iId => $r) { if ($_ = taughtSpell($r)) { pushBuffer($spellBuff, TYPE_SPELL, $_); } pushBuffer($itemBuff, TYPE_ITEM, $iId); } continue; } if ($_ = taughtSpell($l)) { pushBuffer($spellBuff, TYPE_SPELL, $_); } pushBuffer($itemBuff, TYPE_ITEM, $roi); } if ($itemBuff) { DB::Aowow()->query(queryfy('[V]', $itemBuff, $insMore), 20, 20, 20); } if ($spellBuff) { DB::Aowow()->query(queryfy('[V]', $spellBuff, $insMore), 20, 20, 20); } ################## # 21: Pickpocket # ################## CLISetup::log(' * #21 Pickpocket'); $spellBuff = []; $itemBuff = []; $theftLoot = DB::World()->select(' SELECT src.itemOrRef AS ARRAY_KEY, src.entry, it.class, it.subclass, it.spellid_1, it.spelltrigger_1, it.spellid_2, it.spelltrigger_2, COUNT(1) AS qty FROM ( SELECT ct.entry, IF(plt.Reference > 0, -plt.Reference, plt.Item) itemOrRef FROM creature_template ct JOIN pickpocketing_loot_template plt ON plt.entry = ct.pickpocketloot WHERE ct.pickpocketloot > 0 ) src LEFT JOIN item_template it ON src.itemOrRef > 0 AND src.itemOrRef = it.entry GROUP BY ARRAY_KEY '); foreach ($theftLoot as $roi => $l) { if ($roi < 0 && !empty($refLoot[-$roi])) { foreach ($refLoot[-$roi] as $iId => $r) { if ($_ = taughtSpell($r)) { pushBuffer($spellBuff, TYPE_SPELL, $_, $r['qty'] > 1 ? 0 : TYPE_NPC, $l['entry']); } pushBuffer($itemBuff, TYPE_ITEM, $iId, $r['qty'] > 1 ? 0 : TYPE_NPC, $l['entry']); } continue; } if ($_ = taughtSpell($l)) { pushBuffer($spellBuff, TYPE_SPELL, $_, $l['qty'] > 1 ? 0 : TYPE_NPC, $l['entry']); } pushBuffer($itemBuff, TYPE_ITEM, $roi, $l['qty'] > 1 ? 0 : TYPE_NPC, $l['entry']); } if ($itemBuff) { DB::Aowow()->query(queryfy('[V]', $itemBuff, $insMore), 21, 21, 21); } if ($spellBuff) { DB::Aowow()->query(queryfy('[V]', $spellBuff, $insMore), 21, 21, 21); } ################ # 22: Salvaged # ################ CLISetup::log(' * #22 Salvaged'); $spellBuff = []; $itemBuff = []; $salvageLoot = DB::World()->select(' SELECT src.itemOrRef AS ARRAY_KEY, src.entry, it.class, it.subclass, it.spellid_1, it.spelltrigger_1, it.spellid_2, it.spelltrigger_2, COUNT(1) AS qty FROM ( SELECT ct.entry, IF(slt.Reference > 0, -slt.Reference, slt.Item) itemOrRef FROM creature_template ct JOIN skinning_loot_template slt ON slt.entry = ct.skinloot WHERE (type_flags & ?d) AND ct.skinloot > 0 ) src LEFT JOIN item_template it ON src.itemOrRef > 0 AND src.itemOrRef = it.entry GROUP BY ARRAY_KEY', NPC_TYPEFLAG_ENGINEERLOOT); foreach ($salvageLoot as $roi => $l) { if ($roi < 0 && !empty($refLoot[-$roi])) { foreach ($refLoot[-$roi] as $iId => $r) { if ($_ = taughtSpell($r)) { pushBuffer($spellBuff, TYPE_SPELL, $_, $r['qty'] > 1 ? 0 : TYPE_NPC, $l['entry']); } pushBuffer($itemBuff, TYPE_ITEM, $iId, $r['qty'] > 1 ? 0 : TYPE_NPC, $l['entry']); } continue; } if ($_ = taughtSpell($l)) { pushBuffer($spellBuff, TYPE_SPELL, $_, $l['qty'] > 1 ? 0 : TYPE_NPC, $l['entry']); } pushBuffer($itemBuff, TYPE_ITEM, $roi, $l['qty'] > 1 ? 0 : TYPE_NPC, $l['entry']); } if ($itemBuff) { DB::Aowow()->query(queryfy('[V]', $itemBuff, $insMore), 22, 22, 22); } if ($spellBuff) { DB::Aowow()->query(queryfy('[V]', $spellBuff, $insMore), 22, 22, 22); } ############### # 23: Skinned # ############### CLISetup::log(' * #23 Skinned'); $spellBuff = []; $itemBuff = []; $skinLoot = DB::World()->select(' SELECT src.itemOrRef AS ARRAY_KEY, src.entry, it.class, it.subclass, it.spellid_1, it.spelltrigger_1, it.spellid_2, it.spelltrigger_2, COUNT(1) AS qty FROM ( SELECT ct.entry, IF(slt.Reference > 0, -slt.Reference, slt.Item) itemOrRef FROM creature_template ct JOIN skinning_loot_template slt ON slt.entry = ct.skinloot WHERE (type_flags & ?d) = 0 AND ct.skinloot > 0 ) src LEFT JOIN item_template it ON src.itemOrRef > 0 AND src.itemOrRef = it.entry GROUP BY ARRAY_KEY', NPC_TYPEFLAG_HERBLOOT | NPC_TYPEFLAG_MININGLOOT | NPC_TYPEFLAG_ENGINEERLOOT); foreach ($skinLoot as $roi => $l) { if ($roi < 0 && !empty($refLoot[-$roi])) { foreach ($refLoot[-$roi] as $iId => $r) { if ($_ = taughtSpell($r)) { pushBuffer($spellBuff, TYPE_SPELL, $_, $r['qty'] > 1 ? 0 : TYPE_NPC, $l['entry']); } pushBuffer($itemBuff, TYPE_ITEM, $iId, $r['qty'] > 1 ? 0 : TYPE_NPC, $l['entry']); } continue; } if ($_ = taughtSpell($l)) { pushBuffer($spellBuff, TYPE_SPELL, $_, $l['qty'] > 1 ? 0 : TYPE_NPC, $l['entry']); } pushBuffer($itemBuff, TYPE_ITEM, $roi, $l['qty'] > 1 ? 0 : TYPE_NPC, $l['entry']); } if ($itemBuff) { DB::Aowow()->query(queryfy('[V]', $itemBuff, $insMore), 23, 23, 23); } if ($spellBuff) { DB::Aowow()->query(queryfy('[V]', $spellBuff, $insMore), 23, 23, 23); } /*********/ /* Spell */ /*********/ CLISetup::log(' - Spells [original]'); # 4: Quest CLISetup::log(' * #4 Quest'); $quests = DB::World()->select(' SELECT spell AS ARRAY_KEY, id, SUM(qty) AS qty, BIT_OR(side) AS side FROM ( SELECT IF(rewardSpellCast = 0, rewardSpell, rewardSpellCast) AS spell, ID, COUNT(1) AS qty, IF(RequiredRaces & 0x2B2 AND !(RequiredRaces & 0x44D), 2, IF(RequiredRaces & 0x44D AND !(RequiredRaces & 0x2B2), 1, 3)) AS side FROM quest_template WHERE IF(rewardSpellCast = 0, rewardSpell, rewardSpellCast) > 0 GROUP BY spell UNION SELECT SourceSpellId AS spell, ID, COUNT(1) AS qty, IF(RequiredRaces & 0x2B2 AND !(RequiredRaces & 0x44D), 2, IF(RequiredRaces & 0x44D AND !(RequiredRaces & 0x2B2), 1, 3)) AS side FROM quest_template WHERE SourceSpellId > 0 GROUP BY spell ) t GROUP BY spell'); if ($quests) { $qSpells = DB::Aowow()->select('SELECT id AS ARRAY_KEY, effect1Id, effect2Id, effect3Id, effect1TriggerSpell, effect2TriggerSpell, effect3TriggerSpell FROM dbc_spell WHERE id IN (?a) AND (effect1Id = 36 OR effect2Id = 36 OR effect3Id = 36)', array_keys($quests)); $buff = []; foreach ($qSpells as $sId => $spell) { for ($i = 1; $i <= 3; $i++) { if ($spell['effect' . $i . 'Id'] != 36) { // effect: learnSpell continue; } pushBuffer($buff, TYPE_SPELL, $spell['effect' . $i . 'TriggerSpell'], $quests[$sId]['qty'] > 1 ? 0 : TYPE_QUEST, $quests[$sId]['qty'] > 1 ? 0 : $quests[$sId]['id'], $quests[$sId]['side']); } } DB::Aowow()->query(queryfy('[V]', $buff, $insMore), 4, 4, 4); } # 6: Trainer CLISetup::log(' * #6 Trainer'); if ($tNpcs = DB::World()->select('SELECT SpellID AS ARRAY_KEY, ID AS entry, COUNT(1) AS qty FROM npc_trainer WHERE SpellID > 0 GROUP BY ARRAY_KEY')) { $tSpells = DB::Aowow()->select('SELECT Id AS ARRAY_KEY, effect1Id, effect2Id, effect3Id, effect1TriggerSpell, effect2TriggerSpell, effect3TriggerSpell FROM dbc_spell WHERE Id IN (?a)', array_keys($tNpcs)); $buff = []; // todo (med): this skips some spells (e.g. riding) foreach ($tNpcs as $spellId => $npc) { if (!isset($tSpells[$spellId])) { continue; } $effects = $tSpells[$spellId]; $trainerId = $npc['entry'] > 200000 || $npc['qty'] > 1 ? null : $npc['entry']; $triggered = false; for ($i = 1; $i <= 3; $i++) { if ($effects['effect' . $i . 'Id'] != 36) { // effect: learnSpell continue; } $triggered = true; pushBuffer($buff, TYPE_SPELL, $effects['effect' . $i . 'TriggerSpell'], $trainerId ? TYPE_NPC : 0, $trainerId); } if (!$triggered) { pushBuffer($buff, TYPE_SPELL, $spellId, $trainerId ? TYPE_NPC : 0, $trainerId); } } DB::Aowow()->query(queryfy('[V]', $buff, $insMore), 6, 6, 6); } # 7: Discovery CLISetup::log(' * #7 Discovery'); // 61756: Northrend Inscription Research (FAST QA VERSION); if ($disco = DB::World()->select('SELECT ?d, spellId, 1 FROM skill_discovery_template WHERE reqSpell <> ?d', TYPE_SPELL, 61756)) { DB::Aowow()->query(queryfy('[V]', $disco, $insBasic), 7, 7, 7); } # 9: Talent CLISetup::log(' * #9 Talent'); $tSpells = DB::Aowow()->select(' SELECT s.Id AS ARRAY_KEY, s.effect1Id, s.effect2Id, s.effect3Id, s.effect1TriggerSpell, s.effect2TriggerSpell, s.effect3TriggerSpell FROM dbc_talent t JOIN dbc_spell s ON s.Id = t.rank1 WHERE t.rank2 < 1 AND (t.talentSpell = 1 OR (s.effect1Id = 36 OR s.effect2Id = 36 OR s.effect3Id = 36)) '); $n = 0; $buff = []; while ($tSpells) { CLISetup::log(' - ' . ++$n . '. pass'); $recurse = []; foreach ($tSpells as $tId => $spell) { for ($i = 1; $i <= 3; $i++) { if ($spell['effect' . $i . 'Id'] == 36) { // effect: learnSpell $recurse[$spell['effect' . $i . 'TriggerSpell']] = $tId; } } if (array_search($tId, $recurse)) { unset($tSpells[$tId]); } } foreach ($tSpells as $tId => $__) { $buff[$tId] = [TYPE_SPELL, $tId, 1]; } if (!$recurse) { break; } $tSpells = DB::Aowow()->select('SELECT Id AS ARRAY_KEY, effect1Id, effect2Id, effect3Id, effect1TriggerSpell, effect2TriggerSpell, effect3TriggerSpell FROM dbc_spell WHERE Id IN (?a)', array_keys($recurse)); } DB::Aowow()->query(queryfy('[V]', $buff, $insBasic), 9, 9, 9); # 10: Starter CLISetup::log(' * #10 Starter'); /* acquireMethod ABILITY_LEARNED_ON_GET_PROFESSION_SKILL = 1, learnedAt = 1 && source10 = 1 ABILITY_LEARNED_ON_GET_RACE_OR_CLASS_SKILL = 2 not used for now */ $subSkills = DB::Aowow()->subquery('SELECT ?d, spellId, 1, NULL AS m, NULL AS mt FROM dbc_skilllineability WHERE acquireMethod = 1 AND (reqSkillLevel = 1 OR skillLineId = 129) GROUP BY spellId', TYPE_SPELL); DB::Aowow()->query($insSub, 10, $subSkills, 10, 10); if ($pcis = DB::World()->select('SELECT ?d, Spell, 1 FROM playercreateinfo_spell', TYPE_SPELL)) { DB::Aowow()->query(queryfy('[V]', $pcis, $insBasic), 10, 10, 10); } /**********/ /* Titles */ /**********/ CLISetup::log(' - Titles'); # 4: Quest CLISetup::log(' * #4 Quest'); if ($quests = DB::World()->select('SELECT ?d, RewardTitle, 1, ?d, ID FROM quest_template WHERE RewardTitle > 0', TYPE_TITLE, TYPE_QUEST)) { DB::Aowow()->query(queryfy('[V]', $quests, $insMore), 4, 4, 4); } # 12: Achievement CLISetup::log(' * #12 Achievement'); $sets = DB::World()->select(' SELECT ?d, IF (title_A <> 0, title_A, title_H) AS title, 1, ?d, entry FROM achievement_reward WHERE title_A <> 0 OR title_H <> 0 GROUP BY title UNION SELECT ?d, title_H AS title, 1, ?d, entry FROM achievement_reward WHERE title_A <> title_H AND title_A <> 0 AND title_H <> 0', TYPE_TITLE, TYPE_ACHIEVEMENT, TYPE_TITLE, TYPE_ACHIEVEMENT); if ($sets) { DB::Aowow()->query(queryfy('[V]', $sets, $insMore), 12, 12, 12); } # 13: Source-String CLISetup::log(' * #13 cuStrings'); $src13 = [null, 42, 52, 71, 80, 157, 163, 167, 169, 177]; foreach ($src13 as $src => $tId) { if ($tId) { DB::Aowow()->query(queryfy('[V]', [[TYPE_TITLE, $tId, $src]], $insBasic), 13, 13, 13); } } return true; }
protected function generateContent() { $_level = $this->subject->getField('level'); $_minLevel = $this->subject->getField('minLevel'); $_flags = $this->subject->getField('flags'); $_specialFlags = $this->subject->getField('specialFlags'); $_side = Util::sideByRaceMask($this->subject->getField('reqRaceMask')); /***********/ /* Infobox */ /***********/ $infobox = Lang::getInfoBoxForFlags($this->subject->getField('cuFlags')); // event (todo: assign eventData) if ($_ = $this->subject->getField('eventId')) { $this->extendGlobalIds(TYPE_WORLDEVENT, $_); $infobox[] = Lang::game('eventShort') . Lang::main('colon') . '[event=' . $_ . ']'; } // level if ($_level > 0) { $infobox[] = Lang::game('level') . Lang::main('colon') . $_level; } // reqlevel if ($_minLevel) { $lvl = $_minLevel; if ($_ = $this->subject->getField('maxLevel')) { $lvl .= ' - ' . $_; } $infobox[] = sprintf(Lang::game('reqLevel'), $lvl); } // loremaster (i dearly hope those flags cover every case...) if ($this->subject->getField('zoneOrSortBak') > 0 && !$this->subject->isRepeatable()) { $conditions = array(['ac.type', ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_IN_ZONE], ['ac.value1', $this->subject->getField('zoneOrSortBak')], ['a.faction', $_side, '&']); $loremaster = new AchievementList($conditions); $this->extendGlobalData($loremaster->getJSGlobals(GLOBALINFO_SELF)); switch ($loremaster->getMatches()) { case 0: break; case 1: $infobox[] = Lang::quest('loremaster') . Lang::main('colon') . '[achievement=' . $loremaster->id . ']'; break; default: $lm = Lang::quest('loremaster') . Lang::main('colon') . '[ul]'; foreach ($loremaster->iterate() as $id => $__) { $lm .= '[li][achievement=' . $id . '][/li]'; } $infobox[] = $lm . '[/ul]'; break; } } // type (maybe expand uppon?) $_ = []; if ($_flags & QUEST_FLAG_DAILY) { $_[] = Lang::quest('daily'); } else { if ($_flags & QUEST_FLAG_WEEKLY) { $_[] = Lang::quest('weekly'); } else { if ($_specialFlags & QUEST_FLAG_SPECIAL_MONTHLY) { $_[] = Lang::quest('monthly'); } } } if ($t = $this->subject->getField('type')) { $_[] = Lang::quest('questInfo', $t); } if ($_) { $infobox[] = Lang::game('type') . Lang::main('colon') . implode(' ', $_); } // side $_ = Lang::main('side') . Lang::main('colon'); switch ($_side) { case 3: $infobox[] = $_ . Lang::game('si', 3); break; case 2: $infobox[] = $_ . '[span class=icon-horde]' . Lang::game('si', 2) . '[/span]'; break; case 1: $infobox[] = $_ . '[span class=icon-alliance]' . Lang::game('si', 1) . '[/span]'; break; } // races if ($_ = Lang::getRaceString($this->subject->getField('reqRaceMask'), $__, $jsg, $n, false)) { $this->extendGlobalIds(TYPE_RACE, $jsg); $t = $n == 1 ? Lang::game('race') : Lang::game('races'); $infobox[] = Util::ucFirst($t) . Lang::main('colon') . $_; } // classes if ($_ = Lang::getClassString($this->subject->getField('reqClassMask'), $jsg, $n, false)) { $this->extendGlobalIds(TYPE_CLASS, $jsg); $t = $n == 1 ? Lang::game('class') : Lang::game('classes'); $infobox[] = Util::ucFirst($t) . Lang::main('colon') . $_; } // profession / skill if ($_ = $this->subject->getField('reqSkillId')) { $this->extendGlobalIds(TYPE_SKILL, $_); $sk = '[skill=' . $_ . ']'; if ($_ = $this->subject->getField('reqSkillPoints')) { $sk .= ' (' . $_ . ')'; } $infobox[] = Lang::quest('profession') . Lang::main('colon') . $sk; } // timer if ($_ = $this->subject->getField('timeLimit')) { $infobox[] = Lang::quest('timer') . Lang::main('colon') . Util::formatTime($_ * 1000); } $startEnd = DB::Aowow()->select('SELECT * FROM ?_quests_startend WHERE questId = ?d', $this->typeId); // start $start = '[icon name=quest_start' . ($this->subject->isDaily() ? '_daily' : '') . ']' . Lang::event('start') . Lang::main('colon') . '[/icon]'; $s = []; foreach ($startEnd as $se) { if ($se['method'] & 0x1) { $this->extendGlobalIds($se['type'], $se['typeId']); $s[] = ($s ? '[span=invisible]' . $start . '[/span] ' : $start . ' ') . '[' . Util::$typeStrings[$se['type']] . '=' . $se['typeId'] . ']'; } } if ($s) { $infobox[] = implode('[br]', $s); } // end $end = '[icon name=quest_end' . ($this->subject->isDaily() ? '_daily' : '') . ']' . Lang::event('end') . Lang::main('colon') . '[/icon]'; $e = []; foreach ($startEnd as $se) { if ($se['method'] & 0x2) { $this->extendGlobalIds($se['type'], $se['typeId']); $e[] = ($e ? '[span=invisible]' . $end . '[/span] ' : $end . ' ') . '[' . Util::$typeStrings[$se['type']] . '=' . $se['typeId'] . ']'; } } if ($e) { $infobox[] = implode('[br]', $e); } // Repeatable if ($_flags & QUEST_FLAG_REPEATABLE || $_specialFlags & QUEST_FLAG_SPECIAL_REPEATABLE) { $infobox[] = Lang::quest('repeatable'); } // sharable | not sharable $infobox[] = $_flags & QUEST_FLAG_SHARABLE ? Lang::quest('sharable') : Lang::quest('notSharable'); // Keeps you PvP flagged if ($this->subject->isPvPEnabled()) { $infobox[] = Lang::quest('keepsPvpFlag'); } // difficulty (todo (low): formula unclear. seems to be [minLevel,] -4, -2, (level), +3, +(9 to 15)) if ($_level > 0) { $_ = []; // red if ($_minLevel && $_minLevel < $_level - 4) { $_[] = '[color=q10]' . $_minLevel . '[/color]'; } // orange if (!$_minLevel || $_minLevel < $_level - 2) { $_[] = '[color=r1]' . (!$_ && $_minLevel > $_level - 4 ? $_minLevel : $_level - 4) . '[/color]'; } // yellow $_[] = '[color=r2]' . (!$_ && $_minLevel > $_level - 2 ? $_minLevel : $_level - 2) . '[/color]'; // green $_[] = '[color=r3]' . ($_level + 3) . '[/color]'; // grey (is about +/-1 level off) $_[] = '[color=r4]' . ($_level + 3 + ceil(12 * $_level / MAX_LEVEL)) . '[/color]'; if ($_) { $infobox[] = Lang::game('difficulty') . Lang::main('colon') . implode('[small] [/small]', $_); } } $this->infobox = '[ul][li]' . implode('[/li][li]', $infobox) . '[/li][/ul]'; /**********/ /* Series */ /**********/ // Quest Chain (are there cases where quests go in parallel?) $chain = array(array(array('side' => $_side, 'typeStr' => Util::$typeStrings[TYPE_QUEST], 'typeId' => $this->typeId, 'name' => $this->name, '_next' => $this->subject->getField('nextQuestIdChain')))); $_ = $chain[0][0]; while ($_) { if ($_ = DB::Aowow()->selectRow('SELECT id AS typeId, name_loc0, name_loc2, name_loc3, name_loc6, name_loc8, reqRaceMask FROM ?_quests WHERE nextQuestIdChain = ?d', $_['typeId'])) { $n = Util::localizedString($_, 'name'); array_unshift($chain, array(array('side' => Util::sideByRaceMask($_['reqRaceMask']), 'typeStr' => Util::$typeStrings[TYPE_QUEST], 'typeId' => $_['typeId'], 'name' => strlen($n) > 40 ? substr($n, 0, 40) . '…' : $n))); } } $_ = end($chain)[0]; while ($_) { if ($_ = DB::Aowow()->selectRow('SELECT id AS typeId, name_loc0, name_loc2, name_loc3, name_loc6, name_loc8, reqRaceMask, nextQuestIdChain AS _next FROM ?_quests WHERE id = ?d', $_['_next'])) { $n = Util::localizedString($_, 'name'); array_push($chain, array(array('side' => Util::sideByRaceMask($_['reqRaceMask']), 'typeStr' => Util::$typeStrings[TYPE_QUEST], 'typeId' => $_['typeId'], 'name' => strlen($n) > 40 ? substr($n, 0, 40) . '…' : $n, '_next' => $_['_next']))); } } if (count($chain) > 1) { $this->series[] = [$chain, null]; } // todo (low): sensibly merge the following lists into 'series' $listGen = function ($cnd) { $chain = []; $list = new QuestList($cnd); if ($list->error) { return null; } foreach ($list->iterate() as $id => $__) { $n = $list->getField('name', true); $chain[] = array(array('side' => Util::sideByRaceMask($list->getField('reqRaceMask')), 'typeStr' => Util::$typeStrings[TYPE_QUEST], 'typeId' => $id, 'name' => strlen($n) > 40 ? substr($n, 0, 40) . '…' : $n)); } return $chain; }; $extraLists = array(['reqQ', array('OR', ['AND', ['nextQuestId', $this->typeId], ['exclusiveGroup', 0, '<']], ['AND', ['id', $this->subject->getField('prevQuestId')], ['nextQuestIdChain', $this->typeId, '!']])], ['reqOneQ', array(['exclusiveGroup', 0, '>'], ['nextQuestId', $this->typeId])], ['opensQ', array('OR', ['AND', ['prevQuestId', $this->typeId], ['id', $this->subject->getField('nextQuestIdChain'), '!']], ['id', $this->subject->getField('nextQuestId')])], ['closesQ', array(['exclusiveGroup', 0, '!'], ['exclusiveGroup', $this->subject->getField('exclusiveGroup')], ['id', $this->typeId, '!'])], ['enablesQ', array(['prevQuestId', -$this->typeId])], ['enabledByQ', array(['id', -$this->subject->getField('prevQuestId')])]); foreach ($extraLists as $el) { if ($_ = $listGen($el[1])) { $this->series[] = [$_, sprintf(Util::$dfnString, Lang::quest($el[0] . 'Desc'), Lang::quest($el[0]))]; } } /*******************/ /* Objectives List */ /*******************/ $this->objectiveList = []; $this->providedItem = []; // gather ids for lookup $olItems = $olNPCs = $olGOs = $olFactions = []; // items $olItems[0] = array($this->subject->getField('sourceItemId'), $this->subject->getField('sourceItemCount'), false); for ($i = 1; $i < 7; $i++) { $id = $this->subject->getField('reqItemId' . $i); $qty = $this->subject->getField('reqItemCount' . $i); if (!$id || !$qty) { continue; } $olItems[$i] = [$id, $qty, $id == $olItems[0][0]]; } if ($ids = array_column($olItems, 0)) { $olItemData = new ItemList(array(['id', $ids])); $this->extendGlobalData($olItemData->getJSGlobals(GLOBALINFO_SELF)); $providedRequired = false; foreach ($olItems as $i => list($itemId, $qty, $provided)) { if (!$i || !$itemId || !in_array($itemId, $olItemData->getFoundIDs())) { continue; } if ($provided) { $providedRequired = true; } $this->objectiveList[] = array('typeStr' => Util::$typeStrings[TYPE_ITEM], 'id' => $itemId, 'name' => $olItemData->json[$itemId]['name'], 'qty' => $qty > 1 ? $qty : 0, 'quality' => 7 - $olItemData->json[$itemId]['quality'], 'extraText' => $provided ? ' (' . Lang::quest('provided') . ')' : ''); } // if providd item is not required by quest, list it below other requirements if (!$providedRequired && $olItems[0][0] && in_array($olItems[0][0], $olItemData->getFoundIDs())) { $this->providedItem = array('id' => $olItems[0][0], 'name' => $olItemData->json[$olItems[0][0]]['name'], 'qty' => $olItems[0][1] > 1 ? $olItems[0][1] : 0, 'quality' => 7 - $olItemData->json[$olItems[0][0]]['quality']); } } // creature or GO... for ($i = 1; $i < 5; $i++) { $id = $this->subject->getField('reqNpcOrGo' . $i); $qty = $this->subject->getField('reqNpcOrGoCount' . $i); $altTxt = $this->subject->getField('objectiveText' . $i, true); if ($id > 0 && $qty) { $olNPCs[$id] = [$qty, $altTxt, []]; } else { if ($id < 0 && $qty) { $olGOs[-$id] = [$qty, $altTxt]; } } } // .. creature kills if ($ids = array_keys($olNPCs)) { $olNPCData = new CreatureList(array('OR', ['id', $ids], ['killCredit1', $ids], ['killCredit2', $ids])); $this->extendGlobalData($olNPCData->getJSGlobals(GLOBALINFO_SELF)); // create proxy-references foreach ($olNPCData->iterate() as $id => $__) { if ($p = $olNPCData->getField('KillCredit1')) { if (isset($olNPCs[$p])) { $olNPCs[$p][2][$id] = $olNPCData->getField('name', true); } } if ($p = $olNPCData->getField('KillCredit2')) { if (isset($olNPCs[$p])) { $olNPCs[$p][2][$id] = $olNPCData->getField('name', true); } } } foreach ($olNPCs as $i => $pair) { if (!$i || !in_array($i, $olNPCData->getFoundIDs())) { continue; } $ol = array('typeStr' => Util::$typeStrings[TYPE_NPC], 'id' => $i, 'name' => $pair[1] ?: Util::localizedString($olNPCData->getEntry($i), 'name'), 'qty' => $pair[0] > 1 ? $pair[0] : 0, 'extraText' => $_specialFlags & QUEST_FLAG_SPECIAL_SPELLCAST || $pair[1] ? '' : ' ' . Lang::achievement('slain'), 'proxy' => $pair[2]); if ($pair[2]) { // has proxies assigned, add yourself as another proxy $ol['proxy'][$i] = Util::localizedString($olNPCData->getEntry($i), 'name'); } $this->objectiveList[] = $ol; } } // .. GO interactions if ($ids = array_keys($olGOs)) { $olGOData = new GameObjectList(array(['id', $ids])); $this->extendGlobalData($olGOData->getJSGlobals(GLOBALINFO_SELF)); foreach ($olNPCs as $i => $pair) { if (!$i || !in_array($i, $olGOData->getFoundIDs())) { continue; } $this->objectiveList[] = array('typeStr' => Util::$typeStrings[TYPE_OBJECT], 'id' => $i, 'name' => $pair[1] ?: Util::localizedString($olGOData->getEntry($i), 'name'), 'qty' => $pair[0] > 1 ? $pair[0] : 0); } } // reputation required for ($i = 1; $i < 3; $i++) { $id = $this->subject->getField('reqFactionId' . $i); $val = $this->subject->getField('reqFactionValue' . $i); if (!$id) { continue; } $olFactions[$id] = $val; } if ($ids = array_keys($olFactions)) { $olFactionsData = new FactionList(array(['id', $ids])); $this->extendGlobalData($olFactionsData->getJSGlobals(GLOBALINFO_SELF)); foreach ($olFactions as $i => $val) { if (!$i || !in_array($i, $olFactionsData->getFoundIDs())) { continue; } $this->objectiveList[] = array('typeStr' => Util::$typeStrings[TYPE_FACTION], 'id' => $i, 'name' => Util::localizedString($olFactionsData->getEntry($i), 'name'), 'qty' => sprintf(Util::$dfnString, $val . ' ' . Lang::achievement('points'), Lang::getReputationLevelForPoints($val)), 'extraText' => ''); } } // granted spell if ($_ = $this->subject->getField('sourceSpellId')) { $this->extendGlobalIds(TYPE_SPELL, $_); $this->objectiveList[] = array('typeStr' => Util::$typeStrings[TYPE_SPELL], 'id' => $_, 'name' => SpellList::getName($_), 'qty' => 0, 'extraText' => ' (' . Lang::quest('provided') . ')'); } // required money if ($this->subject->getField('rewardOrReqMoney') < 0) { $this->objectiveList[] = ['text' => Lang::quest('reqMoney') . Lang::main('colon') . Util::formatMoney(abs($this->subject->getField('rewardOrReqMoney')))]; } // required pvp kills if ($_ = $this->subject->getField('reqPlayerKills')) { $this->objectiveList[] = ['text' => Lang::quest('playerSlain') . ' (' . $_ . ')']; } /**********/ /* Mapper */ /**********/ $this->addJS('?data=zones&locale=' . User::$localeId . '&t=' . $_SESSION['dataKey']); /* TODO (GODDAMNIT): jeez.. */ // $startend + reqNpcOrGo[1-4] $this->map = null; // array( // 'data' => ['zone' => $this->typeId], // 'som' => Util::toJSON($som) // ); /****************/ /* Main Content */ /****************/ $this->gains = $this->createGains(); $this->mail = $this->createMail($maTab, $startEnd); $this->rewards = $this->createRewards(); $this->objectives = $this->subject->parseText('objectives', false); $this->details = $this->subject->parseText('details', false); $this->offerReward = $this->subject->parseText('offerReward', false); $this->requestItems = $this->subject->parseText('requestItems', false); $this->completed = $this->subject->parseText('completed', false); $this->end = $this->subject->parseText('end', false); $this->suggestedPl = $this->subject->getField('suggestedPlayers'); $this->unavailable = $_flags & QUEST_FLAG_UNAVAILABLE || $this->subject->getField('cuFlags') & CUSTOM_EXCLUDE_FOR_LISTVIEW; $this->redButtons = array(BUTTON_LINKS => ['color' => 'ffffff00', 'linkId' => 'quest:' . $this->typeId . ':' . $_level . ''], BUTTON_WOWHEAD => true); if ($maTab) { $this->lvTabs[] = $maTab; } // factionchange-equivalent if ($pendant = DB::World()->selectCell('SELECT IF(horde_id = ?d, alliance_id, -horde_id) FROM player_factionchange_quests WHERE alliance_id = ?d OR horde_id = ?d', $this->typeId, $this->typeId, $this->typeId)) { $altQuest = new QuestList(array(['id', abs($pendant)])); if (!$altQuest->error) { $this->transfer = sprintf(Lang::quest('_transfer'), $altQuest->id, $altQuest->getField('name', true), $pendant > 0 ? 'alliance' : 'horde', $pendant > 0 ? Lang::game('si', 1) : Lang::game('si', 2)); } } /**************/ /* Extra Tabs */ /**************/ // tab: see also $seeAlso = new QuestList(array(['name_loc' . User::$localeId, '%' . $this->name . '%'], ['id', $this->typeId, '!'])); if (!$seeAlso->error) { $this->extendGlobalData($seeAlso->getJSGlobals()); $this->lvTabs[] = array('file' => 'quest', 'data' => $seeAlso->getListviewData(), 'params' => array('name' => '$LANG.tab_seealso', 'id' => 'see-also')); } // tab: criteria of $criteriaOf = new AchievementList(array(['ac.type', ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST], ['ac.value1', $this->typeId])); if (!$criteriaOf->error) { $this->extendGlobalData($criteriaOf->getJSGlobals()); $this->lvTabs[] = array('file' => 'achievement', 'data' => $criteriaOf->getListviewData(), 'params' => array('name' => '$LANG.tab_criteriaof', 'id' => 'criteria-of')); } // tab: conditions $cnd = []; if ($_ = $this->subject->getField('reqMinRepFaction')) { $cnd[CND_SRC_QUEST_ACCEPT][$this->typeId][0][] = [CND_REPUTATION_RANK, $_, 1 << Util::getReputationLevelForPoints($this->subject->getField('reqMinRepValue'))]; $this->extendGlobalIds(TYPE_FACTION, $_); } if ($_ = $this->subject->getField('reqMaxRepFaction')) { $cnd[CND_SRC_QUEST_ACCEPT][$this->typeId][0][] = [-CND_REPUTATION_RANK, $_, 1 << Util::getReputationLevelForPoints($this->subject->getField('reqMaxRepValue'))]; $this->extendGlobalIds(TYPE_FACTION, $_); } $_ = Util::getServerConditions([CND_SRC_QUEST_ACCEPT, CND_SRC_QUEST_SHOW_MARK], null, $this->typeId); if (!empty($_[0])) { // awkward merger if (isset($_[0][CND_SRC_QUEST_ACCEPT][$this->typeId][0])) { if (isset($cnd[CND_SRC_QUEST_ACCEPT][$this->typeId][0])) { $cnd[CND_SRC_QUEST_ACCEPT][$this->typeId][0] = array_merge($cnd[CND_SRC_QUEST_ACCEPT][$this->typeId][0], $_[0][CND_SRC_QUEST_ACCEPT][$this->typeId][0]); } else { $cnd[CND_SRC_QUEST_ACCEPT] = $_[0][CND_SRC_QUEST_ACCEPT]; } } if (isset($_[0][CND_SRC_QUEST_SHOW_MARK])) { $cnd[CND_SRC_QUEST_SHOW_MARK] = $_[0][CND_SRC_QUEST_SHOW_MARK]; } $this->extendGlobalData($_[1]); } if ($cnd) { $tab = "<script type=\"text/javascript\">\n" . "var markup = ConditionList.createTab(" . Util::toJSON($cnd) . ");\n" . "Markup.printHtml(markup, 'tab-conditions', { allow: Markup.CLASS_STAFF })" . "</script>"; $this->lvTabs[] = array('file' => null, 'data' => $tab, 'params' => array('id' => 'conditions', 'name' => '$LANG.requires')); } }
private static function HandleSellingItems() { if (self::$selling_count <= 0 || !is_array(self::$myitems_storage)) { return false; } $item_ids = array(); $item_ids_guids = array(); $items_data = array(); foreach (self::$myitems_storage as $item) { $item_ids[] = $item['item_template']; $item_ids_guids[$item['itemguid']] = $item['item_template']; $items_data[$item['itemguid']] = $item; } $items = DB::World()->select("SELECT `entry`, `name`, `Quality`, `displayid` FROM `item_template` WHERE `entry` IN (%s)", $item_ids); if (!$items) { return false; } $items_storage = array(); $displayids = array(); foreach ($items as $item) { $items_storage[$item['entry']] = $item; $displayids[] = $item['displayid']; } $icons = DB::WoW()->select("SELECT `displayid`, `icon` FROM `DBPREFIX_icons` WHERE `displayid` IN (%s)", $displayids); if (!$icons) { return false; } $icons_storage = array(); foreach ($icons as $icon) { $icons_storage[$icon['displayid']] = $icon['icon']; } unset($icons); self::$items_storage = array(); self::$buyout_price = 0; foreach ($item_ids_guids as $item_guid => $item_id) { if (isset($items_storage[$item_id])) { $item = new WoW_Item(WoWConfig::$Realms[WoW_Account::GetActiveCharacterInfo('realmId')]['type']); $item->LoadFromDBByEntry($item_guid, $item_id); $auc_time = $items_data[$item_guid]['time']; $now = time(); $auction_time = 0; if ($now - $auc_time <= 48 * IN_HOURS) { $auction_time = 3; } elseif ($now - $auc_time <= 24 * IN_HOURS) { $auction_time = 2; } elseif ($now - $auc_time <= 12 * IN_HOURS) { $auction_time = 1; } self::$items_storage[] = array('auction_id' => $items_data[$item_guid]['id'], 'guid' => $item_guid, 'id' => $items_storage[$item_id]['entry'], 'quality' => $items_storage[$item_id]['Quality'], 'name' => WoW_Locale::GetLocaleId() == LOCALE_EN ? $items_storage[$item_id]['name'] : WoW_Items::GetItemName($item_id), 'icon' => $icons_storage[$items_storage[$item_id]['displayid']], 'price_raw' => $items_data[$item_guid]['startbid'], 'price' => WoW_Utils::GetMoneyFormat($items_data[$item_guid]['startbid']), 'buyout_raw' => $items_data[$item_guid]['buyoutprice'], 'buyout' => WoW_Utils::GetMoneyFormat($items_data[$item_guid]['buyoutprice']), 'lastbid' => $items_data[$item_guid]['lastbid'], 'count' => $item->GetStackCount(), 'time' => $auction_time); self::$buyout_price += $items_data[$item_guid]['buyoutprice']; } } unset($items, $items_storage, $displayids); return true; }
public static function GetNPCInfo($entry, $type) { if (!DB::World()->selectCell("SELECT 1 FROM creature_template WHERE entry = %d", $entry)) { return false; } switch ($type) { case 'name': if (WoW_Locale::GetLocaleID() == LOCALE_EN) { return DB::World()->selectCell("SELECT name FROM creature_template WHERE entry = %d", $entry); } $data = DB::World()->selectRow("\n SELECT\n a.name,\n b.name_loc%d AS name_loc\n FROM creature_template AS a\n LEFT JOIN locales_creature AS b ON b.entry = a.entry\n WHERE a.entry = %d", WoW_Locale::GetLocaleID(), $entry); if (!$data) { return DB::World()->selectCell("SELECT name FROM creature_template WHERE entry = %d", $entry); } if ($data['name_loc'] != null) { return $data['name_loc']; } return $data['name']; break; } }
protected function generateContent() { /***********/ /* Infobox */ /***********/ $infobox = Lang::getInfoBoxForFlags($this->subject->getField('cuFlags')); // points if ($_ = $this->subject->getField('points')) { $infobox[] = Lang::achievement('points') . Lang::main('colon') . '[achievementpoints=' . $_ . ']'; } // location // todo (low) // faction switch ($this->subject->getField('faction')) { case 1: $infobox[] = Lang::main('side') . Lang::main('colon') . '[span class=icon-alliance]' . Lang::game('si', SIDE_ALLIANCE) . '[/span]'; break; case 2: $infobox[] = Lang::main('side') . Lang::main('colon') . '[span class=icon-horde]' . Lang::game('si', SIDE_HORDE) . '[/span]'; break; default: // case 3 $infobox[] = Lang::main('side') . Lang::main('colon') . Lang::game('si', SIDE_BOTH); } // realm first available? if ($this->subject->getField('flags') & 0x100 && DB::isConnectable(DB_AUTH)) { $avlb = []; foreach (DB::Auth()->selectCol('SELECT id AS ARRAY_KEY, name FROM realmlist WHERE allowedSecurityLevel = 0 AND gamebuild = ?d', WOW_VERSION) as $rId => $name) { if (!DB::isConnectable(DB_CHARACTERS . $rId)) { continue; } if (!DB::Characters($rId)->selectCell('SELECT 1 FROM character_achievement WHERE achievement = ?d LIMIT 1', $this->typeId)) { $avlb[] = $name; } } if ($avlb) { $infobox[] = Lang::achievement('rfAvailable') . implode(', ', $avlb); } } /**********/ /* Series */ /**********/ $series = []; if ($c = $this->subject->getField('chainId')) { $chainAcv = new AchievementList(array(['chainId', $c])); foreach ($chainAcv->iterate() as $aId => $__) { $pos = $chainAcv->getField('chainPos'); if (!isset($series[$pos])) { $series[$pos] = []; } $series[$pos][] = array('side' => $chainAcv->getField('faction'), 'typeStr' => Util::$typeStrings[TYPE_ACHIEVEMENT], 'typeId' => $aId, 'name' => $chainAcv->getField('name', true)); } } /****************/ /* Main Content */ /****************/ $this->mail = $this->createMail($reqBook); $this->headIcons = [$this->subject->getField('iconString')]; $this->infobox = $infobox ? '[ul][li]' . implode('[/li][li]', $infobox) . '[/li][/ul]' : null; $this->series = $series ? [[$series, null]] : null; $this->description = $this->subject->getField('description', true); $this->redButtons = array(BUTTON_LINKS => ['color' => 'ffffff00', 'linkId' => Util::$typeStrings[TYPE_ACHIEVEMENT] . ':' . $this->typeId . ':"..UnitGUID("player")..":0:0:0:0:0:0:0:0'], BUTTON_WOWHEAD => !($this->subject->getField('cuFlags') & CUSTOM_SERVERSIDE)); $this->criteria = array('reqQty' => $this->subject->getField('reqCriteriaCount'), 'icons' => [], 'data' => []); if ($reqBook) { $this->addCss(['path' => 'Book.css']); } // create rewards if ($foo = $this->subject->getField('rewards')) { array_walk($foo, function (&$item) { $item = $item[0] != TYPE_ITEM ? null : $item[1]; }); $bar = new ItemList(array(['i.id', $foo])); foreach ($bar->iterate() as $id => $__) { $this->rewards['item'][] = array('name' => $bar->getField('name', true), 'quality' => $bar->getField('quality'), 'typeStr' => Util::$typeStrings[TYPE_ITEM], 'id' => $id, 'globalStr' => 'g_items'); } } if ($foo = $this->subject->getField('rewards')) { array_walk($foo, function (&$item) { $item = $item[0] != TYPE_TITLE ? null : $item[1]; }); $bar = new TitleList(array(['id', $foo])); foreach ($bar->iterate() as $__) { $this->rewards['title'][] = sprintf(Lang::achievement('titleReward'), $bar->id, trim(str_replace('%s', '', $bar->getField('male', true)))); } } $this->rewards['text'] = $this->subject->getField('reward', true); // factionchange-equivalent if ($pendant = DB::World()->selectCell('SELECT IF(horde_id = ?d, alliance_id, -horde_id) FROM player_factionchange_achievement WHERE alliance_id = ?d OR horde_id = ?d', $this->typeId, $this->typeId, $this->typeId)) { $altAcv = new AchievementList(array(['id', abs($pendant)])); if (!$altAcv->error) { $this->transfer = sprintf(Lang::achievement('_transfer'), $altAcv->id, 1, $altAcv->getField('iconString'), $altAcv->getField('name', true), $pendant > 0 ? 'alliance' : 'horde', $pendant > 0 ? Lang::game('si', 1) : Lang::game('si', 2)); } } /**************/ /* Extra Tabs */ /**************/ // tab: see also $conditions = array(['name_loc' . User::$localeId, $this->subject->getField('name', true)], ['id', $this->typeId, '!']); $saList = new AchievementList($conditions); $this->lvTabs[] = array('file' => 'achievement', 'data' => $saList->getListviewData(), 'params' => array('id' => 'see-also', 'name' => '$LANG.tab_seealso', 'visibleCols' => "\$['category']")); $this->extendGlobalData($saList->getJSGlobals()); // tab: criteria of $refs = DB::Aowow()->SelectCol('SELECT refAchievementId FROM ?_achievementcriteria WHERE Type = ?d AND value1 = ?d', ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT, $this->typeId); if (!empty($refs)) { $coList = new AchievementList(array(['id', $refs])); $this->lvTabs[] = array('file' => 'achievement', 'data' => $coList->getListviewData(), 'params' => array('id' => 'criteria-of', 'name' => '$LANG.tab_criteriaof', 'visibleCols' => "\$['category']")); $this->extendGlobalData($coList->getJSGlobals()); } /*****************/ /* Criteria List */ /*****************/ $iconId = 1; $rightCol = []; foreach ($this->subject->getCriteria() as $i => $crt) { // hide hidden criteria for regular users (really do..?) // if (($crt['completionFlags'] & ACHIEVEMENT_CRITERIA_FLAG_HIDDEN) && User::$perms > 0) // continue; // alternative display option $displayMoney = $crt['completionFlags'] & ACHIEVEMENT_CRITERIA_FLAG_MONEY_COUNTER; $crtName = Util::localizedString($crt, 'name'); $tmp = array('id' => $crt['id'], 'name' => $crtName, 'type' => $crt['type']); $obj = (int) $crt['value1']; $qty = (int) $crt['value2']; switch ($crt['type']) { // link to npc case ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE: case ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_CREATURE: $tmp['link'] = array('href' => '?npc=' . $obj, 'text' => $crtName); $tmp['extraText'] = Lang::achievement('slain'); break; // link to area (by map) // link to area (by map) case ACHIEVEMENT_CRITERIA_TYPE_WIN_BG: case ACHIEVEMENT_CRITERIA_TYPE_WIN_ARENA: case ACHIEVEMENT_CRITERIA_TYPE_PLAY_ARENA: case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND: case ACHIEVEMENT_CRITERIA_TYPE_DEATH_AT_MAP: if ($zoneId = DB::Aowow()->selectCell('SELECT id FROM ?_zones WHERE mapId = ? LIMIT 1', $obj)) { $tmp['link'] = array('href' => '?zone=' . $zoneId, 'text' => $crtName); } else { $tmp['extraText'] = $crtName; } break; // link to area // link to area case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_IN_ZONE: case ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL_AT_AREA: $tmp['link'] = array('href' => '?zone=' . $obj, 'text' => $crtName); break; // link to skills // link to skills case ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL: case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LEVEL: case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILLLINE_SPELLS: case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LINE: $tmp['link'] = array('href' => '?skill=' . $obj, 'text' => $crtName); break; // link to class // link to class case ACHIEVEMENT_CRITERIA_TYPE_HK_CLASS: $tmp['link'] = array('href' => '?class=' . $obj, 'text' => $crtName); break; // link to race // link to race case ACHIEVEMENT_CRITERIA_TYPE_HK_RACE: $tmp['link'] = array('href' => '?race=' . $obj, 'text' => $crtName); break; // link to title - todo (low): crosslink // link to title - todo (low): crosslink case ACHIEVEMENT_CRITERIA_TYPE_EARNED_PVP_TITLE: $tmp['extraText'] = Util::ucFirst(Lang::game('title')) . Lang::main('colon') . $crtName; break; // link to achivement (/w icon) // link to achivement (/w icon) case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT: $tmp['link'] = array('href' => '?achievement=' . $obj, 'text' => $crtName); $tmp['icon'] = $iconId; $this->criteria['icons'][] = array('itr' => $iconId++, 'type' => 'g_achievements', 'id' => $obj); $this->extendGlobalIds(TYPE_ACHIEVEMENT, $obj); break; // link to quest // link to quest case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST: // $crtName = ; $tmp['link'] = array('href' => '?quest=' . $obj, 'text' => $crtName ?: QuestList::getName($obj)); break; // link to spell (/w icon) // link to spell (/w icon) case ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET: case ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2: case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL: case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SPELL: case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2: $tmp['link'] = array('href' => '?spell=' . $obj, 'text' => $crtName ?: SpellList::getName($obj)); $this->extendGlobalIds(TYPE_SPELL, $obj); $tmp['icon'] = $iconId; $this->criteria['icons'][] = array('itr' => $iconId++, 'type' => 'g_spells', 'id' => $obj); break; // link to item (/w icon) // link to item (/w icon) case ACHIEVEMENT_CRITERIA_TYPE_OWN_ITEM: case ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM: case ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM: case ACHIEVEMENT_CRITERIA_TYPE_EQUIP_ITEM: $crtItm = new ItemList(array(['i.id', $obj])); $tmp['link'] = array('href' => '?item=' . $obj, 'text' => $crtName ?: $crtItm->getField('name', true), 'quality' => $crtItm->getField('quality'), 'count' => $qty); $this->extendGlobalData($crtItm->getJSGlobals()); $tmp['icon'] = $iconId; $this->criteria['icons'][] = array('itr' => $iconId++, 'type' => 'g_items', 'id' => $obj, 'count' => $qty); break; // link to faction (/w target reputation) // link to faction (/w target reputation) case ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION: $tmp['link'] = array('href' => '?faction=' . $obj, 'text' => $crtName ?: FactionList::getName($obj)); $tmp['extraText'] = ' (' . Lang::getReputationLevelForPoints($qty) . ')'; break; // link to GObject // link to GObject case ACHIEVEMENT_CRITERIA_TYPE_USE_GAMEOBJECT: case ACHIEVEMENT_CRITERIA_TYPE_FISH_IN_GAMEOBJECT: $tmp['link'] = array('href' => '?object=' . $obj, 'text' => $crtName); break; default: // Add a gold coin icon if required $tmp['extraText'] = $displayMoney ? Util::formatMoney($qty) : $crtName; break; } // If the right column if ($i % 2) { $this->criteria['data'][] = $tmp; } else { $rightCol[] = $tmp; } } // If you found the second column - merge data from it to the end of the main body if ($rightCol) { $this->criteria['data'] = array_merge($this->criteria['data'], $rightCol); } }
public function __construct($conditions = []) { parent::__construct($conditions); if ($this->error) { return; } // post processing $foo = DB::World()->selectCol('SELECT perfectItemType FROM skill_perfect_item_template WHERE spellId IN (?a)', $this->getFoundIDs()); foreach ($this->iterate() as &$_curTpl) { // required for globals if ($idx = $this->canCreateItem()) { foreach ($idx as $i) { $foo[] = (int) $_curTpl['effect' . $i . 'CreateItemId']; } } for ($i = 1; $i <= 8; $i++) { if ($_curTpl['reagent' . $i] > 0) { $foo[] = (int) $_curTpl['reagent' . $i]; } } for ($i = 1; $i <= 2; $i++) { if ($_curTpl['tool' . $i] > 0) { $foo[] = (int) $_curTpl['tool' . $i]; } } // ranks $this->ranks[$this->id] = $this->getField('rank', true); // sources for ($i = 1; $i < 25; $i++) { if ($_ = $_curTpl['src' . $i]) { $this->sources[$this->id][$i][] = $_; } unset($_curTpl['src' . $i]); } // set full masks to 0 $_curTpl['reqClassMask'] &= CLASS_MASK_ALL; if ($_curTpl['reqClassMask'] == CLASS_MASK_ALL) { $_curTpl['reqClassMask'] = 0; } $_curTpl['reqRaceMask'] &= RACE_MASK_ALL; if ($_curTpl['reqRaceMask'] == RACE_MASK_ALL) { $_curTpl['reqRaceMask'] = 0; } // unpack skillLines $_curTpl['skillLines'] = []; if ($_curTpl['skillLine1'] < 0) { foreach (Util::$skillLineMask[$_curTpl['skillLine1']] as $idx => $pair) { if ($_curTpl['skillLine2OrMask'] & 1 << $idx) { $_curTpl['skillLines'][] = $pair[1]; } } } else { if ($sec = $_curTpl['skillLine2OrMask']) { if ($this->id == 818) { // and another hack .. basic Campfire (818) has deprecated skill Survival (142) as first skillLine $_curTpl['skillLines'] = [$sec, $_curTpl['skillLine1']]; } else { $_curTpl['skillLines'] = [$_curTpl['skillLine1'], $sec]; } } else { if ($prim = $_curTpl['skillLine1']) { $_curTpl['skillLines'] = [$prim]; } } } unset($_curTpl['skillLine1']); unset($_curTpl['skillLine2OrMask']); } if ($foo) { $this->relItems = new ItemList(array(['i.id', array_unique($foo)], CFG_SQL_LIMIT_NONE)); } }
public static function GetNpcAreaInfo($entry) { $npc_coordinates = DB::World()->selectRow("SELECT `guid`, `map`, `position_x`, `position_y` FROM `creature` WHERE `id` = %d LIMIT 1", $entry); if (!is_array($npc_coordinates)) { WoW_Log::WriteLog('%s : creature #%d was not found in `creature` table!', __METHOD__, $entry); return false; } $area_data = DB::WoW()->selectRow("\n SELECT\n `a`.`id`,\n `a`.`area`,\n `b`.`name_en` AS `areaName_original`,\n `b`.`name_%s` AS `areaName_locale`\n FROM `DBPREFIX_zones` AS `a`\n JOIN `DBPREFIX_areas` AS `b` ON `b`.`id` = `a`.`area`\n WHERE `a`.`map` = %d AND `a`.`y_min` >= %d AND `a`.`y_max` <= %d AND `a`.`x_min` >= %d AND `a`.`x_max` <= %d\n LIMIT 1", WoW_Locale::GetLocale(), $npc_coordinates['map'], $npc_coordinates['position_y'], $npc_coordinates['position_y'], $npc_coordinates['position_x'], $npc_coordinates['position_x']); if (!is_array($area_data)) { WoW_Log::WriteLog('%s : area data for creature #%d (GUID: %d) was not found!', __METHOD__, $entry, $npc_coordinates['guid']); return false; } return array('entry' => $entry, 'guid' => $npc_coordinates['guid'], 'mapID' => $npc_coordinates['map'], 'zoneID' => $area_data['id'], 'areaID' => $area_data['area'], 'zoneName' => $area_data['areaName_original'], 'zoneName_loc' => $area_data['areaName_locale'], 'pos_x' => $npc_coordinates['position_x'], 'pos_y' => $npc_coordinates['position_y']); }
protected function generateContent() { $this->addJS('?data=zones&locale=' . User::$localeId . '&t=' . $_SESSION['dataKey']); $_itemId = $this->subject->getField('itemId'); /***********/ /* Infobox */ /**********/ $infobox = Lang::getInfoBoxForFlags($this->subject->getField('cuFlags')); if ($this->typeId == 103) { // Arena Points $infobox[] = Lang::currency('cap') . Lang::main('colon') . '10\'000'; } else { if ($this->typeId == 104) { // Honor $infobox[] = Lang::currency('cap') . Lang::main('colon') . '75\'000'; } } /****************/ /* Main Content */ /****************/ $this->infobox = $infobox ? '[ul][li]' . implode('[/li][li]', $infobox) . '[/li][/ul]' : null; $this->name = $this->subject->getField('name', true); $this->headIcons = $this->typeId == 104 ? ['inv_bannerpvp_02', 'inv_bannerpvp_01'] : [$this->subject->getField('iconString')]; $this->redButtons = array(BUTTON_WOWHEAD => true, BUTTON_LINKS => true); /**************/ /* Extra Tabs */ /**************/ if ($this->typeId != 103 && $this->typeId != 104) { // tabs: this currency is contained in.. $lootTabs = new Loot(); if ($lootTabs->getByItem($_itemId)) { $this->extendGlobalData($lootTabs->jsGlobals); foreach ($lootTabs->iterate() as $tab) { $this->lvTabs[] = array('file' => $tab[0], 'data' => $tab[1], 'params' => ['name' => $tab[2], 'id' => $tab[3], 'extraCols' => $tab[4] ? '$[' . implode(', ', array_unique($tab[4])) . ']' : null, 'hiddenCols' => $tab[5] ? '$[' . implode(', ', array_unique($tab[5])) . ']' : null, 'visibleCols' => $tab[6] ? '$' . Util::toJSON(array_unique($tab[6])) : null]); } } // tab: sold by $itemObj = new ItemList(array(['id', $_itemId])); if (!empty($itemObj->getExtendedCost()[$_itemId])) { $vendors = $itemObj->getExtendedCost()[$_itemId]; $this->extendGlobalData($itemObj->getJSGlobals(GLOBALINFO_SELF | GLOBALINFO_RELATED)); $soldBy = new CreatureList(array(['id', array_keys($vendors)])); if (!$soldBy->error) { $sbData = $soldBy->getListviewData(); $extraCols = ['Listview.extraCols.stock', "Listview.funcBox.createSimpleCol('stack', 'stack', '10%', 'stack')", 'Listview.extraCols.cost']; $holidays = []; foreach ($sbData as $k => &$row) { $items = []; $tokens = []; foreach ($vendors[$k] as $id => $qty) { if (is_string($id)) { continue; } if ($id > 0) { $tokens[] = [$id, $qty]; } else { if ($id < 0) { $items[] = [-$id, $qty]; } } } if ($vendors[$k]['event']) { if (count($extraCols) == 3) { // not already pushed $extraCols[] = 'Listview.extraCols.condition'; } $this->extendGlobalIds(TYPE_WORLDEVENT, $vendors[$k]['event']); $row['condition'][0][$this->typeId][] = [[CND_ACTIVE_EVENT, $vendors[$k]['event']]]; } $row['stock'] = $vendors[$k]['stock']; $row['stack'] = $itemObj->getField('buyCount'); $row['cost'] = array($itemObj->getField('buyPrice'), $items ? $items : null, $tokens ? $tokens : null); } $this->lvTabs[] = array('file' => 'creature', 'data' => $sbData, 'params' => ['name' => '$LANG.tab_soldby', 'id' => 'sold-by-npc', 'extraCols' => '$[' . implode(', ', $extraCols) . ']', 'hiddenCols' => "\$['level', 'type']"]); } } } // tab: created by (spell) [for items its handled in Loot::getByContainer()] if ($this->typeId == 104) { $createdBy = new SpellList(array(['effect1Id', 45], ['effect2Id', 45], ['effect3Id', 45], 'OR')); if (!$createdBy->error) { $this->extendGlobalData($createdBy->getJSGlobals(GLOBALINFO_SELF | GLOBALINFO_RELATED)); if ($createdBy->hasSetFields(['reagent1'])) { $visCols = ['reagents']; } $this->lvTabs[] = array('file' => 'spell', 'data' => $createdBy->getListviewData(), 'params' => ['name' => '$LANG.tab_createdby', 'id' => 'created-by', 'visibleCols' => isset($visCols) ? '$' . Util::toJSON($visCols) : null]); } } // tab: currency for if ($this->typeId == 103) { $n = '?items&filter=cr=145;crs=1;crv=0'; $w = 'reqArenaPoints > 0'; } else { if ($this->typeId == 104) { $n = '?items&filter=cr=144;crs=1;crv=0'; $w = 'reqHonorPoints > 0'; } else { $n = in_array($this->typeId, [42, 61, 81, 241, 121, 122, 123, 125, 126, 161, 201, 101, 102, 221, 301, 341]) ? '?items&filter=cr=158;crs=' . $_itemId . ';crv=0' : null; $w = 'reqItemId1 = ' . $_itemId . ' OR reqItemId2 = ' . $_itemId . ' OR reqItemId3 = ' . $_itemId . ' OR reqItemId4 = ' . $_itemId . ' OR reqItemId5 = ' . $_itemId; } } $xCosts = DB::Aowow()->selectCol('SELECT id FROM ?_itemextendedcost WHERE ' . $w); $boughtBy = $xCosts ? DB::World()->selectCol('SELECT item FROM npc_vendor WHERE extendedCost IN (?a) UNION SELECT item FROM game_event_npc_vendor WHERE extendedCost IN (?a)', $xCosts, $xCosts) : []; if ($boughtBy) { $boughtBy = new ItemList(array(['id', $boughtBy])); if (!$boughtBy->error) { if ($boughtBy->getMatches() <= CFG_SQL_LIMIT_DEFAULT) { $n = null; } $this->lvTabs[] = array('file' => 'item', 'data' => $boughtBy->getListviewData(ITEMINFO_VENDOR, [TYPE_CURRENCY => $this->typeId]), 'params' => ['name' => '$LANG.tab_currencyfor', 'id' => 'currency-for', 'extraCols' => "\$[Listview.funcBox.createSimpleCol('stack', 'stack', '10%', 'stack')]", 'note' => $n ? sprintf(Util::$filterResultString, $n) : null]); $this->extendGlobalData($boughtBy->getJSGlobals(GLOBALINFO_SELF | GLOBALINFO_RELATED)); } } }