From a8804f6440dbbb62f87f3e9079d18a7b4f971ecb Mon Sep 17 00:00:00 2001 From: Sarjuuk Date: Sun, 7 Jul 2013 23:22:40 +0200 Subject: [PATCH] Achievements: - removed excess escapes (htmlspecialchars really needed?) * urlencode icons for all powered tooltips (some contain obscure symbols) Spell: - added relatedTabs "criteria of" and "contains" (the later should be reworked with generic loot access) * implemented first draft of conditions in listview as extraCol; condition: {type, typeId, status}; currently only inpmplemented in the item-brick * obligatory oneliners all over the place fixing stuff that boggles the mind --- includes/class.achievement.php | 4 +- includes/class.quest.php | 10 +- includes/class.spell.php | 8 +- includes/utilities.php | 2 +- pages/achievement.php | 2 +- pages/item.php | 2 +- pages/spell.php | 181 +++++++++++++++++++---------- template/bricks/globals/quests.tpl | 8 ++ template/bricks/listviews/item.tpl | 3 + template/header.tpl | 3 +- template/js/global.js | 125 +++++++++++++++++++- template/js/locale_dede.js | 2 +- template/spell.tpl | 8 +- 13 files changed, 280 insertions(+), 78 deletions(-) create mode 100644 template/bricks/globals/quests.tpl diff --git a/includes/class.achievement.php b/includes/class.achievement.php index c8668e70..f049dfeb 100644 --- a/includes/class.achievement.php +++ b/includes/class.achievement.php @@ -209,9 +209,9 @@ class AchievementList extends BaseType } if ($crt['complete_flags'] & ACHIEVEMENT_CRITERIA_FLAG_MONEY_COUNTER) - $criteria .= '- '.Util::jsEscape(htmlspecialchars($crtName)).' '.number_format($crt['value2' ] / 10000).'
'; + $criteria .= '- '.htmlspecialchars($crtName).' '.number_format($crt['value2' ] / 10000).'
'; else - $criteria .= '- '.Util::jsEscape(htmlspecialchars($crtName)).'
'; + $criteria .= '- '.htmlspecialchars($crtName).'
'; if (++$i == round(count($rows)/2)) $criteria .= ''; diff --git a/includes/class.quest.php b/includes/class.quest.php index 60290ee2..fe20f9c8 100644 --- a/includes/class.quest.php +++ b/includes/class.quest.php @@ -265,7 +265,15 @@ class QuestList extends BaseType public function addGlobalsToJScript(&$refs) { - // todo + if (!isset($refs['gQuests'])) + $refs['gQuests'] = []; + + while ($this->iterate()) + { + $refs['gQuests'][$this->id] = array( + 'name' => $this->getField('Title', true) + ); + } } } diff --git a/includes/class.spell.php b/includes/class.spell.php index 29dcad6d..87f65019 100644 --- a/includes/class.spell.php +++ b/includes/class.spell.php @@ -50,7 +50,6 @@ class SpellList extends BaseType // required for globals for ($i = 1; $i <= 3; $i++) { - // 24: createItem; 34: changeItem; 59: randomItem; 86: Channel Death Item if ($this->canCreateItem()) $foo[] = (int)$this->curTpl['effect'.$i.'CreateItemId']; } @@ -463,9 +462,9 @@ class SpellList extends BaseType public function canCreateItem() { - // 24: createItem; 34: changeItem; 59: randomItem; 66: Create Mana Gem; 86: Channel Death Item + // 24: createItem; 34: changeItem; 59: randomItem; 66: createManaGem; 157: createitem2; 86: channelDeathItem for ($i = 1; $i < 4; $i++) - if (in_array($this->curTpl['effect'.$i.'Id'], [24, 34, 59, 66]) || $this->curTpl['effect'.$i.'AuraId'] == 86) + if (in_array($this->curTpl['effect'.$i.'Id'], [24, 34, 59, 66, 157]) || $this->curTpl['effect'.$i.'AuraId'] == 86) return true; return false; @@ -1629,7 +1628,10 @@ class SpellList extends BaseType public function addGlobalsToJScript(&$refs) { if ($this->relItems) + { + $this->relItems->reset(); $this->relItems->addGlobalsToJscript($refs); + } $classes = []; $races = []; diff --git a/includes/utilities.php b/includes/utilities.php index c4833aa2..3e1d559e 100644 --- a/includes/utilities.php +++ b/includes/utilities.php @@ -209,7 +209,7 @@ abstract class BaseType return Util::localizedString($this->curTpl, $field); $value = $this->curTpl[$field]; - return is_numeric($value) ? floatVal($value) : $value; + return is_numeric($value) ? floatVal($value) : $value; } public function getMatches() diff --git a/pages/achievement.php b/pages/achievement.php index 7bfe2176..d6689723 100644 --- a/pages/achievement.php +++ b/pages/achievement.php @@ -41,7 +41,7 @@ if (isset($_GET['power'])) $x = '$WowheadPower.registerAchievement('.$id.', '.User::$localeId.",{\n"; $x .= "\tname_".User::$localeString.": '".Util::jsEscape($acv->getField('name', true))."',\n"; - $x .= "\ticon: '".Util::jsEscape($acv->getField('iconString'))."',\n"; + $x .= "\ticon: '".urlencode($acv->getField('iconString'))."',\n"; $x .= "\ttooltip_".User::$localeString.": '".$acv->renderTooltip()."'\n"; $x .= "});"; diff --git a/pages/item.php b/pages/item.php index 80e70dad..90f3cfea 100644 --- a/pages/item.php +++ b/pages/item.php @@ -57,7 +57,7 @@ if (isset($_GET['power'])) $x .= '$WowheadPower.registerItem(\''.$itemString.'\', '.User::$localeId.", {\n"; $x .= "\tname_".User::$localeString.": '".Util::jsEscape($item->getField('name', true))."',\n"; $x .= "\tquality: ".$item->getField('Quality').",\n"; - $x .= "\ticon: '".Util::jsEscape($item->getField('icon'))."',\n"; + $x .= "\ticon: '".urlencode($item->getField('icon'))."',\n"; $x .= "\ttooltip_".User::$localeString.": '".Util::jsEscape($item->tooltip[$id])."'\n"; $x .= "});"; diff --git a/pages/spell.php b/pages/spell.php index 81a1fcbc..334021c3 100644 --- a/pages/spell.php +++ b/pages/spell.php @@ -29,7 +29,7 @@ if (isset($_GET['power'])) if ($n = $spell->getField('name', true)) $pt[] = "\tname_".User::$localeString.": '".Util::jsEscape($n)."'"; if ($i = $spell->getField('iconString')) - $pt[] = "\ticon: '".Util::jsEscape($i)."'"; + $pt[] = "\ticon: '".urlencode($i)."'"; if ($t = $spell->renderTooltip()) $pt[] = "\ttooltip_".User::$localeString.": '".Util::jsEscape($t)."'"; if ($b = $spell->renderBuff()) @@ -103,7 +103,7 @@ if (!$smarty->loadCache($cacheKeyPage, $pageData)) $pageData['path'][] = 410; // Cunning } - $spellArr = $pageData['page'] = $spell->getDetailPageData(); + $pageData['page'] = $spell->getDetailPageData(); // description $pageData['page']['info'] = $spell->renderTooltip(MAX_LEVEL, true); @@ -193,7 +193,7 @@ if (!$smarty->loadCache($cacheKeyPage, $pageData)) foreach ($pageData['page']['tools'] as $k => $tool) { if (isset($tool['itemId'])) // Tool - $pageData['page']['tools'][$k]['url'] = '?item='.$tool; + $pageData['page']['tools'][$k]['url'] = '?item='.$tool['itemId']; else // ToolCat { $pageData['page']['tools'][$k]['quality'] = ITEM_QUALITY_HEIRLOOM - ITEM_QUALITY_NORMAL; @@ -245,9 +245,9 @@ if (!$smarty->loadCache($cacheKeyPage, $pageData)) // Icons: // .. from item - if ($spell->canCreateItem()) + if ($spell->canCreateItem() && ($_ = $spell->getField('effect'.$i.'CreateItemId')) && $_ > 0) { - while ($spell->relItems->id != $spell->getField('effect'.$i.'CreateItemId')) + while ($spell->relItems->id != $_) $spell->relItems->iterate(); $foo['icon'] = array( @@ -555,6 +555,7 @@ if (!$smarty->loadCache($cacheKeyPage, $pageData)) if (in_array($effAura, [11, 12, 36, 77]) || in_array($effId, [])) unset($foo['value']); } + unset($foo); // clear reference $pageData['infobox'] = $infobox ? '[ul]'.implode('', $infobox).'[/ul]' : null; @@ -596,9 +597,9 @@ if (!$smarty->loadCache($cacheKeyPage, $pageData)) $pageData['modifies'] = array( 'data' => $modSpells->getListviewData(), 'params' => [ - 'tabs' => '$tabsRelated', - 'id' => 'modifies', - 'name' => '$LANG.tab_modifies', + 'tabs' => '$tabsRelated', + 'id' => 'modifies', + 'name' => '$LANG.tab_modifies', 'visibleCols' => "$['level']" ] ); @@ -611,7 +612,10 @@ if (!$smarty->loadCache($cacheKeyPage, $pageData)) // modified by $this $sub = ['OR']; - $conditions = [['s.spellFamilyId', $spell->getField('spellFamilyId')], &$sub]; + $conditions = [ + ['s.spellFamilyId', $spell->getField('spellFamilyId')], + &$sub] + ; for ($i = 1; $i < 4; $i++) { @@ -642,9 +646,9 @@ if (!$smarty->loadCache($cacheKeyPage, $pageData)) $pageData['modifiedBy'] = array( 'data' => $modsSpell->getListviewData(), 'params' => [ - 'tabs' => '$tabsRelated', - 'id' => 'modified-by', - 'name' => '$LANG.tab_modifiedby', + 'tabs' => '$tabsRelated', + 'id' => 'modified-by', + 'name' => '$LANG.tab_modifiedby', 'visibleCols' => "$['level']" ] ); @@ -671,9 +675,9 @@ if (!$smarty->loadCache($cacheKeyPage, $pageData)) $pageData['seeAlso'] = array( 'data' => $saSpells->getListviewData(), 'params' => [ - 'tabs' => '$tabsRelated', - 'id' => 'see-also', - 'name' => '$LANG.tab_seealso', + 'tabs' => '$tabsRelated', + 'id' => 'see-also', + 'name' => '$LANG.tab_seealso', 'visibleCols' => "$['level']" ] ); @@ -720,7 +724,7 @@ if (!$smarty->loadCache($cacheKeyPage, $pageData)) if (!$ubItems->error) { $pageData['usedByItem'] = array( - 'data' => $ubItems->getListviewData(0x0), + 'data' => $ubItems->getListviewData(), 'params' => [ 'tabs' => '$tabsRelated', 'id' => 'used-by-item', @@ -731,20 +735,107 @@ if (!$smarty->loadCache($cacheKeyPage, $pageData)) $ubItems->addGlobalsToJScript($pageData); } - /* contains [Open Lock Item] + // criteria of + $_ = [ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2, ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL, ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2, ACHIEVEMENT_CRITERIA_TYPE_LEARN_SPELL]; + if ($crs = DB::Aowow()->selectCol('SELECT refAchievement FROM ?_achievementCriteria WHERE type IN (?a) AND value1 = ?d', $_, $spell->id)) + { + $coAchievemnts = new AchievementList(array(['id', $crs])); + if (!$coAchievemnts->error) + { + $pageData['criteriaOf'] = array( + 'data' => $coAchievemnts->getListviewData(), + 'params' => [ + 'tabs' => '$tabsRelated', + 'id' => 'criteria-of', + 'name' => '$LANG.tab_criteriaof' + ] + ); - effect.$i.Id = 59 - check spell_loot_template - ['contains'] - reset icon..? - * + $coAchievemnts->addGlobalsToJScript($pageData); + } + } - /* related spells - at least 2 similar effects AND - names identical AND - ids not identical - */ - $spellArr['seeAlso'] = []; + // "contains" + // spell_loot_template & skill_extra_item_template + $extraItem = DB::Aowow()->selectRow('SELECT * FROM skill_extra_item_template WHERE spellid = ?d', $spell->id); + $spellLoot = DB::Aowow()->select('SELECT *, item as ARRAY_KEY FROM spell_loot_template WHERE entry = ?d', $spell->id); + if ($extraItem || $spellLoot) + { + $ids = []; + $lv = []; + $extraCols = ['Listview.extraCols.percent']; + foreach ($spellLoot as $row) + $ids[] = (int)$row['item']; + + if ($ids) + { + // todo (high): generic loot-processing function + $slItems = new ItemList(array(['i.entry', $ids])); + $slItems->addGlobalsToJscript($pageData); + $lv += $slItems->getListviewData(); + + $equal = true; + foreach ($lv as $k => $v) + { + $chance = $spellLoot[$k]['ChanceOrQuestChance']; + if ($chance) + $equal = false; + + $lv[$k]['percent'] = $chance; + if ($spellLoot[$k]['maxcount'] > 1) + { + $lv[$k]['maxcount'] = $spellLoot[$k]['maxcount']; + $lv[$k]['mincount'] = $spellLoot[$k]['mincountOrRef'] > 0 ? $spellLoot[$k]['mincountOrRef'] : 1; + } + } + + if ($equal) + foreach ($lv as &$_) + $_['percent'] = number_format(100 / count($lv), 2); + } + + if ($extraItem && $spell->canCreateItem()) + { + $spell->relItems->reset(); + $foo = $spell->relItems->getListviewData(); + + for ($i = 1; $i < 4; $i++) + { + if (($bar = $spell->getField('effect'.$i.'CreateItemId')) && isset($foo[$bar])) + { + $reqSpec = new SpellList(array(['s.id', (int)$extraItem['requiredSpecialization']])); + $lv[$bar] = $foo[$bar]; + $lv[$bar]['percent'] = $extraItem['additionalCreateChance']; + $lv[$bar]['condition'] = json_encode(['type' => TYPE_SPELL, 'typeId' => $reqSpec->id, 'status' => 2], JSON_NUMERIC_CHECK); + $reqSpec->addGlobalsToJscript($pageData); + + $extraCols[] = 'Listview.extraCols.condition'; + if ($max = $extraItem['additionalMaxNum']) + { + $lv[$bar]['mincount'] = 1; + $lv[$bar]['maxcount'] = $max; + } + + break; // skill_extra_item_template can only contain 1 item + } + } + } + + $pageData['contains'] = array( + 'data' => $lv, + 'params' => [ + 'tabs' => '$tabsRelated', + 'name' => '$LANG.tab_contains', + 'id' => 'contains', + 'hiddenCols' => "$['side', 'slot', 'source', 'reqlevel']", + 'extraCols' => "$[".implode(', ', $extraCols)."]" + ] + ); + } + + // teaches + // spell_learn_spell + // skill_discovery_template /* source trainer first check source if not trainer : break @@ -828,40 +919,6 @@ if (!$smarty->loadCache($cacheKeyPage, $pageData)) // if(!$spellArr['taughtbynpc']) // unset($spellArr['taughtbynpc']); - // achievement criteria - $rows = []; - // DB::Aowow()->select(' - // SELECT a.id, a.faction, a.name_loc?d AS name, a.description_loc?d AS description, a.category, a.points, s.iconname, z.areatableID - // FROM ?_spellicons s, ?_achievementcriteria c, ?_achievement a - // LEFT JOIN (?_zones z) ON a.map != -1 AND a.map = z.mapID - // WHERE - // a.icon = s.id - // AND a.id = c.refAchievement - // AND c.type IN (?a) - // AND c.value1 = ?d - // GROUP BY a.id - // ORDER BY a.name_loc?d - // ', - // User::$localeId, - // User::$localeId, - // array( - // ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2, - // ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL, ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2, - // ACHIEVEMENT_CRITERIA_TYPE_LEARN_SPELL - // ), - // $spellArr['entry'], - // User::$localeId - // ); - if($rows) - { - $spellArr['criteria_of'] = []; - foreach($rows as $row) - { - allachievementsinfo2($spell->getField('id')); - $spellArr['criteria_of'][] = achievementinfo2($row); - } - } - $smarty->saveCache($cacheKeyPage, $pageData); } diff --git a/template/bricks/globals/quests.tpl b/template/bricks/globals/quests.tpl new file mode 100644 index 00000000..4d1834e8 --- /dev/null +++ b/template/bricks/globals/quests.tpl @@ -0,0 +1,8 @@ +var _ = g_quests; +{strip} +{foreach from=$data key=id item=item} + _[{$id}]={ldelim} + name_{$user.language}:'{$item.name|escape:"javascript"}', + {rdelim}; +{/foreach} +{/strip} diff --git a/template/bricks/listviews/item.tpl b/template/bricks/listviews/item.tpl index ed8d8e62..4d71a25e 100644 --- a/template/bricks/listviews/item.tpl +++ b/template/bricks/listviews/item.tpl @@ -31,6 +31,9 @@ {if isset($curr.percent)} percent:{$curr.percent}, {/if} + {if isset($curr.condition)} + condition:{$curr.condition}, + {/if} {if isset($curr.group) and isset($curr.groupcount)} group:'({$curr.group}){if $curr.groupcount!=1} x{$curr.groupcount}{/if}', {/if} diff --git a/template/header.tpl b/template/header.tpl index c26fbfe9..9cd4c9e7 100644 --- a/template/header.tpl +++ b/template/header.tpl @@ -40,5 +40,6 @@ {if isset($lvData.gSpells)} { include file='bricks/globals/spells.tpl' data=$lvData.gSpells }{/if} {if isset($lvData.gTitles)} { include file='bricks/globals/titles.tpl' data=$lvData.gTitles }{/if} {if isset($lvData.gCreatures)} { include file='bricks/globals/creatures.tpl' data=$lvData.gCreatures }{/if} - {* TODO: Factions, Quests, Objects, g_gatheredzones(?) *} + {if isset($lvData.gQuests)} { include file='bricks/globals/quests.tpl' data=$lvData.gQuests }{/if} + {* TODO: Factions, Objects, g_gatheredzones(?) *} {/strip} diff --git a/template/js/global.js b/template/js/global.js index 10f8b431..dba7f021 100644 --- a/template/js/global.js +++ b/template/js/global.js @@ -2188,6 +2188,7 @@ function g_staticTooltipLevelClick(div, level) { minLevel = parseInt(_[2]), maxLevel = parseInt(_[3]), curLevel = parseInt(_[4]); + if (!level) { // Prompt for level level = prompt(sprintf(LANG.prompt_ratinglevel, minLevel, maxLevel), curLevel); } @@ -6352,7 +6353,129 @@ Listview.extraCols = { return -strcmp(g_items[a.yield].quality, g_items[b.yield].quality) || strcmp(g_items[a.yield]['name_' + g_locale.name], g_items[b.yield]['name_' + g_locale.name]); } - } + }, + + condition: { + /* + condition.status: [ + 0: missing + 1: active + 2: done / obtained + ] + + LANG.completed + LANG.earned + LANG.progress + + probably also events, zones, skill, faction, .. + */ + + id: 'condition', + name: LANG.requires, + compute: function(row, td) { + td.className = 'small'; + td.style.lineHeight = '18px'; + + if (row.condition) { + switch(g_types[row.condition.type]) { + case 'spell': + return Listview.extraCols.condition.getSpellText(row.condition, td); + case 'item': + return Listview.extraCols.condition.getItemText(row.condition, td); + case 'achievement': + return Listview.extraCols.condition.getAchievementText(row.condition, td); + case 'quest': + return Listview.extraCols.condition.getQuestText(row.condition, td); + default: + return 'unhandled condition'; + } + } + }, + getSpellText: function(cond, td) { + if (!cond.typeId || !g_spells[cond.typeId]) { + return; + } + + var item = g_spells[cond.typeId]; + var span = ce('span'); + span.className = cond.status ? 'q2' : 'q10'; + ae(span, cond.status ? ct(LANG.pr_note_known) : ct(LANG.pr_note_missing)); + ae(td, span); + ae(td, ce('br')); + + var a = ce('a'); + a.href = '?spell=' + cond.typeId; + a.className = 'icontiny tinyspecial'; + a.style.backgroundImage = 'url(' + g_staticUrl + '/images/icons/tiny/' + item.icon.toLowerCase() + '.gif)'; + a.style.whiteSpace = 'nowrap'; + ae(a, ct(item['name_' + g_locale.name])); + ae(td, a); + }, + getItemText: function(cond, td) { + if (!cond.typeId || !g_items[cond.typeId]) { + return; + } + + var item = g_items[cond.typeId]; + var span = ce('span'); + span.className = cond.status ? 'q2' : 'q10'; + ae(span, cond.status ? ct(LANG.pr_note_earned) : ct(LANG.pr_note_missing)); + ae(td, span); + ae(td, ce('br')); + + var a = ce('a'); + a.href = '?item=' + cond.typeId; + a.className = 'icontiny tinyspecial'; + a.className += ' q' + item.quality; + a.style.backgroundImage = 'url(' + g_staticUrl + '/images/icons/tiny/' + item.icon.toLowerCase() + '.gif)'; + a.style.whiteSpace = 'nowrap'; + ae(a, ct(item['name_' + g_locale.name])); + ae(td, a); + }, + getAchievementText: function(cond, td) { + if (!cond.typeId || !g_achievements[cond.typeId]) { + return; + } + + var item = g_achievements[cond.typeId]; + var span = ce('span'); + span.className = cond.status ? 'q2' : 'q10'; + ae(span, cond.status ? ct(LANG.pr_note_earned) : ct(LANG.pr_note_incomplete)); + ae(td, span); + ae(td, ce('br')); + + var a = ce('a'); + a.href = '?achievement=' + cond.typeId; + a.className = 'icontiny tinyspecial'; + a.style.backgroundImage = 'url(' + g_staticUrl + '/images/icons/tiny/' + item.icon.toLowerCase() + '.gif)'; + a.style.whiteSpace = 'nowrap'; + st(a, item['name_' + g_locale.name]); + ae(td, a); + }, + getQuestText: function(cond, td) { + if (!cond.typeId || !g_quests[cond.typeId]) { + return; + } + + var item = g_quests[cond.typeId]; + var span = ce('span'); + span.className = cond.status == 1 ? 'q1' : cond.status == 2 ? 'q2' : 'q10'; + ae(span, cond.status == 1 ? ct(LANG.progress) : cond.status == 2 ? ct(LANG.pr_note_complete) : ct(LANG.pr_note_incomplete)); + ae(td, span); + ae(td, ce('br')); + + var a = ce('a'); + a.href = '?quest=' + cond.typeId; + a.style.whiteSpace = 'nowrap'; + st(a, item['name_' + g_locale.name]); + ae(td, a); + }, + sortFunc: function(a, b, col) { + if (a.condition.status && b.condition.status) { + return strcmp(a.condition.status, b.condition.status); + } + } + }, }; Listview.funcBox = { diff --git a/template/js/locale_dede.js b/template/js/locale_dede.js index f4bde372..6604f58d 100644 --- a/template/js/locale_dede.js +++ b/template/js/locale_dede.js @@ -2172,7 +2172,7 @@ var LANG = { amount: "Menge", abilities: "Fähigkeiten", activity: "Aktivität", - animation: "Animation", + animation: "Animation", armor: "Rüstung", text: "Text", author: "Autor", diff --git a/template/spell.tpl b/template/spell.tpl index dcdf9586..ccdae05d 100644 --- a/template/spell.tpl +++ b/template/spell.tpl @@ -69,8 +69,8 @@ {/section} {if $lvData.page.reagents}{/if}{/if} @@ -194,14 +194,14 @@ {if isset($lvData.seeAlso)} {include file='bricks/listviews/spell.tpl' data=$lvData.seeAlso.data params=$lvData.seeAlso.params } {/if} {if isset($lvData.usedByItem)} {include file='bricks/listviews/item.tpl' data=$lvData.usedByItem.data params=$lvData.usedByItem.params } {/if} {if isset($lvData.usedByItemset)} {include file='bricks/listviews/itemset.tpl' data=$lvData.usedByItemset.data params=$lvData.usedByItemset.params} {/if} +{if isset($lvData.criteriaOf)} {include file='bricks/listviews/achievement.tpl' data=$lvData.criteriaOf.data params=$lvData.criteriaOf.params } {/if} +{if isset($lvData.contains)} {include file='bricks/listviews/item.tpl' data=$lvData.contains.data params=$lvData.contains.params } {/if} {if isset($lvData.taughtbynpc)} {include file='bricks/listviews/creature.tpl' data=$lvData.taughtbynpc.data params=$lvData.taughtbynpc.params } {/if} {if isset($lvData.taughtbyitem)} {include file='bricks/listviews/item.tpl' data=$lvData.taughtbyitem.data params=$lvData.taughtbyitem.params } {/if} {if isset($lvData.taughtbyquest)} {include file='bricks/listviews/quest.tpl' data=$lvData.taughtbyquest.data params=$lvData.taughtbyquest.params} {/if} {if isset($lvData.questreward)} {include file='bricks/listviews/quest.tpl' data=$lvData.questreward.data params=$lvData.questreward.params } {/if} {if isset($lvData.usedbynpc)} {include file='bricks/listviews/creature.tpl' data=$lvData.usedbynpc.data params=$lvData.usedbynpc.params } {/if} -{if isset($lvData.contains)} {include file='bricks/listviews/item.tpl' data=$lvData.contains.data params=$lvData.contains.params } {/if} -{if isset($lvData.criteria_of)} {include file='bricks/listviews/achievement.tpl' data=$lvData.criteria_of.data params=$lvData.criteria_of.params } {/if} new Listview({ldelim}template: 'comment', id: 'comments', name: LANG.tab_comments, tabs: tabsRelated, parent: 'listview-generic', data: lv_comments{rdelim}); new Listview({ldelim}template: 'screenshot', id: 'screenshots', name: LANG.tab_screenshots, tabs: tabsRelated, parent: 'listview-generic', data: lv_screenshots{rdelim}); if (lv_videos.length || (g_user && g_user.roles & (U_GROUP_ADMIN | U_GROUP_BUREAU | U_GROUP_VIDEO)))