diff --git a/includes/types/item.class.php b/includes/types/item.class.php index 0852c6a6..b6236cec 100644 --- a/includes/types/item.class.php +++ b/includes/types/item.class.php @@ -282,12 +282,14 @@ class ItemList extends BaseType else if ($k < 0) $currency[] = [-$k, $qty]; } + $data[$this->id]['stock'] = $cost['stock']; - $data[$this->id]['cost'] = array( - $this->getField('buyPrice'), - $currency ? $currency : null, - $tokens ? $tokens : null - ); + $data[$this->id]['cost'] = [$this->getField('buyPrice')]; + if ($currency || $tokens) // fill idx:3 if required + $data[$this->id]['cost'][] = $currency; + + if ($tokens) + $data[$this->id]['cost'][] = $tokens; } if ($x = $this->curTpl['buyPrice']) diff --git a/includes/utilities.php b/includes/utilities.php index 12974b9e..bf3afe7c 100644 --- a/includes/utilities.php +++ b/includes/utilities.php @@ -2096,24 +2096,43 @@ class Util return $lv; } - public static function getLootSource($itemId) + public static function getLootSource($itemId, $maxResults = SQL_LIMIT_DEFAULT) { if (!$itemId) return []; - $final = []; + // [fileName, tabData, tabName, tabId, extraCols, hiddenCols, visibleCols] + $tabsFinal = array( + ['item', [], '$LANG.tab_containedin', 'contained-in-item', [], [], []], + ['item', [], '$LANG.tab_disenchantedfrom', 'disenchanted-from', [], [], []], + ['item', [], '$LANG.tab_prospectedfrom', 'prospected-from', [], [], []], + ['item', [], '$LANG.tab_milledfrom', 'milled-from', [], [], []], + ['creature', [], '$LANG.tab_droppedby', 'dropped-by', [], [], []], + ['creature', [], '$LANG.tab_pickpocketedfrom', 'pickpocketed-from', [], [], []], + ['creature', [], '$LANG.tab_skinnedfrom', 'skinned-from', [], [], []], + ['creature', [], '$LANG.tab_minedfromnpc', 'mined-from-npc', [], [], []], + ['creature', [], '$LANG.tab_salvagedfrom', 'salvaged-from', [], [], []], + ['creature', [], '$LANG.tab_gatheredfromnpc', 'gathered-from-npc', [], [], []], + ['quest', [], '$LANG.tab_rewardfrom', 'reward-from-quest', [], [], []], + ['zone', [], '$LANG.tab_fishedin', 'fished-in-zone', [], [], []], + ['object', [], '$LANG.tab_containedin', 'contained-in-object', [], [], []], + ['object', [], '$LANG.tab_minedfrom', 'mined-from-object', [], [], []], + ['object', [], '$LANG.tab_gatheredfrom', 'gathered-from-object', [], [], []], + ['object', [], '$LANG.tab_fishedin', 'fished-in-object', [], [], []], + ['spell', [], '$LANG.tab_createdby', 'created-by', [], [], []] + ); $refResults = []; $chanceMods = []; $query = 'SELECT -lt1.entry AS ARRAY_KEY, - IF (lt1.mincountOrRef > 0, lt1.item, lt1.mincountOrRef) AS item, + IF(lt1.mincountOrRef > 0, lt1.item, lt1.mincountOrRef) AS item, lt1.ChanceOrQuestChance AS chance, SUM(IF(lt2.ChanceOrQuestChance = 0, 1, 0)) AS nZeroItems, SUM(IF(lt2.ChanceOrQuestChance > 0, lt2.ChanceOrQuestChance, 0)) AS sumChance, IF(lt1.groupid > 0, 1, 0) AS isGrouped, - IF (lt1.mincountOrRef > 0, lt1.mincountOrRef, 1) AS min, - IF (lt1.mincountOrRef > 0, lt1.maxcount, 1) AS max, - IF (lt1.mincountOrRef < 0, lt1.maxcount, 1) AS multiplier + IF(lt1.mincountOrRef > 0, lt1.mincountOrRef, 1) AS min, + IF(lt1.mincountOrRef > 0, lt1.maxcount, 1) AS max, + IF(lt1.mincountOrRef < 0, lt1.maxcount, 1) AS multiplier FROM ?# lt1 LEFT JOIN @@ -2124,7 +2143,8 @@ class Util $calcChance = function ($refs, $parents = []) use (&$chanceMods) { - $return = []; + $retData = []; + $retKeys = []; foreach ($refs as $rId => $ref) { @@ -2167,13 +2187,23 @@ class Util if ($stack) // yes, it wants a string .. how weired is that.. $data['pctstack'] = json_encode($stack, JSON_NUMERIC_CHECK); - $return[$rId] = $data; + // sort highest chances first + $i = 0; + for (; $i < count($retData); $i++) + if ($retData[$i]['percent'] < $data['percent']) + break; + + array_splice($retData, $i, 0, [$data]); + array_splice($retKeys, $i, 0, [$rId]); } } - return $return; + return array_combine($retKeys, $retData); }; + /* + get references containing the item + */ $newRefs = DB::Aowow()->select( sprintf($query, 'lt1.item = ?d AND lt1.mincountOrRef > 0'), LOOT_REFERENCE, LOOT_REFERENCE, @@ -2192,44 +2222,143 @@ class Util $refResults += $calcChance($curRefs, array_column($newRefs, 'item')); } + /* + search the real loot-templates for the itemId and gathered refds + */ for ($i = 1; $i < count(self::$lootTemplates); $i++) { - $res = DB::Aowow()->select( + $result = $calcChance(DB::Aowow()->select( sprintf($query, '{lt1.mincountOrRef IN (?a) OR }(lt1.mincountOrRef > 0 AND lt1.item = ?d)'), self::$lootTemplates[$i], self::$lootTemplates[$i], $refResults ? array_keys($refResults) : DBSIMPLE_SKIP, $itemId - ); + )); - if ($_ = $calcChance($res)) + // do not skip here if $result is empty. Additional loot for spells and quest is added separately + + // format for actual use + foreach ($result as $k => $v) { - // format for use in item.php - $sort = []; - foreach ($_ as $k => $v) - { - unset($_[$k]); - $v['percent'] = round($v['percent'] * 100, 3); - $v['key'] = abs($k); // array_multisort issue: it does not preserve numeric keys, restore after sort - $sort[$k] = $v['percent']; - $_[abs($k)] = $v; - } + unset($result[$k]); + $v['percent'] = round($v['percent'] * 100, 3); + $result[abs($k)] = $v; + } - array_multisort($sort, SORT_DESC, $_); + // cap fetched entries to the sql-limit to guarantee, that the highest chance items get selected first + // screws with GO-loot and skinnig-loot as these templates are shared for several tabs (fish, herb, ore) (herb, ore, leather) + $ids = array_slice(array_keys($result), 0, $maxResults); - foreach ($_ as $k => $v) - { - $key = $v['key']; - unset($_[$k]); - unset($v['key']); + switch (self::$lootTemplates[$i]) + { + case LOOT_CREATURE: $field = 'lootId'; $tabId = 4; break; + case LOOT_PICKPOCKET: $field = 'pickpocketLootId'; $tabId = 5; break; + case LOOT_SKINNING: $field = 'skinLootId'; $tabId = -6; break; // assigned later + case LOOT_PROSPECTING: $field = 'id'; $tabId = 2; break; + case LOOT_MILLING: $field = 'id'; $tabId = 3; break; + case LOOT_ITEM: $field = 'id'; $tabId = 0; break; + case LOOT_DISENCHANT: $field = 'disenchantId'; $tabId = 1; break; + case LOOT_FISHING: $field = 'id'; $tabId = 11; break; // subAreas are currently ignored + case LOOT_GAMEOBJECT: + if (!$ids) + break; - $_[$key] = $v; - } + $srcObj = new GameObjectList(array(['type', [OBJECT_CHEST, OBJECT_FISHINGHOLE]], ['data1', $ids])); + if ($srcObj->error) + break; - $final[self::$lootTemplates[$i]] = $_; + $srcData = $srcObj->getListviewData(); + + foreach ($srcObj->iterate() as $curTpl) + { + switch ($curTpl['type']) + { + case 25: $tabId = 15; break; // fishing node + case -3: $tabId = 14; break; // herb + case -4: $tabId = 13; break; // vein + default: $tabId = 12; break; // general chest loot + } + + $tabsFinal[$tabId][1][] = array_merge($srcData[$srcObj->id], $result[$srcObj->getField('lootId')]); + $tabsFinal[$tabId][4][] = 'Listview.extraCols.percent'; + if ($tabId != 15) + $tabsFinal[$tabId][6][] = 'skill'; + } + break; + case LOOT_QUEST: + $conditions = array(['RewardChoiceItemId1', $itemId], ['RewardChoiceItemId2', $itemId], ['RewardChoiceItemId3', $itemId], ['RewardChoiceItemId4', $itemId], ['RewardChoiceItemId5', $itemId], + ['RewardChoiceItemId6', $itemId], ['RewardItemId1', $itemId], ['RewardItemId2', $itemId], ['RewardItemId3', $itemId], ['RewardItemId4', $itemId], + 'OR'); + if ($ids) + $conditions[] = ['qt.RewardMailTemplateId', $ids]; + + $srcObj = new QuestList($conditions); + if (!$srcObj->error) + { + $srcObj->addGlobalsToJscript(self::$pageTemplate, GLOBALINFO_SELF | GLOBALINFO_REWARDS); + $srcData = $srcObj->getListviewData(); + + foreach ($srcObj->iterate() as $_) + $tabsFinal[10][1][] = array_merge($srcData[$srcObj->id], empty($result[$srcObj->id]) ? ['percent' => -1] : $result[$srcObj->id]); + } + break; + case LOOT_SPELL: + $conditions = ['OR', ['effect1CreateItemId', $itemId], ['effect2CreateItemId', $itemId], ['effect3CreateItemId', $itemId]]; + if ($ids) + $conditions[] = ['id', $ids]; + + $srcObj = new SpellList($conditions); + if (!$srcObj->error) + { + $srcObj->addGlobalsToJscript(self::$pageTemplate, GLOBALINFO_SELF | GLOBALINFO_RELATED); + $srcData = $srcObj->getListviewData(); + + if (!empty($result)) + $tabsFinal[16][4][] = 'Listview.extraCols.percent'; + + if ($srcObj->hasSetFields(['reagent1'])) + $tabsFinal[16][6][] = 'reagents'; + + foreach ($srcObj->iterate() as $_) + $tabsFinal[16][1][] = array_merge($srcData[$srcObj->id], empty($result[$srcObj->id]) ? ['percent' => -1] : $result[$srcObj->id]); + } + break; + } + + if (!$ids) + continue; + + switch ($tabsFinal[abs($tabId)][0]) + { + case 'creature': // new CreatureList + case 'item': // new ItemList + case 'zone': // new ZoneList + $oName = ucFirst($tabsFinal[abs($tabId)][0]).'List'; + $srcObj = new $oName(array([$field, $ids])); + if (!$srcObj->error) + { + $srcObj->addGlobalsToJscript(self::$pageTemplate, GLOBALINFO_SELF | GLOBALINFO_RELATED); + $srcData = $srcObj->getListviewData(); + + foreach ($srcObj->iterate() as $_) + { + if ($tabId < 0 && $curTpl['type_flags'] & NPC_TYPEFLAG_HERBLOOT) + $tabId = 9; + else if ($tabId < 0 && $curTpl['type_flags'] & NPC_TYPEFLAG_ENGINEERLOOT) + $tabId = 8; + else if ($tabId < 0 && $curTpl['type_flags'] & NPC_TYPEFLAG_MININGLOOT) + $tabId = 7; + else if ($tabId < 0) + $tabId = abs($tabId); // general case (skinning) + + $tabsFinal[$tabId][1][] = array_merge($srcData[$srcObj->id], $result[$srcObj->getField($field)]); + $tabsFinal[$tabId][4][] = 'Listview.extraCols.percent'; + } + } + break; } } - return $final; + return $tabsFinal; } } diff --git a/pages/currency.php b/pages/currency.php new file mode 100644 index 00000000..2d2e818e --- /dev/null +++ b/pages/currency.php @@ -0,0 +1,223 @@ +loadCache($cacheKeyPage, $pageData)) +{ + $currency = new CurrencyList(array(['id', $_id])); + if ($currency->error) + $smarty->notFound(Lang::$game['skill']); + + $_cat = $currency->getField('category'); + $_itemId = $currency->getField('itemId'); + $_isSpecial = $_id == 103 || $_id == 104; // honor && arena points are not handled as items + + /****************/ + /* Main Content */ + /****************/ + + $pageData = array( + 'title' => $currency->getField('name', true), + 'path' => [0, 15], + 'relTabs' => [], + 'buttons' => array( + BUTTON_WOWHEAD => true, + BUTTON_LINKS => true + ), + 'page' => array( + 'name' => $currency->getField('name', true), + 'icon' => $currency->getField('iconString'), + 'id' => $_id + ), + ); + + if ($_cat) + $pageData['path'][] = $_cat; + + /**************/ + /* Extra Tabs */ + /**************/ + + if (!$_isSpecial) + { + // tabs: this currency is contained in.. + $lootTabs = Util::getLootSource($_itemId); + foreach ($lootTabs as $tab) + { + $pageData['relTabs'][] = array( + 'file' => $tab[0], + 'data' => $tab[1], + 'params' => [ + 'tabs' => '$tabsRelated', + '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] ? '$'. json_encode( array_unique($tab[6])) : null + ] + ); + } + + // tab: sold by + $itemObj = new ItemList(array(['id', $_itemId])); + if ($vendors = @$itemObj->getExtendedCost()[$_itemId]) + { + $soldBy = new CreatureList(array(['id', array_keys($vendors)])); + if (!$soldBy->error) + { + $soldBy->addGlobalsToJscript($smarty, GLOBALINFO_SELF); + $sbData = $soldBy->getListviewData(); + + $extraCols = ['Listview.extraCols.stock', "Listview.funcBox.createSimpleCol('stack', 'stack', '10%', 'stack')", 'Listview.extraCols.cost']; + + $holidays = []; + foreach ($sbData as $k => &$row) + { + $currency = []; + $tokens = []; + foreach ($vendors[$k] as $id => $qty) + { + if (is_string($id)) + continue; + + if ($id > 0) + $tokens[] = [$id, $qty]; + else if ($id < 0) + $currency[] = [-$id, $qty]; + } + + if ($_ = $vendors[$k]['event']) + { + if (count($extraCols) == 3) // not already pushed + $extraCols[] = 'Listview.extraCols.condition'; + + $holidays[$_] = 0; // applied as back ref. + + $row['condition'] = array( + 'type' => TYPE_WORLDEVENT, + 'typeId' => &$holidays[$_], + 'status' => 1 + ); + } + + $row['stock'] = $vendors[$k]['stock']; + $row['stack'] = $item->getField('buyCount'); + $row['cost'] = array( + $item->getField('buyPrice'), + $currency ? $currency : null, + $tokens ? $tokens : null + ); + } + + if ($holidays) + { + $hObj = new WorldEventList(array(['id', array_keys($holidays)])); + $hObj->addGlobalsToJscript($smarty); + foreach ($hObj->iterate() as $id => $tpl) + { + if ($_ = $tpl['holidayId']) + $holidays[$tpl['eventBak']] = $_; + else + $holidays[-$id] = $id; + } + } + + $pageData['relTabs'][] = array( + 'file' => 'creature', + 'data' => $sbData, + 'params' => [ + 'tabs' => '$tabsRelated', + 'name' => '$LANG.tab_soldby', + 'id' => 'sold-by-npc', + 'extraCols' => '$['.implode(', ', $extraCols).']', + 'hiddenCols' => "$['level', 'type']" + ] + ); + } + } + } + + // tab: created by (spell) [for items its handled in Util::getLootSource()] + if ($_id == 104) + { + $createdBy = new SpellList(array(['effect1Id', 45], ['effect2Id', 45], ['effect3Id', 45], 'OR'])); + if (!$createdBy->error) + { + if ($createdBy->hasSetFields(['reagent1'])) + $visCols = ['reagents']; + + $pageData['relTabs'][] = array( + 'file' => 'spell', + 'data' => $createdBy->getListviewData(), + 'params' => [ + 'tabs' => '$tabsRelated', + 'name' => '$LANG.tab_createdby', + 'id' => 'created-by', + 'visibleCols' => isset($visCols) ? '$'.json_encode($visCols) : null + ] + ); + } + } + + // tab: currency for + if ($_id == 103) + $w = 'iec.reqArenaPoints > 0'; + else if ($_id == 104) + $w = 'iec.reqHonorPoints > 0'; + else + $w = 'iec.reqItemId1 = '.$_itemId.' OR iec.reqItemId2 = '.$_itemId.' OR iec.reqItemId3 = '.$_itemId.' OR iec.reqItemId4 = '.$_itemId.' OR iec.reqItemId5 = '.$_itemId; + + $boughtBy = DB::Aowow()->selectCol(' + SELECT item FROM npc_vendor nv JOIN ?_itemExtendedCost iec ON iec.id = nv.extendedCost WHERE '.$w.' + UNION + SELECT item FROM game_event_npc_vendor genv JOIN ?_itemExtendedCost iec ON iec.id = genv.extendedCost WHERE '.$w + ); + if ($boughtBy) + { + $boughtBy = new ItemList(array(['id', $boughtBy])); + if (!$boughtBy->error) + { + $boughtBy->addGlobalsToJscript($smarty); + + $pageData['relTabs'][] = array( + 'file' => 'item', + 'data' => $boughtBy->getListviewData(ITEMINFO_VENDOR, [TYPE_CURRENCY => $_id]), + 'params' => [ + 'tabs' => '$tabsRelated', + 'name' => '$LANG.tab_currencyfor', + 'id' => 'currency-for', + 'extraCols' => "$[Listview.funcBox.createSimpleCol('stack', 'stack', '10%', 'stack'), Listview.extraCols.cost]" + ] + ); + } + } + + $smarty->saveCache($cacheKeyPage, $pageData); +} + +// menuId 14: Skill g_initPath() +// tabId 0: Database g_initHeader() +$smarty->updatePageVars(array( + 'title' => $pageData['title']." - ".Util::ucfirst(Lang::$game['skill']), + 'path' => json_encode($pageData['path'], JSON_NUMERIC_CHECK), + 'tab' => 0, + 'type' => TYPE_CURRENCY, + 'typeId' => $_id +)); +$smarty->assign('redButtons', $pageData['buttons']); +$smarty->assign('community', CommunityContent::getAll(TYPE_CURRENCY, $_id)); // comments, screenshots, videos +$smarty->assign('lang', array_merge(Lang::$main)); +$smarty->assign('lvData', $pageData); + +// load the page +$smarty->display('skill.tpl'); + +?> diff --git a/pages/item.php b/pages/item.php index a52192cd..db439edd 100644 --- a/pages/item.php +++ b/pages/item.php @@ -353,210 +353,24 @@ if (!$smarty->loadCache($cacheKeyPage, $item)) /**************/ // tabs: this item is contained in.. - $sourceTabs = array( - // 0 => refLoot - 1 => ['item', '$LANG.tab_containedin', 'contained-in-item', [], [], []], - 2 => ['item', '$LANG.tab_disenchantedfrom', 'disenchanted-from', [], [], []], - 3 => ['item', '$LANG.tab_prospectedfrom', 'prospected-from', [], [], []], - 4 => ['item', '$LANG.tab_milledfrom', 'milled-from', [], [], []], - 5 => ['creature', '$LANG.tab_droppedby', 'dropped-by', [], [], []], - 6 => ['creature', '$LANG.tab_pickpocketedfrom', 'pickpocketed-from', [], [], []], - 7 => ['creature', '$LANG.tab_skinnedfrom', 'skinned-from', [], [], []], - 8 => ['creature', '$LANG.tab_minedfromnpc', 'mined-from-npc', [], [], []], - 9 => ['creature', '$LANG.tab_salvagedfrom', 'salvaged-from', [], [], []], - 10 => ['creature', '$LANG.tab_gatheredfromnpc', 'gathered-from-npc', [], [], []], - 11 => ['quest', '$LANG.tab_rewardfrom', 'reward-from-quest', [], [], []], - 12 => ['zone', '$LANG.tab_fishedin', 'fished-in-zone', [], [], []], - 13 => ['object', '$LANG.tab_containedin', 'contained-in-object', [], [], []], - 14 => ['object', '$LANG.tab_minedfrom', 'mined-from-object', [], [], []], - 15 => ['object', '$LANG.tab_gatheredfrom', 'gathered-from-object', [], [], []], - 16 => ['object', '$LANG.tab_fishedin', 'fished-in-object', [], [], []], - 17 => ['spell', '$LANG.tab_createdby', 'created-by', [], [], []] - ); - - $data = []; - $questLoot = []; - $spellLoot = []; - $sources = Util::getLootSource($_id); - foreach ($sources as $lootTpl => $lootData) + $lootTabs = Util::getLootSource($_id); + foreach ($lootTabs as $tab) { - // cap fetched entries to the sql-limit to guarantee, that the highest chance items get selected first - $ids = array_slice(array_keys($lootData), 0, SQL_LIMIT_DEFAULT); - - switch ($lootTpl) - { - case LOOT_CREATURE: - $srcType = new CreatureList(array(['ct.lootId', $ids])); - $srcType->addGlobalsToJscript($smarty, GLOBALINFO_SELF | GLOBALINFO_RELATED); - $srcData = $srcType->getListviewData(); - - foreach ($srcType->iterate() as $_) - $data[5][] = array_merge($srcData[$srcType->id], $lootData[$srcType->getField('lootId')]); - - $sourceTabs[5][3][] = 'Listview.extraCols.percent'; - break; - case LOOT_PICKPOCKET: - $srcType = new CreatureList(array(['ct.pickpocketLootId', $ids])); - $srcType->addGlobalsToJscript($smarty, GLOBALINFO_SELF | GLOBALINFO_RELATED); - $srcData = $srcType->getListviewData(); - - foreach ($srcType->iterate() as $_) - $data[6][] = array_merge($srcData[$srcType->id], $lootData[$srcType->getField('pickpocketLootId')]); - - $sourceTabs[6][3][] = 'Listview.extraCols.percent'; - break; - case LOOT_SKINNING: - $srcType = new CreatureList(array(['ct.skinLootId', $ids])); - $srcType->addGlobalsToJscript($smarty, GLOBALINFO_SELF | GLOBALINFO_RELATED); - $srcData = $srcType->getListviewData(); - - foreach ($srcType->iterate() as $curTpl) - { - $tabId = 7; // general case (skinning) - if ($curTpl['type_flags'] & NPC_TYPEFLAG_HERBLOOT) - $tabId = 10; - else if ($curTpl['type_flags'] & NPC_TYPEFLAG_ENGINEERLOOT) - $tabId = 9; - else if ($curTpl['type_flags'] & NPC_TYPEFLAG_MININGLOOT) - $tabId = 8; - - $data[$tabId][] = array_merge($srcData[$srcType->id], $lootData[$srcType->getField('skinLootId')]); - $sourceTabs[$tabId][3][] = 'Listview.extraCols.percent'; - } - - break; - case LOOT_FISHING: - // subAreas are currently ignored - $srcType = new ZoneList(array(['id', $ids])); - $srcType->addGlobalsToJscript($smarty, GLOBALINFO_SELF | GLOBALINFO_RELATED); - $srcData = $srcType->getListviewData(); - - foreach ($srcType->iterate() as $_) - $data[12][] = array_merge($srcData[$srcType->id], $lootData[$srcType->id]); - - $sourceTabs[12][3][] = 'Listview.extraCols.percent'; - break; - case LOOT_GAMEOBJECT: - $srcType = new GameObjectList(array(['type', [OBJECT_CHEST, OBJECT_FISHINGHOLE]], ['data1', $ids])); - $srcData = $srcType->getListviewData(); - - foreach ($srcType->iterate() as $curTpl) - { - $tabId = 13; // general chest loot - if ($curTpl['type'] == -4) // vein - $tabId = 14; - else if ($curTpl['type'] == -3) // herb - $tabId = 15; - else if ($curTpl['type'] == 25) // fishing node - $tabId = 16; - - $data[$tabId][] = array_merge($srcData[$srcType->id], $lootData[$srcType->getField('lootId')]); - $sourceTabs[$tabId][3][] = 'Listview.extraCols.percent'; - $sourceTabs[$tabId][5][] = 'skill'; // conflicts a bit with fishing nodes (no real requirement) - } - break; - case LOOT_PROSPECTING: - $sourceTab = 3; - case LOOT_MILLING: - if (!isset($sourceTab)) - $sourceTab = 4; - case LOOT_ITEM: - if (!isset($sourceTab)) - $sourceTab = 1; - - $srcType = new ItemList(array(['i.id', $ids])); - $srcType->addGlobalsToJscript($smarty, GLOBALINFO_SELF | GLOBALINFO_RELATED); - $srcData = $srcType->getListviewData(); - - foreach ($srcType->iterate() as $_) - $data[$sourceTab][] = array_merge($srcData[$srcType->id], $lootData[$srcType->id]); - - $sourceTabs[$sourceTab][3][] = 'Listview.extraCols.percent'; - break; - case LOOT_DISENCHANT: - $srcType = new ItemList(array(['i.disenchantId', $ids])); - $srcType->addGlobalsToJscript($smarty, GLOBALINFO_SELF | GLOBALINFO_RELATED); - $srcData = $srcType->getListviewData(); - - foreach ($srcType->iterate() as $_) - $data[2][] = array_merge($srcData[$srcType->id], $lootData[$srcType->getField('disenchantId')]); - - $sourceTabs[2][3][] = 'Listview.extraCols.percent'; - break; - case LOOT_QUEST: - // merge regular quest rewards into quest_mail_loot_template results - $questLoot = $ids; - break; - case LOOT_SPELL: - // merge with "created by [spell]" - $spellLoot = $ids; - break; - } - } - - // merge quest rewards with quest_mail_loot - $conditions = array( - 'OR', - ['RewardChoiceItemId1', $_id], ['RewardChoiceItemId2', $_id], ['RewardChoiceItemId3', $_id], ['RewardChoiceItemId4', $_id], ['RewardChoiceItemId5', $_id], - ['RewardChoiceItemId6', $_id], ['RewardItemId1', $_id], ['RewardItemId2', $_id], ['RewardItemId3', $_id], ['RewardItemId4', $_id], - ); - - if ($questLoot) - $conditions[] = ['qt.RewardMailTemplateId', $questLoot]; - - $questLoot = new QuestList($conditions); - if (!$questLoot->error) - { - $questLoot->addGlobalsToJscript($smarty, GLOBALINFO_SELF | GLOBALINFO_REWARDS); - $data[11] = $questLoot->getListviewData(); - } - - // merge spell_loot with "created by [spell]" - $conditions = ['OR', ['effect1CreateitemId', $_id], ['effect2CreateitemId', $_id], ['effect3CreateitemId', $_id]]; - if ($spellLoot) - $conditions[] = ['id', $spellLoot]; - - $spellLoot = new SpellList($conditions); - if (!$spellLoot->error) - { - $spellLoot->addGlobalsToJscript($smarty, GLOBALINFO_SELF | GLOBALINFO_RELATED); - $spellData = $spellLoot->getListviewData(); - - if (!empty($sources[LOOT_SPELL])) - $sourceTabs[17][3][] = 'Listview.extraCols.percent'; - - if ($spellLoot->hasSetFields(['reagent1'])) - $sourceTabs[17][5][] = 'reagents'; - - foreach ($spellLoot->iterate() as $_) - { - if (!empty($sources[LOOT_SPELL][$spellLoot->id])) - $data[17][] = array_merge($spellData[$spellLoot->id], $sources[LOOT_SPELL][$spellLoot->id]); - else - $data[17][] = array_merge($spellData[$spellLoot->id], ['percent' => -1]); - } - } - - foreach ($sourceTabs as $k => $tab) - { - if (empty($data[$k])) - continue; - $pageData['relTabs'][] = array( 'file' => $tab[0], - 'data' => $data[$k], + 'data' => $tab[1], 'params' => [ 'tabs' => '$tabsRelated', - 'name' => $tab[1], - 'id' => $tab[2], - 'extraCols' => $tab[3] ? '$['.implode(', ', array_unique($tab[3])).']' : null, - 'hiddenCols' => $tab[4] ? '$['.implode(', ', array_unique($tab[4])).']' : null, - 'visibleCols' => $tab[5] ? '$'.json_encode($tab[5]) : null + '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] ? '$'. json_encode( array_unique($tab[6])) : null ] ); } - // tabs: this item contains + // tabs: this item contains.. $sourceFor = array( [LOOT_ITEM, $item->id, '$LANG.tab_contains', 'contains', ['Listview.extraCols.percent'], [] , []], [LOOT_PROSPECTING, $item->id, '$LANG.tab_prospecting', 'prospecting', ['Listview.extraCols.percent'], ['side', 'slot', 'reqlevel'], []], @@ -933,11 +747,12 @@ if (!$smarty->loadCache($cacheKeyPage, $item)) $row['stock'] = $vendors[$k]['stock']; $row['stack'] = $item->getField('buyCount'); - $row['cost'] = array( - $item->getField('buyPrice'), - $currency ? $currency : null, - $tokens ? $tokens : null - ); + $row['cost'] = [$this->getField('buyPrice')]; + if ($currency || $tokens) // fill idx:3 if required + $row['cost'][] = $currency; + + if ($tokens) + $row['cost'][] = $tokens; } if ($holidays)