diff --git a/includes/defines.php b/includes/defines.php index fd330894..0f60c8a9 100644 --- a/includes/defines.php +++ b/includes/defines.php @@ -27,6 +27,7 @@ define('TYPE_CURRENCY', 17); // internal types (not published to js) define('TYPE_USER', 500); define('TYPE_EMOTE', 501); +define('TYPE_ENCHANTMENT', 502); define('CACHE_TYPE_NONE', 0); // page will not be cached define('CACHE_TYPE_PAGE', 1); diff --git a/includes/types/emote.class.php b/includes/types/emote.class.php index 09d52503..674c1e2d 100644 --- a/includes/types/emote.class.php +++ b/includes/types/emote.class.php @@ -11,6 +11,18 @@ class EmoteList extends BaseType protected $queryBase = 'SELECT *, e.id AS ARRAY_KEY FROM ?_emotes e'; + public function __construct($conditions = []) + { + parent::__construct($conditions); + + // post processing + foreach ($this->iterate() as &$curTpl) + { + // remap for generic access + $curTpl['name'] = $curTpl['cmd']; + } + } + public function getListviewData() { $data = []; @@ -31,7 +43,12 @@ class EmoteList extends BaseType public function getJSGlobals($addMask = GLOBALINFO_ANY) { - return []; + $data = []; + + foreach ($this->iterate() as $__) + $data[TYPE_EMOTE][$this->id] = ['name' => $this->getField('cmd')]; + + return $data; } public function renderTooltip() { } diff --git a/includes/types/enchantment.class.php b/includes/types/enchantment.class.php new file mode 100644 index 00000000..125889df --- /dev/null +++ b/includes/types/enchantment.class.php @@ -0,0 +1,279 @@ + TYPE_ENCHANTMENT + 'ie' => [['is']], + 'is' => ['j' => ['?_item_stats `is` ON `is`.`type` = 502 AND `is`.`typeId` = `ie`.`id`', true], 's' => ', `is`.*'], + ); + + public function __construct($conditions = []) + { + parent::__construct($conditions); + + // post processing + foreach ($this->iterate() as &$curTpl) + { + $curTpl['spells'] = []; // [spellId, triggerType, charges, chanceOrPpm] + for ($i = 1; $i <=3; $i++) + { + if ($curTpl['object'.$i] <= 0) + continue; + + switch ($curTpl['type'.$i]) + { + case 1: + $proc = -$this->getField('ppmRate') ?: ($this->getField('procChance') ?: $this->getField('amount'.$i)); + $curTpl['spells'][$i] = [$curTpl['object'.$i], 2, $curTpl['charges'], $proc]; + $this->relSpells[] = $curTpl['object'.$i]; + break; + case 3: + $curTpl['spells'][$i] = [$curTpl['object'.$i], 1, $curTpl['charges'], 0]; + $this->relSpells[] = $curTpl['object'.$i]; + break; + case 7: + $curTpl['spells'][$i] = [$curTpl['object'.$i], 0, $curTpl['charges'], 0]; + $this->relSpells[] = $curTpl['object'.$i]; + break; + } + } + + // floats are fetched as string from db :< + Util::checkNumeric($curTpl); + + // remove zero-stats + foreach (Util::$itemMods as $str) + if ($curTpl[$str] == 0) // empty(0.0f) => true .. yeah, sure + unset($curTpl[$str]); + + if ($curTpl['dps'] == 0) + unset($curTpl['dps']); + } + + if ($this->relSpells) + $this->relSpells = new SpellList(array(['id', $this->relSpells])); + } + + // use if you JUST need the name + public static function getName($id) + { + $n = DB::Aowow()->SelectRow('SELECT name_loc0, name_loc2, name_loc3, name_loc6, name_loc8 FROM ?_itemenchantment WHERE id = ?d', $id ); + return Util::localizedString($n, 'name'); + } + // end static use + + public function getListviewData($addInfoMask = 0x0) + { + $data = []; + + foreach ($this->iterate() as $__) + { + $data[$this->id] = array( + 'id' => $this->id, + 'name' => $this->getField('name', true), + 'spells' => [] + ); + + if ($this->curTpl['skillLine'] > 0) + $data[$this->id]['reqskill'] = $this->curTpl['skillLine']; + + if ($this->curTpl['skillLevel'] > 0) + $data[$this->id]['reqskillrank'] = $this->curTpl['skillLevel']; + + if ($this->curTpl['requiredLevel'] > 0) + $data[$this->id]['reqlevel'] = $this->curTpl['requiredLevel']; + + foreach ($this->curTpl['spells'] as $s) + { + // enchant is procing or onUse + if ($s[1] == 2 || $s[1] == 0) + $data[$this->id]['spells'][$s[0]] = $s[2]; + // spell is procing + else if ($this->relSpells && $this->relSpells->getEntry($s[0]) && ($_ = $this->relSpells->canTriggerSpell())) + { + foreach ($_ as $idx) + { + $this->triggerIds[] = $this->relSpells->getField('effect'.$idx.'TriggerSpell'); + $data[$this->id]['spells'][$this->relSpells->getField('effect'.$idx.'TriggerSpell')] = $s[2]; + } + } + } + + if (!$data[$this->id]['spells']) + unset($data[$this->id]['spells']); + + Util::arraySumByKey($data[$this->id], $this->getStatGain()); + } + + return $data; + } + + public function getStatGain() + { + $data = []; + + foreach (Util::$itemMods as $str) + if (isset($this->curTpl[$str])) + $data[$str] = $this->curTpl[$str]; + + if (isset($this->curTpl['dps'])) + $data['dps'] = $this->curTpl['dps']; + + return $data; + } + + public function getRelSpell($id) + { + if ($this->relSpells) + return $this->relSpells->getEntry($id); + + return null; + } + + public function getJSGlobals($addMask = GLOBALINFO_ANY) + { + $data = []; + + if ($addMask & GLOBALINFO_SELF) + foreach ($this->iterate() as $__) + $data[TYPE_ENCHANTMENT][$this->id] = ['name' => $this->getField('name', true)]; + + if ($addMask & GLOBALINFO_RELATED) + { + if ($this->relSpells) + $data = $this->relSpells->getJSGlobals(GLOBALINFO_SELF); + + foreach ($this->triggerIds as $tId) + if (empty($data[TYPE_SPELL][$tId])) + $data[TYPE_SPELL][$tId] = $tId; + } + + return $data; + } + + public function renderTooltip() { } +} + + +class EnchantmentListFilter extends Filter +{ + protected $enums = array( + 3 => array( // requiresprof + null, 171, 164, 185, 333, 202, 129, 755, 165, 186, 197, true, false, 356, 182, 773 + ) + ); + + protected $genericFilter = array( // misc (bool): _NUMERIC => useFloat; _STRING => localized; _FLAG => match Value; _BOOLEAN => stringSet + 2 => [FILTER_CR_NUMERIC, 'id', null, true], // id + 3 => [FILTER_CR_ENUM, 'skillLine' ], // requiresprof + 4 => [FILTER_CR_NUMERIC, 'skillLevel', ], // reqskillrank + 5 => [FILTER_CR_BOOLEAN, 'conditionId' ], // hascondition + 10 => [FILTER_CR_FLAG, 'cuFlags', CUSTOM_HAS_COMMENT ], // hascomments + 11 => [FILTER_CR_FLAG, 'cuFlags', CUSTOM_HAS_SCREENSHOT ], // hasscreenshots + 12 => [FILTER_CR_FLAG, 'cuFlags', CUSTOM_HAS_VIDEO ], // hasvideos + 21 => [FILTER_CR_NUMERIC, 'is.agi', null, true], // agi + 23 => [FILTER_CR_NUMERIC, 'is.int', null, true], // int + 22 => [FILTER_CR_NUMERIC, 'is.sta', null, true], // sta + 24 => [FILTER_CR_NUMERIC, 'is.spi', null, true], // spi + 20 => [FILTER_CR_NUMERIC, 'is.str', null, true], // str + 115 => [FILTER_CR_NUMERIC, 'is.health', null, true], // health + 116 => [FILTER_CR_NUMERIC, 'is.mana', null, true], // mana + 60 => [FILTER_CR_NUMERIC, 'is.healthrgn', null, true], // healthrgn + 61 => [FILTER_CR_NUMERIC, 'is.manargn', null, true], // manargn + 41 => [FILTER_CR_NUMERIC, 'is.armor' , null, true], // armor + 44 => [FILTER_CR_NUMERIC, 'is.blockrtng', null, true], // blockrtng + 43 => [FILTER_CR_NUMERIC, 'is.block', null, true], // block + 42 => [FILTER_CR_NUMERIC, 'is.defrtng', null, true], // defrtng + 45 => [FILTER_CR_NUMERIC, 'is.dodgertng', null, true], // dodgertng + 46 => [FILTER_CR_NUMERIC, 'is.parryrtng', null, true], // parryrtng + 79 => [FILTER_CR_NUMERIC, 'is.resirtng', null, true], // resirtng + 77 => [FILTER_CR_NUMERIC, 'is.atkpwr', null, true], // atkpwr + 97 => [FILTER_CR_NUMERIC, 'is.feratkpwr', null, true], // feratkpwr + 114 => [FILTER_CR_NUMERIC, 'is.armorpenrtng', null, true], // armorpenrtng + 96 => [FILTER_CR_NUMERIC, 'is.critstrkrtng', null, true], // critstrkrtng + 117 => [FILTER_CR_NUMERIC, 'is.exprtng', null, true], // exprtng + 103 => [FILTER_CR_NUMERIC, 'is.hastertng', null, true], // hastertng + 119 => [FILTER_CR_NUMERIC, 'is.hitrtng', null, true], // hitrtng + 94 => [FILTER_CR_NUMERIC, 'is.splpen', null, true], // splpen + 123 => [FILTER_CR_NUMERIC, 'is.splpwr', null, true], // splpwr + 52 => [FILTER_CR_NUMERIC, 'is.arcsplpwr', null, true], // arcsplpwr + 53 => [FILTER_CR_NUMERIC, 'is.firsplpwr', null, true], // firsplpwr + 54 => [FILTER_CR_NUMERIC, 'is.frosplpwr', null, true], // frosplpwr + 55 => [FILTER_CR_NUMERIC, 'is.holsplpwr', null, true], // holsplpwr + 56 => [FILTER_CR_NUMERIC, 'is.natsplpwr', null, true], // natsplpwr + 57 => [FILTER_CR_NUMERIC, 'is.shasplpwr', null, true], // shasplpwr + 32 => [FILTER_CR_NUMERIC, 'is.dps', true, true], // dps + 34 => [FILTER_CR_NUMERIC, 'is.dmg', true, true], // dmg + 25 => [FILTER_CR_NUMERIC, 'is.arcres', null, true], // arcres + 26 => [FILTER_CR_NUMERIC, 'is.firres', null, true], // firres + 28 => [FILTER_CR_NUMERIC, 'is.frores', null, true], // frores + 30 => [FILTER_CR_NUMERIC, 'is.holres', null, true], // holres + 27 => [FILTER_CR_NUMERIC, 'is.natres', null, true], // natres + 29 => [FILTER_CR_NUMERIC, 'is.shares', null, true], // shares + 37 => [FILTER_CR_NUMERIC, 'is.mleatkpwr', null, true], // mleatkpwr + 84 => [FILTER_CR_NUMERIC, 'is.mlecritstrkrtng', null, true], // mlecritstrkrtng + 78 => [FILTER_CR_NUMERIC, 'is.mlehastertng', null, true], // mlehastertng + 95 => [FILTER_CR_NUMERIC, 'is.mlehitrtng', null, true], // mlehitrtng + 38 => [FILTER_CR_NUMERIC, 'is.rgdatkpwr', null, true], // rgdatkpwr + 40 => [FILTER_CR_NUMERIC, 'is.rgdcritstrkrtng', null, true], // rgdcritstrkrtng + 101 => [FILTER_CR_NUMERIC, 'is.rgdhastertng', null, true], // rgdhastertng + 39 => [FILTER_CR_NUMERIC, 'is.rgdhitrtng', null, true], // rgdhitrtng + 49 => [FILTER_CR_NUMERIC, 'is.splcritstrkrtng', null, true], // splcritstrkrtng + 102 => [FILTER_CR_NUMERIC, 'is.splhastertng', null, true], // splhastertng + 48 => [FILTER_CR_NUMERIC, 'is.splhitrtng', null, true], // splhitrtng + 51 => [FILTER_CR_NUMERIC, 'is.spldmg', null, true], // spldmg + 50 => [FILTER_CR_NUMERIC, 'is.splheal', null, true] // splheal + ); + + 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]; + } + } + + protected function createSQLForValues() + { + $parts = []; + $_v = &$this->fiData['v']; + + //string + if (isset($_v['na'])) + if ($_ = $this->modularizeString(['name_loc'.User::$localeId])) + $parts[] = $_; + + // type + if (isset($_v['ty'])) + { + $_ = (array)$_v['ty']; + if (!array_diff($_, [1, 2, 3, 4, 5, 6, 7, 8])) + $parts[] = ['OR', ['type1', $_], ['type2', $_], ['type3', $_]]; + else + unset($_v['ty']); + } + + return $parts; + } +} + +?> diff --git a/includes/types/item.class.php b/includes/types/item.class.php index 93d3845b..50d079c6 100644 --- a/includes/types/item.class.php +++ b/includes/types/item.class.php @@ -24,13 +24,13 @@ class ItemList extends BaseType private $jsGlobals = []; // getExtendedCost creates some and has no access to template protected $queryBase = 'SELECT i.*, i.id AS ARRAY_KEY, i.id AS id FROM ?_items i'; - protected $queryOpts = array( + protected $queryOpts = array( // 3 => TYPE_ITEM 'i' => [['is', 'src', 'ic'], 'o' => 'i.quality DESC, i.itemLevel DESC'], - 'ic' => ['j' => ['?_icons ic ON ic.id = -i.displayId', true], 's' => ', ic.iconString'], - 'is' => ['j' => ['?_item_stats `is` ON `is`.`id` = `i`.`id`', true], 's' => ', `is`.*'], - 's' => ['j' => ['?_spell `s` ON s.effect1CreateItemId = i.id', true], 'g' => 'i.id'], - 'e' => ['j' => ['?_events `e` ON e.id = i.eventId', true], 's' => ', e.holidayId'], - 'src' => ['j' => ['?_source src ON type = 3 AND typeId = i.id', true], 's' => ', moreType, moreTypeId, src1, src2, src3, src4, src5, src6, src7, src8, src9, src10, src11, src12, src13, src14, src15, src16, src17, src18, src19, src20, src21, src22, src23, src24'] + 'ic' => ['j' => ['?_icons `ic` ON `ic`.`id` = -`i`.`displayId`', true], 's' => ', ic.iconString'], + 'is' => ['j' => ['?_item_stats `is` ON `is`.`type` = 3 AND `is`.`typeId` = `i`.`id`', true], 's' => ', `is`.*'], + 's' => ['j' => ['?_spell `s` ON `s`.`effect1CreateItemId` = `i`.`id`', true], 'g' => 'i.id'], + 'e' => ['j' => ['?_events `e` ON `e`.`id` = `i`.`eventId`', true], 's' => ', e.holidayId'], + 'src' => ['j' => ['?_source `src` ON `src`.`type` = 3 AND `src`.`typeId` = `i`.`id`', true], 's' => ', moreType, moreTypeId, src1, src2, src3, src4, src5, src6, src7, src8, src9, src10, src11, src12, src13, src14, src15, src16, src17, src18, src19, src20, src21, src22, src23, src24'] ); public function __construct($conditions = [], $miscData = null) @@ -469,10 +469,10 @@ class ItemList extends BaseType if ($rndEnch['allocationPct'.$i] > 0) { $amount = intVal($rndEnch['allocationPct'.$i] * $this->generateEnchSuffixFactor()); - $randEnchant .= ''.str_replace('$i', $amount, Util::localizedString($enchant, 'text')).'
'; + $randEnchant .= ''.str_replace('$i', $amount, Util::localizedString($enchant, 'name')).'
'; } else - $randEnchant .= ''.Util::localizedString($enchant, 'text').'
'; + $randEnchant .= ''.Util::localizedString($enchant, 'name').'
'; } } else @@ -638,7 +638,7 @@ class ItemList extends BaseType if ($geId = $this->curTpl['gemEnchantmentId']) { $gemEnch = DB::Aowow()->selectRow('SELECT * FROM ?_itemenchantment WHERE id = ?d', $geId); - $x .= ''.Util::localizedString($gemEnch, 'text').'
'; + $x .= ''.Util::localizedString($gemEnch, 'name').'
'; // activation conditions for meta gems if ($gemEnch['conditionId']) @@ -697,7 +697,7 @@ class ItemList extends BaseType if (isset($enhance['e'])) { if ($enchText = DB::Aowow()->selectRow('SELECT * FROM ?_itemenchantment WHERE Id = ?', $enhance['e'])) - $x .= ''.Util::localizedString($enchText, 'text').'
'; + $x .= ''.Util::localizedString($enchText, 'name').'
'; else { unset($enhance['e']); @@ -749,7 +749,7 @@ class ItemList extends BaseType $col = $pop ? 1 : 0; $hasMatch &= $pop ? (($gems[$pop]['colorMask'] & (1 << $colorId)) ? 1 : 0) : 0; $icon = $pop ? sprintf(Util::$bgImagePath['tiny'], STATIC_URL, strtolower($gems[$pop]['iconString'])) : null; - $text = $pop ? Util::localizedString($gems[$pop], 'text') : Lang::item('socket', $colorId); + $text = $pop ? Util::localizedString($gems[$pop], 'name') : Lang::item('socket', $colorId); if ($interactive) $x .= ''.$text.'
'; @@ -763,7 +763,7 @@ class ItemList extends BaseType $pop = array_pop($enhance['g']); $col = $pop ? 1 : 0; $icon = $pop ? sprintf(Util::$bgImagePath['tiny'], STATIC_URL, strtolower($gems[$pop]['iconString'])) : null; - $text = $pop ? Util::localizedString($gems[$pop], 'text') : Lang::item('socket', -1); + $text = $pop ? Util::localizedString($gems[$pop], 'name') : Lang::item('socket', -1); if ($interactive) $x .= ''.$text.'
'; @@ -773,10 +773,10 @@ class ItemList extends BaseType else // prismatic socket placeholder $x .= ''; - if ($this->curTpl['socketBonus']) + if ($_ = $this->curTpl['socketBonus']) { - $sbonus = DB::Aowow()->selectRow('SELECT * FROM ?_itemenchantment WHERE Id = ?d', $this->curTpl['socketBonus']); - $x .= ''.Lang::item('socketBonus').Lang::main('colon').Util::localizedString($sbonus, 'text').'
'; + $sbonus = DB::Aowow()->selectRow('SELECT * FROM ?_itemenchantment WHERE Id = ?d', $_); + $x .= ''.Lang::item('socketBonus').Lang::main('colon').''.Util::localizedString($sbonus, 'name').'
'; } // durability @@ -1182,17 +1182,20 @@ class ItemList extends BaseType if ($enchantments) { - $parsed = Util::parseItemEnchantment(array_keys($enchantments)); + $eStats = DB::Aowow()->select('SELECT *, typeId AS ARRAY_KEY FROM ?_item_stats WHERE `type` = ?d AND typeId IN (?a)', TYPE_ENCHANTMENT, array_keys($enchantments)); // and merge enchantments back - foreach ($parsed as $eId => $stats) + foreach ($enchantments as $eId => $items) { - foreach ($enchantments[$eId] as $item) + if (empty($eStats[$eId])) + continue; + + foreach ($items as $item) { if ($item > 0) // apply socketBonus - $this->json[$item]['socketbonusstat'] = $stats; + $this->json[$item]['socketbonusstat'] = array_filter($eStats[$eId]); else /* if ($item < 0) */ // apply gemEnchantment - Util::arraySumByKey($this->json[-$item][$mod], $stats); + Util::arraySumByKey($this->json[-$item][$mod], array_filter($eStats[$eId])); } } } @@ -1437,11 +1440,12 @@ class ItemList extends BaseType $enchIds[] = $enchId; } - foreach (Util::parseItemEnchantment($enchIds, false, $misc) as $eId => $stats) + $enchants = new EnchantmentList(array(['id', $enchIds], CFG_SQL_LIMIT_NONE)); + foreach ($enchants->iterate() as $eId => $_) { $this->rndEnchIds[$eId] = array( - 'text' => $misc[$eId]['name'], - 'stats' => $stats + 'text' => $enchants->getField('name', true), + 'stats' => $enchants->getStatGain() ); } @@ -1456,19 +1460,19 @@ class ItemList extends BaseType $qty = intVal($data['allocationPct'.$i] * $this->generateEnchSuffixFactor()); $stats = array_fill_keys(array_keys($this->rndEnchIds[$enchId]['stats']), $qty); - $jsonText[] = str_replace('$i', $qty, $this->rndEnchIds[$enchId]['text']); + $jsonText[$enchId] = str_replace('$i', $qty, $this->rndEnchIds[$enchId]['text']); Util::arraySumByKey($jsonEquip, $stats); } else // RandomProperty: static Enchantment; enchId > 0 { - $jsonText[] = $this->rndEnchIds[$enchId]['text']; + $jsonText[$enchId] = $this->rndEnchIds[$enchId]['text']; Util::arraySumByKey($jsonEquip, $this->rndEnchIds[$enchId]['stats']); } } $this->subItems[$mstItem][$subId] = array( 'name' => Util::localizedString($data, 'name'), - 'enchantment' => implode(', ', $jsonText), + 'enchantment' => $jsonText, 'jsonequip' => $jsonEquip, 'chance' => $data['chance'] // hmm, only needed for item detail page... ); diff --git a/includes/types/spell.class.php b/includes/types/spell.class.php index 665b2c45..a172c597 100644 --- a/includes/types/spell.class.php +++ b/includes/types/spell.class.php @@ -156,8 +156,16 @@ class SpellList extends BaseType // Enchant Item Permanent (53) / Temporary (54) if (in_array($this->curTpl['effect'.$i.'Id'], [53, 54])) { - if ($mv && ($_ = Util::parseItemEnchantment($mv, true))) - Util::arraySumByKey($stats, $_[$mv]); + if ($mv && ($json = DB::Aowow()->selectRow('SELECT * FROM ?_item_stats WHERE `type` = ?d AND `typeId` = ?d', TYPE_ENCHANTMENT, $mv))) + { + $mods = []; + foreach ($json as $str => $val) + if ($val && ($idx = array_search($str, Util::$itemMods))) + $mods[$idx] = $val; + + if ($mods) + Util::arraySumByKey($stats, $mods); + } continue; } @@ -165,7 +173,6 @@ class SpellList extends BaseType switch ($au) { case 29: // ModStat MiscVal:type - { if ($mv < 0) // all stats { for ($j = 0; $j < 5; $j++) @@ -175,16 +182,12 @@ class SpellList extends BaseType Util::arraySumByKey($stats, [(ITEM_MOD_AGILITY + $mv) => $pts]); break; - } case 34: // Increase Health case 230: case 250: - { Util::arraySumByKey($stats, [ITEM_MOD_HEALTH => $pts]); break; - } case 13: // damage splpwr + physical (dmg & any) - { // + weapon damage if ($mv == (1 << SPELL_SCHOOL_NORMAL)) { @@ -226,14 +229,10 @@ class SpellList extends BaseType } break; - } case 135: // healing splpwr (healing & any) .. not as a mask.. - { Util::arraySumByKey($stats, [ITEM_MOD_SPELL_HEALING_DONE => $pts]); break; - } case 35: // ModPower - MiscVal:type see defined Powers only energy/mana in use - { if ($mv == POWER_HEALTH) Util::arraySumByKey($stats, [ITEM_MOD_HEALTH => $pts]); if ($mv == POWER_ENERGY) @@ -244,7 +243,6 @@ class SpellList extends BaseType Util::arraySumByKey($stats, [ITEM_MOD_RUNIC_POWER => $pts]); break; - } case 189: // CombatRating MiscVal:ratingMask case 220: if ($mod = Util::itemModByRatingMask($mv)) @@ -310,6 +308,10 @@ class SpellList extends BaseType case 240: // ModExpertise Util::arraySumByKey($stats, [ITEM_MOD_EXPERTISE_RATING => $pts]); break; + case 123: // Mod Target Resistance + if ($mv == 0x7C && $pts < 0) + Util::arraySumByKey($stats, [ITEM_MOD_SPELL_PENETRATION => -$pts]); + break; } } @@ -1411,7 +1413,7 @@ class SpellList extends BaseType if (isset($var[1]) && $var[0] != $var[1] && !isset($var[4])) { - $_ = is_numeric($var[0]) ? abs($var[0]) : $var[0]; + $_ = is_numeric($var[1]) ? abs($var[1]) : $var[1]; $resolved .= Lang::game('valueDelim'); $resolved .= isset($var[3]) ? sprintf($var[3], $_) : $_; } diff --git a/includes/utilities.php b/includes/utilities.php index cca4908d..79aaee37 100644 --- a/includes/utilities.php +++ b/includes/utilities.php @@ -40,15 +40,16 @@ class Util null, 'CreatureList', 'GameObjectList', 'ItemList', 'ItemsetList', 'QuestList', 'SpellList', 'ZoneList', 'FactionList', 'PetList', 'AchievementList', 'TitleList', 'WorldEventList', 'CharClassList', 'CharRaceList', 'SkillList', null, 'CurrencyList', - TYPE_EMOTE => 'EmoteList' + TYPE_EMOTE => 'EmoteList', + TYPE_ENCHANTMENT => 'EnchantmentList' ); public static $typeStrings = array( // zero-indexed null, 'npc', 'object', 'item', 'itemset', 'quest', 'spell', 'zone', 'faction', 'pet', 'achievement', 'title', 'event', 'class', 'race', 'skill', null, 'currency', - TYPE_USER => 'user', - TYPE_EMOTE => 'emote' - + TYPE_USER => 'user', + TYPE_EMOTE => 'emote', + TYPE_ENCHANTMENT => 'enchantment' ); public static $combatRatingToItemMod = array( // zero-indexed idx:CR; val:Mod @@ -1096,131 +1097,6 @@ class Util } } - // EnchantmentTypes - // 0 => TYPE_NONE dnd stuff; (ignore) - // 1 => TYPE_COMBAT_SPELL proc spell from ObjectX (amountX == procChance?; ignore) - // 2 => TYPE_DAMAGE +AmountX damage - // 3 => TYPE_EQUIP_SPELL Spells from ObjectX (amountX == procChance?) - // 4 => TYPE_RESISTANCE +AmountX resistance for ObjectX School - // 5 => TYPE_STAT +AmountX for Statistic by type of ObjectX - // 6 => TYPE_TOTEM Rockbiter AmountX as Damage (ignore) - // 7 => TYPE_USE_SPELL Engineering gadgets - // 8 => TYPE_PRISMATIC_SOCKET Extra Sockets AmountX as socketCount (ignore) - public static function parseItemEnchantment($ench, $raw = false, &$misc = null) - { - if (!$ench) - return []; - - if (is_numeric($ench)) - $ench = [$ench]; - - if (!is_array($ench)) - return []; - - $enchants = DB::Aowow()->select('SELECT *, Id AS ARRAY_KEY FROM ?_itemenchantment WHERE id IN (?a)', $ench); - if (!$enchants) - return []; - - $result = []; - foreach ($enchants as $eId => $e) - { - $misc[$eId] = array( - 'name' => self::localizedString($e, 'text'), - 'text' => array( - 'text_loc0' => $e['text_loc0'], - 'text_loc2' => $e['text_loc2'], - 'text_loc3' => $e['text_loc3'], - 'text_loc6' => $e['text_loc6'], - 'text_loc8' => $e['text_loc8'] - ) - ); - - if ($e['skillLine'] > 0) - $misc[$eId]['reqskill'] = $e['skillLine']; - - if ($e['skillLevel'] > 0) - $misc[$eId]['reqskillrank'] = $e['skillLevel']; - - if ($e['requiredLevel'] > 0) - $misc[$eId]['reqlevel'] = $e['requiredLevel']; - - // parse stats - $jsonStats = []; - for ($h = 1; $h <= 3; $h++) - { - $obj = (int)$e['object'.$h]; - $val = (int)$e['amount'.$h]; - - switch ($e['type'.$h]) - { - case 2: - $obj = ITEM_MOD_WEAPON_DMG; - break; - case 3: - case 7: - $spl = new SpellList(array(['s.id', $obj])); - if (!$spl->error) - Util::arraySumByKey($jsonStats, $spl->getStatGain()[$obj]); - - $obj = null; - break; - case 4: - switch ($obj) - { - case 0: // Physical - $obj = ITEM_MOD_ARMOR; - break; - case 1: // Holy - $obj = ITEM_MOD_HOLY_RESISTANCE; - break; - case 2: // Fire - $obj = ITEM_MOD_FIRE_RESISTANCE; - break; - case 3: // Nature - $obj = ITEM_MOD_NATURE_RESISTANCE; - break; - case 4: // Frost - $obj = ITEM_MOD_FROST_RESISTANCE; - break; - case 5: // Shadow - $obj = ITEM_MOD_SHADOW_RESISTANCE; - break; - case 6: // Arcane - $obj = ITEM_MOD_ARCANE_RESISTANCE; - break; - default: - $obj = null; - } - break; - case 5: - break; - default: // skip assignment below - $obj = null; - } - - if ($obj) - { - if (!isset($jsonStats[$obj])) - $jsonStats[$obj] = 0; - - $jsonStats[$obj] += $val; - } - } - - if ($raw) - $result[$eId] = $jsonStats; - else - { - $result[$eId] = []; - foreach ($jsonStats as $k => $v) // check if we use these mods - if ($str = Util::$itemMods[$k]) - $result[$eId][$str] = $v; - } - } - - return $result; - } - // default ucFirst doesn't convert UTF-8 chars public static function ucFirst($str) { diff --git a/index.php b/index.php index 725b8d3c..b42e35bf 100644 --- a/index.php +++ b/index.php @@ -31,6 +31,8 @@ switch ($pageCall) case 'compare': // tool: item comparison case 'emote': case 'emotes': + case 'enchantment': + case 'enchantments': case 'event': case 'events': case 'faction': diff --git a/localization/lang.class.php b/localization/lang.class.php index beafdb37..a5f5254a 100644 --- a/localization/lang.class.php +++ b/localization/lang.class.php @@ -30,6 +30,7 @@ class Lang private static $zone; private static $emote; + private static $enchantment; public static function load($loc) { diff --git a/localization/locale_dede.php b/localization/locale_dede.php index 1fc14ec3..12dbde58 100644 --- a/localization/locale_dede.php +++ b/localization/locale_dede.php @@ -175,6 +175,8 @@ $lang = array( 'duration' => "Dauer", 'emote' => "Emote", 'emotes' => "Emotes", + 'enchantment' => "Verzauberung", + 'enchantments' => "Verzauberungen", 'object' => "Objekt", 'objects' => "Objekte", 'glyphType' => "Glyphenart", @@ -389,6 +391,14 @@ $lang = array( 'aliases' => "Aliasse", 'noText' => "Dieses Emote besitzt keinen Text.", ), + 'enchantment' => array( + 'details' => "Details", + 'activation' => "Aktivierung", + 'types' => array( + 1 => "Zauber (Auslösung)", 3 => "Zauber (Anlegen)", 7 => "Zauber (Benutzen)", 8 => "Prismatischer Sockel", + 5 => "Statistik", 2 => "Waffenschaden", 6 => "DPS", 4 => "Verteidigung" + ) + ), 'gameObject' => array( 'notFound' => "Dieses Objekt existiert nicht.", 'cat' => [0 => "Anderes", 9 => "Bücher", 3 => "Behälter", -5 => "Truhen", 25 => "Fischschwärme", -3 => "Kräuter", -4 => "Erzadern", -2 => "Quest", -6 => "Werkzeuge"], diff --git a/localization/locale_enus.php b/localization/locale_enus.php index 30aa4e3e..f52e83ff 100644 --- a/localization/locale_enus.php +++ b/localization/locale_enus.php @@ -168,8 +168,10 @@ $lang = array( 'difficulty' => "Difficulty", 'dispelType' => "Dispel type", 'duration' => "Duration", - 'emote' => "Emote", + 'emote' => "emote", 'emotes' => "Emotes", + 'enchantment' => "enchantment", + 'enchantments' => "Enchantments", 'object' => "object", 'objects' => "Objects", 'glyphType' => "Glyph type", @@ -384,6 +386,14 @@ $lang = array( 'aliases' => "Aliases", 'noText' => "This Emote has no text.", ), + 'enchantment' => array( + 'details' => "Details", + 'activation' => "Activation", + 'types' => array( + 1 => "Proc Spell", 3 => "Equip Spell", 7 => "Use Spell", 8 => "Prismatic Socket", + 5 => "Statistics", 2 => "Weapon Damage", 6 => "DPS", 4 => "Defense" + ) + ), 'gameObject' => array( 'notFound' => "This object doesn't exist.", 'cat' => [0 => "Other", 9 => "Books", 3 => "Containers", -5 => "Chests", 25 => "Fishing Pools", -3 => "Herbs", -4 => "Mineral Veins", -2 => "Quest", -6 => "Tools"], diff --git a/localization/locale_eses.php b/localization/locale_eses.php index a54e5f11..cc4ce2b3 100644 --- a/localization/locale_eses.php +++ b/localization/locale_eses.php @@ -173,8 +173,10 @@ $lang = array( 'difficulty' => "Dificultad", 'dispelType' => "Tipo de disipación", 'duration' => "Duración", - 'emote' => "Emoción", + 'emote' => "emoción", 'emotes' => "Emociones", + 'enchantment' => "encantamiento", + 'enchantments' => "Encantamientos", 'object' => "entidad", 'objects' => "Entidades", 'glyphType' => "Tipo de glifo", @@ -390,6 +392,14 @@ $lang = array( 'aliases' => "[Aliases]", 'noText' => "[This Emote has no text.]", ), + 'enchantment' => array( + 'details' => "Detalles", + 'activation' => "Activación", + 'types' => array( + 1 => "[Proc Spell]", 3 => "[Equip Spell]", 7 => "[Use Spell]", 8 => "Ranura prismática", + 5 => "Atributos", 2 => "Daño de arma", 6 => "DPS", 4 => "Defensa" + ) + ), 'gameObject' => array( 'notFound' => "Este entidad no existe.", 'cat' => [0 => "Otros", 9 => "Libros", 3 => "Contenedores", -5 => "Cofres", 25 => "Bancos de peces", -3 => "Hierbas", -4 => "Venas de minerales", -2 => "Misiones", -6 => "Herramientas"], diff --git a/localization/locale_frfr.php b/localization/locale_frfr.php index b9594603..406685f8 100644 --- a/localization/locale_frfr.php +++ b/localization/locale_frfr.php @@ -173,8 +173,10 @@ $lang = array( 'difficulty' => "Difficulté", 'dispelType' => "Type de dissipation", 'duration' => "Durée", - 'emote' => "Emote", + 'emote' => "emote", 'emotes' => "Emotes", + 'enchantment' => "enchantement", + 'enchantments' => "Enchantements", 'object' => "entité", 'objects' => "Entités", 'glyphType' => "Type de glyphe", @@ -389,6 +391,14 @@ $lang = array( 'aliases' => "[Aliases]", 'noText' => "[This Emote has no text.]", ), + 'enchantment' => array( + 'details' => "En détail", + 'activation' => "Activation", + 'types' => array( + 1 => "[Proc Spell]", 3 => "[Equip Spell]", 7 => "[Use Spell]", 8 => "Châsse prismatique", + 5 => "Statistiques", 2 => "Dégâts d'arme", 6 => "DPS", 4 => "Défense" + ) + ), 'gameObject' => array( 'notFound' => "Cette entité n'existe pas.", 'cat' => [0 => "Autre", 9 => "Livres", 3 => "Conteneurs", -5 => "Coffres", 25 => "Bancs de poissons", -3 => "Herbes", -4 => "Filons de minerai", -2 => "Quêtes", -6 => "Outils"], diff --git a/localization/locale_ruru.php b/localization/locale_ruru.php index 7dab6a89..5441bbd8 100644 --- a/localization/locale_ruru.php +++ b/localization/locale_ruru.php @@ -175,6 +175,8 @@ $lang = array( 'duration' => "Длительность", 'emote' => "Эмоция", 'emotes' => "Эмоции", + 'enchantment' => "улучшение", + 'enchantments' => "Улучшения", 'object' => "объект", 'objects' => "Объекты", 'glyphType' => "Тип символа", @@ -389,6 +391,14 @@ $lang = array( 'aliases' => "[Aliases]", 'noText' => "[This Emote has no text.]", ), + 'enchantment' => array( + 'details' => "Подробности", + 'activation' => "Активации", + 'types' => array( + 1 => "[Proc Spell]", 3 => "[Equip Spell]", 7 => "[Use Spell]", 8 => "Бесцветное гнездо", + 5 => "Характеристики", 2 => "Урон оружия", 6 => "УВС", 4 => "Защита" + ) + ), 'gameObject' => array( 'notFound' => "Такой объект не существует.", 'cat' => [0 => "Другое", 9 => "Книги", 3 => "Контейнеры", -5 => "Сундуки", 25 => "Рыболовные лунки",-3 => "Травы", -4 => "Полезные ископаемые", -2 => "Задания", -6 => "Инструменты"], diff --git a/pages/emote.php b/pages/emote.php index f66889b9..9d78a2f0 100644 --- a/pages/emote.php +++ b/pages/emote.php @@ -10,7 +10,7 @@ class EmotePage extends GenericPage { use DetailPage; - protected $type = TYPE_PET; + protected $type = TYPE_EMOTE; protected $typeId = 0; protected $tpl = 'detail-page-generic'; protected $path = [0, 100]; @@ -80,7 +80,7 @@ class EmotePage extends GenericPage $text .= '[pad][b]'.$h.'[/b][ul][li][span class=s4]'.preg_replace('/%\d?\$?s/', '<'.Util::ucFirst(Lang::main('name')).'>', $t).'[/span][/li][/ul]'; $this->extraText = $text; - $this->infobox = '[ul][li]'.implode('[/li][li]', $infobox).'[/li][/ul]'; + $this->infobox = $infobox ? '[ul][li]'.implode('[/li][li]', $infobox).'[/li][/ul]' : null; /**************/ /* Extra Tabs */ diff --git a/pages/enchantment.php b/pages/enchantment.php new file mode 100644 index 00000000..2e374ffb --- /dev/null +++ b/pages/enchantment.php @@ -0,0 +1,311 @@ +typeId = intVal($id); + + $this->subject = new EnchantmentList(array(['id', $this->typeId])); + if ($this->subject->error) + $this->notFound(Util::ucFirst(Lang::game('enchantment')), Lang::enchantment('notFound')); + + $this->extendGlobalData($this->subject->getJSGlobals()); + + $this->name = Util::ucFirst($this->subject->getField('name', true)); + } + + private function getDistinctType() + { + $type = 0; + for ($i = 1; $i < 4; $i++) + { + if ($_ = $this->subject->getField('type'.$i)) + { + if ($type) // already set + return 0; + else + $type = $_; + } + } + + return $type; + } + + 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]['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! + 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 + case 3: $foo = '2:4:5'; break; // yellow + case 4: $foo = '1:3:4'; break; // blue + } + + return $foo; + }; + + $bLink = $gemCnd['color'.$i] ? ''.Lang::item('gemColors', $gemCnd['color'.$i] - 1).'' : ''; + $cLink = $gemCnd['cmpColor'.$i] ? ''.Lang::item('gemColors', $gemCnd['cmpColor'.$i] - 1).'' : ''; + + switch ($gemCnd['comparator'.$i]) + { + case 2: // requires less than ( || ) gems + case 5: // requires at least than ( || ) gems + $sp = (int)$gemCnd['value'.$i] > 1; + $x .= ''.Lang::achievement('reqNumCrt').' '.sprintf(Lang::item('gemConditions', $gemCnd['comparator'.$i], $sp), $gemCnd['value'.$i], $bLink).'
'; + break; + case 3: // requires more than ( || ) gems + $link = ''.Lang::item('gemColors', $gemCnd['cmpColor'.$i] - 1).''; + $x .= ''.Lang::achievement('reqNumCrt').' '.sprintf(Lang::item('gemConditions', 3), $bLink, $cLink).'
'; + break; + } + } + } + + $this->activateCondition = $x; + } + + /**************/ + /* Extra Tabs */ + /**************/ + + // used by gem + $gemList = new ItemList(array(['gemEnchantmentId', $this->typeId])); + if (!$gemList->error) + { + $this->lvTabs[] = array( + 'file' => 'item', + 'data' => $gemList->getListviewData(), + 'params' => array( + 'name' => '$LANG.tab_usedby + \' \' + LANG.gems', + 'id' => 'used-by-gems', + ) + ); + + $this->extendGlobalData($gemList->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', // [use, useUndelayed] + ['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[] = array( + 'file' => 'item', + 'data' => $ubItems->getListviewData(), + 'params' => [] + ); + + $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[] = array( + 'file' => 'spell', + 'data' => $spellData, + 'params' => [] + ); + } + + // 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[] = array( + 'file' => 'item', + 'data' => $data, + 'params' => array( + 'id' => 'used-by-rand', + 'name' => Lang::item('_rndEnchants'), + 'extraCols' => '$[Listview.extraCols.percent]' + ) + ); + + $this->extendGlobalData($randItems->getJSGlobals(GLOBALINFO_SELF)); + } + } + } + } + + protected function generateTitle() + { + array_unshift($this->title, $this->name, Util::ucFirst(Lang::game('enchantment'))); + } + + protected function generatePath() + { + if ($_ = $this->getDistinctType()) + $this->path[] = $_; + } +} + +?> diff --git a/pages/enchantments.php b/pages/enchantments.php new file mode 100644 index 00000000..961c5cc3 --- /dev/null +++ b/pages/enchantments.php @@ -0,0 +1,106 @@ +filterObj = new EnchantmentListFilter(); + $this->getCategoryFromUrl($pageParam);; + + parent::__construct($pageCall, $pageParam); + + $this->name = Util::ucFirst(Lang::game('enchantments')); + $this->subCat = $pageParam !== null ? '='.$pageParam : ''; + } + + protected function generateContent() + { + $tab = array( + 'file' => 'enchantment', + 'data' => [], + 'params' => [] + ); + + $conditions = []; + + if (!User::isInGroup(U_GROUP_EMPLOYEE)) + $conditions[] = [['cuFlags', CUSTOM_EXCLUDE_FOR_LISTVIEW, '&'], 0]; + + if ($_ = $this->filterObj->getConditions()) + $conditions[] = $_; + + $ench = new EnchantmentList($conditions); + + $tab['data'] = $ench->getListviewData(); + $this->extendGlobalData($ench->getJSGlobals()); + + // recreate form selection + $this->filter = array_merge($this->filterObj->getForm('form'), $this->filter); + $this->filter['query'] = isset($_GET['filter']) ? $_GET['filter'] : NULL; + $this->filter['fi'] = $this->filterObj->getForm(); + + $xCols = $this->filterObj->getForm('extraCols', true); + foreach (Util::$itemFilter as $fiId => $str) + if (array_column($tab['data'], $str)) + $xCols[] = $fiId; + + if (array_column($tab['data'], 'dmg')) + $xCols[] = 34; + + if ($xCols) + $this->filter['fi']['extraCols'] = "fi_extraCols = ".Util::toJSON(array_values(array_unique($xCols))).";"; + + if (!empty($this->filter['fi']['extraCols'])) + $tab['params']['extraCols'] = '$fi_getExtraCols(fi_extraCols, 0, 0)'; + + if ($ench->getMatches() > CFG_SQL_LIMIT_DEFAULT) + { + $tab['params']['note'] = sprintf(Util::$tryFilteringString, 'LANG.lvnote_enchantmentsfound', $ench->getMatches(), CFG_SQL_LIMIT_DEFAULT); + $tab['params']['_truncated'] = 1; + } + + if (array_filter(array_column($tab['data'], 'spells'))) + $tab['params']['visibleCols'] = '$[\'trigger\']'; + + if (!$ench->hasSetFields(['skillLine'])) + $tab['params']['hiddenCols'] = '$[\'skill\']'; + + if ($this->filterObj->error) + $tab['params']['_errors'] = '$1'; + + $this->lvTabs[] = $tab; + } + + protected function generateTitle() + { + $form = $this->filterObj->getForm('form'); + if (!empty($form['ty']) && intVal($form['ty']) && $form['ty'] > 0 && $form['ty'] < 9) + array_unshift($this->title, Lang::enchantment('types', $form['ty'])); + + array_unshift($this->title, $this->name); + } + + protected function generatePath() + { + $form = $this->filterObj->getForm('form'); + if (isset($form['ty']) && !is_array($form['ty'])) + $this->path[] = $form['ty']; + } +} + +?> diff --git a/pages/genericPage.class.php b/pages/genericPage.class.php index add97605..8a599e1c 100644 --- a/pages/genericPage.class.php +++ b/pages/genericPage.class.php @@ -620,6 +620,8 @@ class GenericPage case TYPE_CURRENCY: $jsg[TYPE_CURRENCY] = ['g_gatheredcurrencies', [], []]; break; // well, this is awkward case TYPE_USER: $jsg[TYPE_USER] = ['g_users', [], []]; break; + case TYPE_EMOTE: $jsg[TYPE_EMOTE] = ['g_emotes', [], []]; break; + case TYPE_ENCHANTMENT: $jsg[TYPE_ENCHANTMENT] = ['g_enchantments', [], []]; break; } } @@ -658,6 +660,8 @@ class GenericPage case TYPE_CURRENCY: $obj = new CurrencyList($cnd); break; // "um, eh":, he ums and ehs. case TYPE_USER: $obj = new UserList($cnd); break; + case TYPE_EMOTE: $obj = new EmoteList($cnd); break; + case TYPE_ENCHANTMENT: $obj = new EnchantmentList($cnd); break; default: continue; } diff --git a/pages/search.php b/pages/search.php index 8f3aa2f7..d1ca8de8 100644 --- a/pages/search.php +++ b/pages/search.php @@ -52,7 +52,7 @@ class SearchPage extends GenericPage ['_searchProficiency'], ['_searchProfession'], ['_searchCompanion'], ['_searchMount'], ['_searchCreature'], ['_searchQuest'], ['_searchAchievement'], ['_searchStatistic'], ['_searchZone'], ['_searchObject'], ['_searchFaction'], ['_searchSkill'], ['_searchPet'], ['_searchCreatureAbility'], ['_searchSpell'], - ['_searchEmote'] + ['_searchEmote'], ['_searchEnchantment'] ); public function __construct($pageCall, $pageParam) @@ -1431,9 +1431,44 @@ class SearchPage extends GenericPage return $result; } - // private function _searchCharacter($cndBase) { } // 26 Characters $searchMask & 0x4000000 - // private function _searchGuild($cndBase) { } // 27 Guilds $searchMask & 0x8000000 - // private function _searchArenaTeam($cndBase) { } // 28 Arena Teams $searchMask & 0x10000000 + private function _searchEnchantment($cndBase) // 26 Enchantments $searchMask & 0x4000000 + { + $result = []; + $cnd = array_merge($cndBase, [$this->createLookup(['name_loc'.User::$localeId])]); + $enchantment = new EnchantmentList($cnd); + + if ($data = $enchantment->getListviewData()) + { + $this->extendGlobalData($enchantment->getJSGlobals()); + + $result = array( + 'type' => TYPE_ENCHANTMENT, + 'appendix' => ' (Enchantment)', + 'matches' => $enchantment->getMatches(), + 'file' => EnchantmentList::$brickFile, + 'data' => $data, + 'params' => [] + ); + + if (array_filter(array_column($result['data'], 'spells'))) + $result['params']['visibleCols'] = '$[\'trigger\']'; + + if (!$enchantment->hasSetFields(['skillLine'])) + $result['params']['hiddenCols'] = '$[\'skill\']'; + + if ($enchantment->getMatches() > $this->maxResults) + { + $result['params']['note'] = sprintf(Util::$tryNarrowingString, 'LANG.lvnote_enchantmentsfound', $enchantment->getMatches(), $this->maxResults); + $result['params']['_truncated'] = 1; + } + } + + return $result; + } + + // private function _searchCharacter($cndBase) { } // 27 Characters $searchMask & 0x8000000 + // private function _searchGuild($cndBase) { } // 28 Guilds $searchMask & 0x10000000 + // private function _searchArenaTeam($cndBase) { } // 29 Arena Teams $searchMask & 0x20000000 } ?> diff --git a/pages/spell.php b/pages/spell.php index 3c4fe5cc..ff2098e7 100644 --- a/pages/spell.php +++ b/pages/spell.php @@ -180,7 +180,7 @@ class SpellPage extends GenericPage { $this->extendGlobalData($rSkill->getJSGlobals()); - $bar = sprintf(Lang::game('requires'), '[skill='.$rSkill->id.']'); + $bar = sprintf(Lang::game('requires'), ' [skill='.$rSkill->id.']'); if ($_ = $this->subject->getField('learnedAt')) $bar .= ' ('.$_.')'; @@ -1585,7 +1585,7 @@ class SpellPage extends GenericPage } // Effect Name - $foo['name'] = User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, 'EffectId: '.$effId, Util::$spellEffectStrings[$effId]) : Util::$spellEffectStrings[$effId]; + $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'); @@ -1631,9 +1631,9 @@ class SpellPage extends GenericPage break; case 16: // QuestComplete if ($_ = QuestList::getName($effMV)) - $foo['name'] .= Lang::main('colon').'('.$_.')'; + $foo['name'] .= '('.$_.')'; else - $foo['name'] .= Lang::main('colon').Util::ucFirst(Lang::game('quest')).' #'.$effMV;; + $foo['name'] .= Util::ucFirst(Lang::game('quest')).' #'.$effMV;; break; case 28: // Summon case 90: // Kill Credit @@ -1645,7 +1645,7 @@ class SpellPage extends GenericPage $redButtons[BUTTON_VIEW3D] = ['type' => TYPE_NPC, 'displayId' => $summon['displayId']]; } - $foo['name'] .= Lang::main('colon').$_; + $foo['name'] .= $_; break; case 33: // Open Lock $_ = Lang::spell('lockType', $effMV); @@ -1658,9 +1658,10 @@ class SpellPage extends GenericPage break; case 53: // Enchant Item Perm case 54: // Enchant Item Temp + case 92: // Enchant Held Item case 156: // Enchant Item Prismatic if ($_ = DB::Aowow()->selectRow('SELECT * FROM ?_itemenchantment WHERE id = ?d', $effMV)) - $foo['name'] .= ' '.Util::localizedString($_, 'text').' ('.$effMV.')'; + $foo['name'] .= ' ('.Util::localizedString($_, 'name').')'; else $foo['name'] .= ' #'.$effMV; break; @@ -1697,15 +1698,15 @@ class SpellPage extends GenericPage $redButtons[BUTTON_VIEW3D] = ['type' => TYPE_OBJECT, 'displayId' => $summon['displayId']]; } - $foo['name'] .= Lang::main('colon').$_; + $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'] .= Lang::main('colon').'('.$n.')'; + $foo['name'] .= '('.$n.')'; else - $foo['name'] .= Lang::main('colon').Util::ucFirst(Lang::game('spell')).' #'.$effMV; + $foo['name'] .= Util::ucFirst(Lang::game('spell')).' #'.$effMV; } else $foo['name'] .= ' #'.$effMV;; @@ -1737,9 +1738,9 @@ class SpellPage extends GenericPage break; case 118: // Require Skill if ($_ = SkillList::getName($effMV)) - $foo['name'] .= Lang::main('colon').'('.$_.')'; + $foo['name'] .= '('.$_.')'; else - $foo['name'] .= Lang::main('colon').Util::ucFirst(Lang::game('skill')).' #'.$effMV;; + $foo['name'] .= Util::ucFirst(Lang::game('skill')).' #'.$effMV;; break; case 146: // Activate Rune $_ = Lang::spell('powerRunes', $effMV); @@ -1768,7 +1769,7 @@ class SpellPage extends GenericPage { if ($effAura > 0 && isset(Util::$spellAuraStrings[$effAura])) { - $foo['name'] .= User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, 'AuraId: '.$effAura, Lang::main('colon').Util::$spellAuraStrings[$effAura]) : Lang::main('colon').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) @@ -1888,6 +1889,7 @@ class SpellPage extends GenericPage case 22: // Mod Resistance case 39: // School Immunity case 40: // Damage Immunity + case 50: // Mod Critical Healing Amount case 57: // Mod Spell Crit Chance case 69: // School Absorb case 71: // Mod Spell Crit Chance School @@ -1949,6 +1951,9 @@ class SpellPage extends GenericPage break; case 168: // Mod Damage Done Versus case 59: // Mod Damage Done Versus Creature + case 102: // Mod Melee Attack Power Versus + case 131: // Mod Ranged Attack Power Versus + case 180: // Mod Spell Damage Versus $_ = []; foreach (Lang::game('ct') as $k => $str) if ($effMV & (1 << $k - 1)) diff --git a/setup/db_structure.sql b/setup/db_structure.sql index baab5ded..cc74e85f 100644 --- a/setup/db_structure.sql +++ b/setup/db_structure.sql @@ -262,8 +262,8 @@ DROP TABLE IF EXISTS `aowow_articles`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `aowow_articles` ( - `type` tinyint(4) NOT NULL, - `typeId` int(11) NOT NULL, + `type` smallint(5) NOT NULL, + `typeId` mediumint(9) NOT NULL, `locale` tinyint(4) NOT NULL, `article` text COMMENT 'Markdown formated', `quickInfo` text COMMENT 'Markdown formated', @@ -330,8 +330,8 @@ DROP TABLE IF EXISTS `aowow_comments`; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `aowow_comments` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Comment ID', - `type` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'Type of Page', - `typeId` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'ID Of Page', + `type` smallint(5) unsigned NOT NULL COMMENT 'Type of Page', + `typeId` mediumint(9) NOT NULL COMMENT 'ID Of Page', `userId` int(10) unsigned NOT NULL COMMENT 'User ID', `roles` smallint(5) unsigned NOT NULL, `body` text NOT NULL COMMENT 'Comment text', @@ -718,7 +718,8 @@ DROP TABLE IF EXISTS `aowow_item_stats`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `aowow_item_stats` ( - `id` mediumint(8) unsigned NOT NULL, + `type` smallint(5) unsigned NOT NULL, + `typeId` mediumint(9) unsigned NOT NULL, `nsockets` tinyint(3) unsigned NOT NULL, `dmgmin1` smallint(5) unsigned NOT NULL, `dmgmax1` smallint(5) unsigned NOT NULL, @@ -798,8 +799,7 @@ CREATE TABLE `aowow_item_stats` ( `shasplpwr` smallint(6) NOT NULL, `natsplpwr` smallint(6) NOT NULL, `arcsplpwr` smallint(6) NOT NULL, - PRIMARY KEY (`id`), - KEY `item` (`id`) + PRIMARY KEY (`typeId`, `type`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; /*!40101 SET character_set_client = @saved_cs_client */; @@ -812,6 +812,10 @@ DROP TABLE IF EXISTS `aowow_itemenchantment`; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `aowow_itemenchantment` ( `id` smallint(5) unsigned NOT NULL, + `charges` tinyint(4) unsigned NOT NULL, + `cuFlags` int(10) unsigned NOT NULL, + `procChance` tinyint(3) unsigned NOT NULL, + `ppmRate` float NOT NULL, `type1` tinyint(4) unsigned NOT NULL, `type2` tinyint(4) unsigned NOT NULL, `type3` tinyint(4) unsigned NOT NULL, @@ -821,12 +825,11 @@ CREATE TABLE `aowow_itemenchantment` ( `object1` mediumint(9) unsigned NOT NULL, `object2` mediumint(9) unsigned NOT NULL, `object3` smallint(6) unsigned NOT NULL, - `text_loc0` varchar(65) NOT NULL, - `text_loc2` varchar(91) NOT NULL, - `text_loc3` varchar(84) NOT NULL, - `text_loc6` varchar(89) NOT NULL, - `text_loc8` varchar(96) NOT NULL, - `gemReference` mediumint(8) unsigned NOT NULL, + `name_loc0` varchar(65) NOT NULL, + `name_loc2` varchar(91) NOT NULL, + `name_loc3` varchar(84) NOT NULL, + `name_loc6` varchar(89) NOT NULL, + `name_loc8` varchar(96) NOT NULL, `conditionId` tinyint(3) unsigned NOT NULL, `skillLine` smallint(5) unsigned NOT NULL, `skillLevel` smallint(5) unsigned NOT NULL, @@ -1688,7 +1691,7 @@ DROP TABLE IF EXISTS `aowow_screenshots`; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `aowow_screenshots` ( `id` int(16) unsigned NOT NULL AUTO_INCREMENT, - `type` tinyint(4) unsigned NOT NULL, + `type` smallint(5) unsigned NOT NULL, `typeId` mediumint(9) NOT NULL, `uploader` int(16) unsigned NOT NULL, `date` int(32) unsigned NOT NULL, @@ -2214,8 +2217,8 @@ DROP TABLE IF EXISTS `aowow_videos`; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `aowow_videos` ( `id` int(16) NOT NULL, - `type` int(8) NOT NULL, - `typeId` int(16) NOT NULL, + `type` smallint(5) unsigned NOT NULL, + `typeId` mediumint(9) NOT NULL, `uploader` int(16) NOT NULL, `date` int(32) NOT NULL, `videoId` varchar(12) NOT NULL, diff --git a/setup/tools/dbc.class.php b/setup/tools/dbc.class.php index a400f380..365f55fe 100644 --- a/setup/tools/dbc.class.php +++ b/setup/tools/dbc.class.php @@ -104,7 +104,7 @@ class DBC 'spellduration' => 'nixx', 'spellfocusobject' => 'nsxssxxsxsxxxxxxxx', 'spellicon' => 'ns', - 'spellitemenchantment' => 'nxiiiiiixxxiiisxssxxsxsxxxxxxxxxxiiiii', + 'spellitemenchantment' => 'niiiiiiixxxiiisxssxxsxsxxxxxxxxxxxiiii', 'spellitemenchantmentcondition' => 'nbbbbbxxxxxbbbbbbbbbbiiiiiXXXXX', 'spellradius' => 'nfxf', 'spellrange' => 'nffffisxssxxsxsxxxxxxxxxxxxxxxxxxxxxxxxx', @@ -186,7 +186,7 @@ class DBC 'spelldifficulty' => 'normal10,normal25,heroic10,heroic25', 'spellfocusobject' => 'Id,name_loc0,name_loc2,name_loc3,name_loc6,name_loc8', 'spellicon' => 'Id,iconPath', - 'spellitemenchantment' => 'Id,type1,type2,type3,amount1,amount2,amount3,object1,object2,object3,text_loc0,text_loc2,text_loc3,text_loc6,text_loc8,gemReference,conditionId,skillLine,skillLevel,requiredLevel', + 'spellitemenchantment' => 'Id,charges,type1,type2,type3,amount1,amount2,amount3,object1,object2,object3,name_loc0,name_loc2,name_loc3,name_loc6,name_loc8,conditionId,skillLine,skillLevel,requiredLevel', 'spellitemenchantmentcondition' => 'Id,color1,color2,color3,color4,color5,comparator1,comparator2,comparator3,comparator4,comparator5,cmpColor1,cmpColor2,cmpColor3,cmpColor4,cmpColor5,value1,value2,value3,value4,value5', 'spellradius' => 'Id,radiusMin,radiusMax', 'spellrange' => 'Id,rangeMinHostile,rangeMinFriend,rangeMaxHostile,rangeMaxFriend,rangeType,name_loc0,name_loc2,name_loc3,name_loc6,name_loc8', diff --git a/setup/tools/fileGen.class.php b/setup/tools/fileGen.class.php index d04c47b1..103870a4 100644 --- a/setup/tools/fileGen.class.php +++ b/setup/tools/fileGen.class.php @@ -40,9 +40,9 @@ class FileGen 'pets' => [['spawns', 'creature'], null], 'talentIcons' => [null, null], 'glyphs' => [['items', 'spell'], null], - 'itemsets' => [['itemset'], null], - 'enchants' => [['items'], null], - 'gems' => [['items'], null], + 'itemsets' => [['itemset', 'spell'], null], + 'enchants' => [['items', 'spell', 'itemenchantment'], null], + 'gems' => [['items', 'spell', 'itemenchantment'], null], 'profiler' => [['quests', 'quests_startend', 'spell', 'currencies', 'achievement', 'titles'], null] ); @@ -82,6 +82,8 @@ class FileGen self::$subScripts = array_merge(array_keys(self::$tplFiles), array_keys(self::$datasets)); if ($doScripts) self::$subScripts = array_intersect($doScripts, self::$subScripts); + else if ($doScripts === null) + self::$subScripts = []; if (!CLISetup::$localeIds /* todo: && this script has localized text */) { @@ -127,7 +129,7 @@ class FileGen $doScripts[] = $name; } - $doScripts = array_unique($doScripts); + $doScripts = $doScripts ? array_unique($doScripts) : null; } else if (!empty($_['build'])) $doScripts = explode(',', $_['build']); diff --git a/setup/tools/filegen/enchants.func.php b/setup/tools/filegen/enchants.func.php index 040b5e8f..c1e271a5 100644 --- a/setup/tools/filegen/enchants.func.php +++ b/setup/tools/filegen/enchants.func.php @@ -11,8 +11,6 @@ if (!CLI) // this script requires the following dbc-files to be parsed and available // Spells, SkillLineAbility, SpellItemEnchantment - // todo (high): restructure to work more efficiently (outer loop: spells, inner loop: locales) - /* Examples 15: { name:'Leichtes Rstungsset', @@ -72,8 +70,13 @@ if (!CLI) foreach ($enchantSpells->iterate() as $__) $enchIds[] = $enchantSpells->getField('effect1MiscValue'); - $enchMisc = []; - $enchJSON = Util::parseItemEnchantment($enchIds, false, $enchMisc); + $enchantments = new EnchantmentList(array(['id', $enchIds], CFG_SQL_LIMIT_NONE)); + if ($enchantments->error) + { + CLISetup::log('Required table ?_itemenchantment seems to be empty! Leaving enchants()...', CLISetup::LOG_ERROR); + CLISetup::log(); + return false; + } foreach (CLISetup::$localeIds as $lId) { @@ -85,6 +88,13 @@ if (!CLI) $enchantsOut = []; foreach ($enchantSpells->iterate() as $__) { + $eId = $enchantSpells->getField('effect1MiscValue'); + if (!$enchantments->getEntry($eId)) + { + CLISetup::log(' * could not find enchantment #'.$eId.' referenced by spell #'.$enchantSpells->id, CLISetup::LOG_WARN); + continue; + } + // slots have to be recalculated $slot = 0; if ($enchantSpells->getField('equippedItemClass') == 4) // armor @@ -111,7 +121,6 @@ if (!CLI) } } - $eId = $enchantSpells->getField('effect1MiscValue'); // defaults $ench = array( @@ -121,20 +130,20 @@ if (!CLI) 'source' => [], // <0: item; >0:spell 'skill' => -1, // modified if skill 'slots' => [], // determined per spell but set per item - 'enchantment' => Util::localizedString($enchMisc[$eId]['text'], 'text'), - 'jsonequip' => @$enchJSON[$eId] ?: [], + 'enchantment' => $enchantments->getField('name', true), + 'jsonequip' => $enchantments->getStatGain(), 'temp' => 0, // always 0 'classes' => 0, // modified by item ); - if (isset($enchMisc[$eId]['reqskill'])) - $ench['jsonequip']['reqskill'] = $enchMisc[$eId]['reqskill']; + if ($_ = $enchantments->getField('skillLine')) + $ench['jsonequip']['reqskill'] = $_; - if (isset($enchMisc[$eId]['reqskillrank'])) - $ench['jsonequip']['reqskill'] = $enchMisc[$eId]['reqskillrank']; + if ($_ = $enchantments->getField('skillLevel')) + $ench['jsonequip']['reqskillrank'] = $_; - if (isset($enchMisc[$eId]['requiredLevel'])) - $ench['jsonequip']['requiredLevel'] = $enchMisc[$eId]['requiredLevel']; + if (($_ = $enchantments->getField('requiredLevel')) && $_ > 1) + $ench['jsonequip']['reqlevel'] = $_; // check if the spell has an entry in skill_line_ability -> Source:Profession if ($skills = $enchantSpells->getField('skillLines')) diff --git a/setup/tools/filegen/gems.func.php b/setup/tools/filegen/gems.func.php index 68f6723e..be8e87ad 100644 --- a/setup/tools/filegen/gems.func.php +++ b/setup/tools/filegen/gems.func.php @@ -52,8 +52,13 @@ if (!CLI) foreach ($gems as $pop) $enchIds[] = $pop['enchId']; - $enchMisc = []; - $enchJSON = Util::parseItemEnchantment($enchIds, false, $enchMisc); + $enchantments = new EnchantmentList(array(['id', $enchIds], CFG_SQL_LIMIT_NONE)); + if ($enchantments->error) + { + CLISetup::log('Required table ?_itemenchantment seems to be empty! Leaving gems()...', CLISetup::LOG_ERROR); + CLISetup::log(); + return false; + } foreach (CLISetup::$localeIds as $lId) { @@ -65,12 +70,18 @@ if (!CLI) $gemsOut = []; foreach ($gems as $pop) { + if (!$enchantments->getEntry($pop['enchId'])) + { + CLISetup::log(' * could not find enchantment #'.$pop['enchId'].' referenced by item #'.$gem['itemId'], CLISetup::LOG_WARN); + continue; + } + $gemsOut[$pop['itemId']] = array( 'name' => Util::localizedString($pop, 'name'), 'quality' => $pop['quality'], 'icon' => strToLower($pop['icon']), - 'enchantment' => Util::localizedString(@$enchMisc[$pop['enchId']]['text'] ?: [], 'text'), - 'jsonequip' => @$enchJSON[$pop['enchId']] ?: [], + 'enchantment' => $enchantments->getField('name', true), + 'jsonequip' => $enchantments->getStatGain(), 'colors' => $pop['colors'], 'expansion' => $pop['expansion'] ); diff --git a/setup/tools/sqlGen.class.php b/setup/tools/sqlGen.class.php index fe9f9f39..d11e855e 100644 --- a/setup/tools/sqlGen.class.php +++ b/setup/tools/sqlGen.class.php @@ -23,7 +23,6 @@ class SqlGen 'achievementcategory' => ['achievement_category', false, null, null], 'achievementcriteria' => ['achievement_criteria', false, null, null], 'glyphproperties' => ['glyphproperties', true, null, null], - 'itemenchantment' => ['spellitemenchantment', false, null, null], 'itemenchantmentcondition' => ['spellitemenchantmentcondition', false, null, null], 'itemextendedcost' => ['itemextendedcost', false, null, null], 'itemlimitcategory' => ['itemlimitcategory', false, null, null], @@ -46,6 +45,7 @@ class SqlGen 'shapeshiftforms' => [null, null, null, null], 'skillline' => [null, null, null, null], 'emotes' => [null, null, null, null], + 'itemenchantment' => [null, null, null, ['spell_enchant_proc_data']], 'achievement' => [null, null, null, ['dbc_achievement']], 'creature' => [null, null, null, ['creature_template', 'locales_creature', 'creature_classlevelstats', 'instance_encounters']], 'currencies' => [null, null, null, ['item_template', 'locales_item']], @@ -62,8 +62,8 @@ class SqlGen 'spawns' /* + waypoints */ => [null, null, null, ['creature', 'creature_addon', 'gameobject', 'gameobject_template', 'vehicle_accessory', 'vehicle_accessory_template', 'script_waypoint', 'waypoints', 'waypoint_data']], 'zones' => [null, null, null, ['access_requirement']], 'itemset' => [null, null, ['spell'], ['item_template', 'game_event']], - 'item_stats' => [null, null, ['items', 'spell'], null], - 'source' => [null, null, ['spell', 'achievements'], ['npc_vendor', 'game_event_npc_vendor', 'creature', 'quest_template', 'playercreateinfo_item', 'npc_trainer', 'skill_discovery_template', 'playercreateinfo_spell', 'achievement_reward']] + 'item_stats' /* + ench */ => [null, null, ['items', 'spell'], null], + 'source' => [null, null, ['spell', 'achievement'], ['npc_vendor', 'game_event_npc_vendor', 'creature', 'quest_template', 'playercreateinfo_item', 'npc_trainer', 'skill_discovery_template', 'playercreateinfo_spell', 'achievement_reward']] ); public static $cliOpts = []; @@ -92,6 +92,8 @@ class SqlGen self::$subScripts = array_keys(self::$tables); if ($doScripts) self::$subScripts = array_intersect($doScripts, self::$subScripts); + else if ($doScripts === null) + self::$subScripts = []; if (!CLISetup::$localeIds /* && this script has localized text */) { @@ -124,7 +126,7 @@ class SqlGen if (!empty($info[2]) && array_intersect($doTbls, $info[2])) $doTbls[] = $name; - $doTbls = array_unique($doTbls); + $doTbls = $doTbls ? array_unique($doTbls) : null; } else if (!empty($_['sql'])) $doTbls = explode(',', $_['sql']); diff --git a/setup/tools/sqlgen/item_stats.func.php b/setup/tools/sqlgen/item_stats.func.php index 268d3c02..3aebe1ff 100644 --- a/setup/tools/sqlgen/item_stats.func.php +++ b/setup/tools/sqlgen/item_stats.func.php @@ -10,17 +10,18 @@ if (!CLI) /* deps: * ?_items finalized * ?_spell finalized + * dbc_spellitemenchantment */ $customData = array( ); -$reqDBC = []; +$reqDBC = ['spellitemenchantment']; class ItemStatSetup extends ItemList { private $statCols = []; - public function __construct($start, $limit, array $ids) + public function __construct($start, $limit, array $ids, array $enchStats) { $this->statCols = DB::Aowow()->selectCol('SELECT `COLUMN_NAME` FROM `INFORMATION_SCHEMA`.`COLUMNS` WHERE `TABLE_NAME` LIKE "%item_stats"'); $this->queryOpts['i']['o'] = 'i.id ASC'; @@ -36,6 +37,8 @@ class ItemStatSetup extends ItemList $conditions[] = ['id', $ids]; parent::__construct($conditions); + + $this->enchParsed = $enchStats; } public function writeStatsTable() @@ -87,27 +90,25 @@ class ItemStatSetup extends ItemList } // execute: convert enchantments to stats - if ($enchantments) + // and merge enchantments back + foreach ($enchantments as $eId => $items) { - $parsed = Util::parseItemEnchantment(array_keys($enchantments)); + if (empty($this->enchParsed[$eId])) + continue; - // and merge enchantments back - foreach ($parsed as $eId => $stats) + foreach ($items as $item) { - foreach ($enchantments[$eId] as $item) - { - if ($item > 0) // apply socketBonus - $this->json[$item]['socketbonusstat'] = $stats; - else /* if ($item < 0) */ // apply gemEnchantment - Util::arraySumByKey($this->json[-$item], $stats); - } + if ($item > 0) // apply socketBonus + $this->json[$item]['socketbonusstat'] = $this->enchParsed[$eId]; + else /* if ($item < 0) */ // apply gemEnchantment + Util::arraySumByKey($this->json[-$item], $this->enchParsed[$eId]); } } // collect data and write to DB foreach ($this->iterate() as $__) { - $updateFields = ['id' => $this->id]; + $updateFields = ['type' => TYPE_ITEM, 'typeId' => $this->id]; foreach (@$this->json[$this->id] as $k => $v) { @@ -128,8 +129,7 @@ class ItemStatSetup extends ItemList } } - if (count($updateFields) > 1) - DB::Aowow()->query('REPLACE INTO ?_item_stats (?#) VALUES (?a)', array_keys($updateFields), array_values($updateFields), $this->id); + DB::Aowow()->query('REPLACE INTO ?_item_stats (?#) VALUES (?a)', array_keys($updateFields), array_values($updateFields)); } } } @@ -137,9 +137,15 @@ class ItemStatSetup extends ItemList function item_stats(array $ids = []) { $offset = 0; + + CLISetup::log(' - applying stats for enchantments'); + $enchStats = enchantment_stats(); + CLISetup::log(' '.count($enchStats).' enchantments parsed'); + CLISetup::log(' - applying stats for items'); + while (true) { - $items = new ItemStatSetup($offset, SqlGen::$stepSize, $ids); + $items = new ItemStatSetup($offset, SqlGen::$stepSize, $ids, $enchStats); if ($items->error) break; @@ -157,4 +163,112 @@ function item_stats(array $ids = []) return true; } +function enchantment_stats() +{ + $statCols = DB::Aowow()->selectCol('SELECT `COLUMN_NAME` FROM `INFORMATION_SCHEMA`.`COLUMNS` WHERE `TABLE_NAME` LIKE "%item_stats"'); + $enchants = DB::Aowow()->select('SELECT *, Id AS ARRAY_KEY FROM dbc_spellitemenchantment'); + $spells = []; + $spellStats = []; + + foreach ($enchants as $eId => $e) + { + for ($i = 1; $i <=3; $i++) + { + // trigger: onEquip + valid SpellId + if ($e['object'.$i] > 0 && $e['type'.$i] == 3) + $spells[] = $e['object'.$i]; + } + } + + if ($spells) + $spellStats = (new SpellList(array(['id', $spells], CFG_SQL_LIMIT_NONE)))->getStatGain(); + + $result = []; + foreach ($enchants as $eId => $e) + { + // parse stats + $result[$eId] = []; + for ($h = 1; $h <= 3; $h++) + { + $obj = (int)$e['object'.$h]; + $val = (int)$e['amount'.$h]; + + switch ($e['type'.$h]) + { + case 6: // TYPE_TOTEM +AmountX as DPS (Rockbiter) + $result[$eId]['dps'] = $val; // we do not use dps as itemMod, so apply it directly + $obj = null; + break; + case 2: // TYPE_DAMAGE +AmountX damage + $obj = ITEM_MOD_WEAPON_DMG; + break; + // case 1: // TYPE_COMBAT_SPELL proc spell from ObjectX (amountX == procChance) + // case 7: // TYPE_USE_SPELL Engineering gadgets + case 3: // TYPE_EQUIP_SPELL Spells from ObjectX (use of amountX?) + if (!empty($spellStats[$obj])) + foreach ($spellStats[$obj] as $mod => $val) + if ($str = Util::$itemMods[$mod]) + Util::arraySumByKey($result[$eId], [$str => $val]); + + $obj = null; + break; + case 4: // TYPE_RESISTANCE +AmountX resistance for ObjectX School + switch ($obj) + { + case 0: // Physical + $obj = ITEM_MOD_ARMOR; + break; + case 1: // Holy + $obj = ITEM_MOD_HOLY_RESISTANCE; + break; + case 2: // Fire + $obj = ITEM_MOD_FIRE_RESISTANCE; + break; + case 3: // Nature + $obj = ITEM_MOD_NATURE_RESISTANCE; + break; + case 4: // Frost + $obj = ITEM_MOD_FROST_RESISTANCE; + break; + case 5: // Shadow + $obj = ITEM_MOD_SHADOW_RESISTANCE; + break; + case 6: // Arcane + $obj = ITEM_MOD_ARCANE_RESISTANCE; + break; + default: + $obj = null; + } + break; + case 5: // TYPE_STAT +AmountX for Statistic by type of ObjectX + 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 + + break; // stats are directly assigned below + case 8: // TYPE_PRISMATIC_SOCKET Extra Sockets AmountX as socketCount (ignore) + $result[$eId]['nsockets'] = $val; // there is no itemmod for sockets, so apply it directly + default: // TYPE_NONE dnd stuff; skip assignment below + $obj = null; + } + + if ($obj !== null) + if ($str = Util::$itemMods[$obj]) // check if we use these mods + Util::arraySumByKey($result[$eId], [$str => $val]); + } + + $updateCols = ['type' => TYPE_ENCHANTMENT, 'typeId' => $eId]; + foreach ($result[$eId] as $k => $v) + { + if (!in_array($k, $statCols) || !$v || $k == 'id') + continue; + + $updateCols[$k] = number_format($v, 2, '.', ''); + } + + DB::Aowow()->query('REPLACE INTO ?_item_stats (?#) VALUES (?a)', array_keys($updateCols), array_values($updateCols)); + } + + return $result; +} + ?> diff --git a/setup/tools/sqlgen/itemenchantment.func.php b/setup/tools/sqlgen/itemenchantment.func.php new file mode 100644 index 00000000..4c4c1f36 --- /dev/null +++ b/setup/tools/sqlgen/itemenchantment.func.php @@ -0,0 +1,37 @@ +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; +} + +?> diff --git a/setup/updates/1438620486_01.sql b/setup/updates/1438620486_01.sql new file mode 100644 index 00000000..6e3cc6da --- /dev/null +++ b/setup/updates/1438620486_01.sql @@ -0,0 +1,66 @@ +-- structure changed hard +DROP TABLE IF EXISTS `dbc_spellitemenchantment`; +DROP TABLE IF EXISTS `aowow_itemenchantment`; +CREATE TABLE `aowow_itemenchantment` ( + `id` smallint(5) unsigned NOT NULL, + `charges` tinyint(4) unsigned NOT NULL, + `cuFlags` int(10) unsigned NOT NULL, + `procChance` tinyint(3) unsigned NOT NULL, + `ppmRate` float NOT NULL, + `type1` tinyint(4) unsigned NOT NULL, + `type2` tinyint(4) unsigned NOT NULL, + `type3` tinyint(4) unsigned NOT NULL, + `amount1` smallint(5) NOT NULL, + `amount2` smallint(5) NOT NULL, + `amount3` smallint(5) NOT NULL, + `object1` mediumint(9) unsigned NOT NULL, + `object2` mediumint(9) unsigned NOT NULL, + `object3` smallint(5) unsigned NOT NULL, + `name_loc0` varchar(65) NOT NULL, + `name_loc2` varchar(91) NOT NULL, + `name_loc3` varchar(84) NOT NULL, + `name_loc6` varchar(89) NOT NULL, + `name_loc8` varchar(96) NOT NULL, + `conditionId` tinyint(3) unsigned NOT NULL, + `skillLine` smallint(5) unsigned NOT NULL, + `skillLevel` smallint(5) unsigned NOT NULL, + `requiredLevel` tinyint(3) unsigned NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +ALTER TABLE `aowow_item_stats` + ALTER `id` DROP DEFAULT; +ALTER TABLE `aowow_item_stats` + ADD COLUMN `type` smallint(5) unsigned NOT NULL FIRST, + CHANGE COLUMN `id` `typeId` mediumint(9) unsigned NOT NULL AFTER `type`, + DROP INDEX `item`, + DROP PRIMARY KEY, + ADD PRIMARY KEY (`typeId`, `type`) + +ALTER TABLE `aowow_articles` + ALTER `type` DROP DEFAULT, + ALTER `typeId` DROP DEFAULT; +ALTER TABLE `aowow_articles` + CHANGE COLUMN `type` `type` smallint(5) NOT NULL FIRST, + CHANGE COLUMN `typeId` `typeId` mediumint(9) NOT NULL AFTER `type`; + +ALTER TABLE `aowow_comments` + ALTER `type` DROP DEFAULT, + ALTER `typeId` DROP DEFAULT; +ALTER TABLE `aowow_comments` + CHANGE COLUMN `type` `type` smallint(5) unsigned NOT NULL COMMENT 'Type of Page' AFTER `id`, + CHANGE COLUMN `typeId` `typeId` mediumint(9) NOT NULL COMMENT 'ID Of Page' AFTER `type`; + +ALTER TABLE `aowow_screenshots` + ALTER `type` DROP DEFAULT; + ALTER `typeId` DROP DEFAULT; +ALTER TABLE `aowow_screenshots` + CHANGE COLUMN `type` `type` smallint(5) unsigned NOT NULL AFTER `id`, + CHANGE COLUMN `typeId` `typeId` mediumint(9) NOT NULL AFTER `type`; + +ALTER TABLE `aowow_videos` + ALTER `type` DROP DEFAULT, + ALTER `typeId` DROP DEFAULT; +ALTER TABLE `aowow_videos` + CHANGE COLUMN `type` `type` smallint(5) unsigned NOT NULL AFTER `id`, + CHANGE COLUMN `typeId` `typeId` mediumint(9) NOT NULL AFTER `type`; diff --git a/static/css/aowow.css b/static/css/aowow.css index accbaf6d..464b2940 100644 --- a/static/css/aowow.css +++ b/static/css/aowow.css @@ -38,6 +38,7 @@ a { color: #FFD100; cursor: pointer; outline: none; + text-decoration: none; } a:hover { diff --git a/static/js/Markup.js b/static/js/Markup.js index e76f59fb..89d03411 100644 --- a/static/js/Markup.js +++ b/static/js/Markup.js @@ -570,6 +570,86 @@ var Markup = { return str; } }, + emote: + { + empty: true, + allowInReplies: true, + attr: + { + unnamed: { req: true, valid: /^[0-9]+$/ }, + domain: { req: false, valid: /^(beta|mop|ptr|www|de|es|fr|ru|pt)$/ }, + site: { req: false, valid: /^(beta|mop|ptr|www|de|es|fr|ru|pt)$/ } + }, + validate: function(attr) + { + if((attr.domain || attr.site) && Markup.dbpage) + return false; + return true; + }, + toHtml: function(attr) + { + var id = attr.unnamed; + var domainInfo = Markup._getDatabaseDomainInfo(attr); + var url = domainInfo[0]; + var nameCol = domainInfo[1]; + + if(g_emotes[id] && g_emotes[id][nameCol]) + { + return '' + Markup._safeHtml(g_emotes[id][nameCol]) + ''; + } + return '(' + LANG.types[501][0] + ' #' + id + ')'; + }, + toText: function(attr) + { + var id = attr.unnamed; + var domainInfo = Markup._getDatabaseDomainInfo(attr); + var nameCol = domainInfo[1]; + + if(g_emotes[id] && g_emotes[id][nameCol]) + return Markup._safeHtml(g_emotes[id][nameCol]); + return LANG.types[501][0] + ' #' + id; + } + }, + enchantment: + { + empty: true, + allowInReplies: true, + attr: + { + unnamed: { req: true, valid: /^[0-9]+$/ }, + domain: { req: false, valid: /^(beta|mop|ptr|www|de|es|fr|ru|pt)$/ }, + site: { req: false, valid: /^(beta|mop|ptr|www|de|es|fr|ru|pt)$/ } + }, + validate: function(attr) + { + if((attr.domain || attr.site) && Markup.dbpage) + return false; + return true; + }, + toHtml: function(attr) + { + var id = attr.unnamed; + var domainInfo = Markup._getDatabaseDomainInfo(attr); + var url = domainInfo[0]; + var nameCol = domainInfo[1]; + + if(g_enchantments[id] && g_enchantments[id][nameCol]) + { + return '' + Markup._safeHtml(g_enchantments[id][nameCol]) + ''; + } + return '(' + LANG.types[502][0] + ' #' + id + ')'; + }, + toText: function(attr) + { + var id = attr.unnamed; + var domainInfo = Markup._getDatabaseDomainInfo(attr); + var nameCol = domainInfo[1]; + + if(g_enchantments[id] && g_enchantments[id][nameCol]) + return Markup._safeHtml(g_enchantments[id][nameCol]); + return LANG.types[502][0] + ' #' + id; + } + }, event: { empty: true, diff --git a/static/js/filters.js b/static/js/filters.js index b0444f96..b4f2cafe 100644 --- a/static/js/filters.js +++ b/static/js/filters.js @@ -401,8 +401,83 @@ var fi_filters = { { id: 18, name: 'teamname5v5', type: 'str' }, { id: 19, name: 'teamrtng5v5', type: 'num' }, { id: 20, name: 'teamcontrib5v5', type: 'num' } - ] + ], + // custom + enchantments: [ + { id: 1, name: 'sepgeneral' }, + { id: 2, name: 'id', type: 'num', before: 'name' }, + { id: 3, name: 'requiresprof', type: 'profession' }, + { id: 4, name: 'reqskillrank', type: 'num' }, + { id: 5, name: 'hascondition', type: 'yn' }, + + { id: 19, name: 'sepbasestats' }, + { id: 21, name: 'agi', type: 'num' }, + { id: 23, name: 'int', type: 'num' }, + { id: 22, name: 'sta', type: 'num' }, + { id: 24, name: 'spi', type: 'num' }, + { id: 20, name: 'str', type: 'num' }, + { id: 115, name: 'health', type: 'num' }, + { id: 116, name: 'mana', type: 'num' }, + { id: 60, name: 'healthrgn', type: 'num' }, + { id: 61, name: 'manargn', type: 'num' }, + + { id: 120, name: 'sepdefensivestats' }, + { id: 41, name: 'armor', type: 'num' }, + { id: 44, name: 'blockrtng', type: 'num' }, + { id: 43, name: 'block', type: 'num' }, + { id: 42, name: 'defrtng', type: 'num' }, + { id: 45, name: 'dodgertng', type: 'num' }, + { id: 46, name: 'parryrtng', type: 'num' }, + { id: 79, name: 'resirtng', type: 'num' }, + + { id: 31, name: 'sepoffensivestats' }, + { id: 32, name: 'dps', type: 'num' }, + { id: 34, name: 'dmg', type: 'num' }, + { id: 77, name: 'atkpwr', type: 'num' }, + { id: 97, name: 'feratkpwr', type: 'num', indent: 1 }, + { id: 114, name: 'armorpenrtng', type: 'num' }, + { id: 96, name: 'critstrkrtng', type: 'num' }, + { id: 117, name: 'exprtng', type: 'num' }, + { id: 103, name: 'hastertng', type: 'num' }, + { id: 119, name: 'hitrtng', type: 'num' }, + { id: 94, name: 'splpen', type: 'num' }, + { id: 123, name: 'splpwr', type: 'num' }, + { id: 52, name: 'arcsplpwr', type: 'num', indent: 1 }, + { id: 53, name: 'firsplpwr', type: 'num', indent: 1 }, + { id: 54, name: 'frosplpwr', type: 'num', indent: 1 }, + { id: 55, name: 'holsplpwr', type: 'num', indent: 1 }, + { id: 56, name: 'natsplpwr', type: 'num', indent: 1 }, + { id: 57, name: 'shasplpwr', type: 'num', indent: 1 }, + + { id: 121, name: 'sepresistances' }, + { id: 25, name: 'arcres', type: 'num' }, + { id: 26, name: 'firres', type: 'num' }, + { id: 28, name: 'frores', type: 'num' }, + { id: 30, name: 'holres', type: 'num' }, + { id: 27, name: 'natres', type: 'num' }, + { id: 29, name: 'shares', type: 'num' }, + + { id: 47, name: 'sepindividualstats' }, + { id: 37, name: 'mleatkpwr', type: 'num' }, + { id: 84, name: 'mlecritstrkrtng', type: 'num' }, + { id: 78, name: 'mlehastertng', type: 'num' }, + { id: 95, name: 'mlehitrtng', type: 'num' }, + { id: 38, name: 'rgdatkpwr', type: 'num' }, + { id: 40, name: 'rgdcritstrkrtng', type: 'num' }, + { id: 101, name: 'rgdhastertng', type: 'num' }, + { id: 39, name: 'rgdhitrtng', type: 'num' }, + { id: 49, name: 'splcritstrkrtng', type: 'num' }, + { id: 102, name: 'splhastertng', type: 'num' }, + { id: 48, name: 'splhitrtng', type: 'num' }, + { id: 51, name: 'spldmg', type: 'num' }, + { id: 50, name: 'splheal', type: 'num' }, + + { id: 9999,name: 'sepcommunity' }, + { id: 10, name: 'hascomments', type: 'yn' }, + { id: 11, name: 'hasscreenshots', type: 'yn' }, + { id: 12, name: 'hasvideos', type: 'yn' } + ] }; function fi_toggle() { diff --git a/static/js/global.js b/static/js/global.js index 729cde2c..c27d386b 100644 --- a/static/js/global.js +++ b/static/js/global.js @@ -2256,7 +2256,7 @@ function ss_appendSticky() { th = sections[sections.length - (lv_videos && lv_videos.length ? 2 : 1)]; } - $WH.ae(a, $WH.ct(th.innerText + ' (' + lv_screenshots.length + ')')); + $WH.ae(a, $WH.ct(th.textContent + ' (' + lv_screenshots.length + ')')); a.href = '#screenshots' a.title = $WH.sprintf(LANG.infobox_showall, lv_screenshots.length); a.onclick = function() { @@ -2876,12 +2876,13 @@ function vi_appendSticky() { var th = $WH.ge('infobox-videos'); var a = $WH.ce('a'); + if (!th) { var sections = $('th', _.parentNode); th = sections[sections.length - (lv_videos && lv_videos.length ? 2 : 1)]; } - $WH.ae(a, $WH.ct(th.innerText + ' (' + lv_videos.length + ')')); + $WH.ae(a, $WH.ct(th.textContent + ' (' + lv_videos.length + ')')); a.href = '#videos' a.title = $WH.sprintf(LANG.infobox_showall, lv_videos.length); a.onclick = function() { @@ -21102,25 +21103,29 @@ var g_classes = {}, g_races = {}, g_skills = {}, - g_gatheredcurrencies = {}; + g_gatheredcurrencies = {}, + g_enchantments = {}, + g_emotes = {}; var g_types = { - 1: 'npc', - 2: 'object', - 3: 'item', - 4: 'itemset', - 5: 'quest', - 6: 'spell', - 7: 'zone', - 8: 'faction', - 9: 'pet', - 10: 'achievement', - 11: 'title', - 12: 'event', - 13: 'class', - 14: 'race', - 15: 'skill', - 17: 'currency' + 1: 'npc', + 2: 'object', + 3: 'item', + 4: 'itemset', + 5: 'quest', + 6: 'spell', + 7: 'zone', + 8: 'faction', + 9: 'pet', + 10: 'achievement', + 11: 'title', + 12: 'event', + 13: 'class', + 14: 'race', + 15: 'skill', + 17: 'currency', + 501: 'emote', + 502: 'enchantment' }; // Items diff --git a/static/js/locale_dede.js b/static/js/locale_dede.js index 4cef5e36..4a41bbdc 100644 --- a/static/js/locale_dede.js +++ b/static/js/locale_dede.js @@ -770,6 +770,17 @@ var mn_currencies = [ [2,"Spieler gegen Spieler","?currencies=2"], [1,"Verschiedenes","?currencies=1"] ]; +var mn_enchantments = [ + [1,"Zauber (Auslösung)","?enchantments&filter=ty=1"], + [3,"Zauber (Anlegen)","?enchantments&filter=ty=3"], + [7,"Zauber (Benutzen)","?enchantments&filter=ty=7"], + [8,"Prismatischer Sockel","?enchantments&filter=ty=8"], + [5,"Statistik","?enchantments&filter=ty=5"], + [2,"Waffenschaden","?enchantments&filter=ty=2"], + [6,"DPS","?enchantments&filter=ty=6"], + [4,"Verteidigung","?enchantments&filter=ty=4"] +]; + var mn_talentCalc = [ [6,"Todesritter","?talent#j",,{className:"c6",tinyIcon:"class_deathknight"}], [11,"Druide","?talent#0",,{className:"c11",tinyIcon:"class_druid"}], @@ -836,7 +847,8 @@ var mn_database = [ [15,"Währungen","?currencies",mn_currencies], [11,"Weltereignisse","?events",mn_holidays], [1,"Zauber","?spells",mn_spells], - [100,"Emotes","?emotes",null] + [100,"Emotes","?emotes",null], + [101,"Verzauberungen","?enchantments",mn_enchantments] ]; var mn_tools = [ [0,"Talentrechner","?talent",mn_talentCalc], @@ -2604,6 +2616,7 @@ var LANG = { lvnote_arenateamsfound: "Insgesamt $1 Arena-Teams", lvnote_arenateamsfound2: "Insgesamt $1 Arena-Teams, $2 passende", lvnote_currenciesfound: "$1 Währungen gefunden ($2 angezeigt)", + lvnote_enchantmentsfound: "$1 Verzauberungen gefunden ($2 angezeigt)", lvnote_createafilter: 'Filter erstellen', lvnote_filterresults: 'Diese Ergebnisse filtern', @@ -3175,23 +3188,25 @@ var LANG = { myaccount_purgesuccess: "Bekanntmachungsdaten wurden erfolgreich gelöscht!", types: { - 1: ["NPC", "NPC" , "NPCs", "NPCs"], - 2: ["Objekt", "Objekt", "Objekte", "Objekte"], - 3: ["Gegenstand", "Gegenstand", "Gegenstände", "Gegenstände"], - 4: ["Ausrüstungsset", "Ausrüstungsset", "Ausrüstungssets", "Ausrüstungssets"], - 5: ["Quest", "Quest", "Quests", "Quests"], - 6: ["Zauber", "Zauber", "Zauber", "Zauber"], - 7: ["Zone", "Zone", "Gebiete", "Gebiete"], - 8: ["Fraktion", "Fraktion", "Fraktionen", "Fraktionen"], - 9: ["Begleiter", "Begleiter", "Begleiter", "Begleiter"], - 10: ["Erfolg", "Erfolg", "Erfolge", "Erfolge"], - 11: ["Titel", "Titel", "Titel", "Titel"], - 12: ["Weltereignis", "Weltereignis", "Weltereignisse", "Weltereignisse"], - 13: ["Klasse", "Klasse", "Klassen", "Klassen"], - 14: ["Volk", "Volk", "Völker", "Völker"], - 15: ["Fertigkeit", "Fertigkeit", "Fertigkeiten", "Fertigkeiten"], - 16: ["Statistik", "Statistik", "Statistiken", "Statistiken"], - 17: ["Währung", "Währung", "Währungen", "Währungen"] + 1: ["NPC", "NPC" , "NPCs", "NPCs"], + 2: ["Objekt", "Objekt", "Objekte", "Objekte"], + 3: ["Gegenstand", "Gegenstand", "Gegenstände", "Gegenstände"], + 4: ["Ausrüstungsset", "Ausrüstungsset", "Ausrüstungssets", "Ausrüstungssets"], + 5: ["Quest", "Quest", "Quests", "Quests"], + 6: ["Zauber", "Zauber", "Zauber", "Zauber"], + 7: ["Zone", "Zone", "Gebiete", "Gebiete"], + 8: ["Fraktion", "Fraktion", "Fraktionen", "Fraktionen"], + 9: ["Begleiter", "Begleiter", "Begleiter", "Begleiter"], + 10: ["Erfolg", "Erfolg", "Erfolge", "Erfolge"], + 11: ["Titel", "Titel", "Titel", "Titel"], + 12: ["Weltereignis", "Weltereignis", "Weltereignisse", "Weltereignisse"], + 13: ["Klasse", "Klasse", "Klassen", "Klassen"], + 14: ["Volk", "Volk", "Völker", "Völker"], + 15: ["Fertigkeit", "Fertigkeit", "Fertigkeiten", "Fertigkeiten"], + 16: ["Statistik", "Statistik", "Statistiken", "Statistiken"], + 17: ["Währung", "Währung", "Währungen", "Währungen"], + 501: ["Emote", "Emote", "Emotes", "Emotes"], + 502: ["Verzauberung", "Verzauberung", "Verzauberungen", "Verzauberungen"] }, timeunitssg: ["Jahr", "Monat", "Woche", "Tag", "Stunde", "Minute", "Sekunde"], @@ -3865,6 +3880,18 @@ var LANG = { teamcontrib5v5: "5v5 Arena-Teambeteiligung" }, + // custom + fienchantments: { + id: "ID", + hascondition: "Benötigt Edelsteinkombination", + requiresprof: "Benötigt einen Beruf", + + sepcommunity: "Community", + hascomments: "Has comments", + hasscreenshots: "Has screenshots", + hasvideos: "Has videos" + }, + pr_notice: 'Zum ersten Mal hier? – Seid nicht schüchtern! Schaut ruhig mal auf unserer Hilfeseite (zurzeit noch unübersetzt) nach!   Schließen', pr_datasource: 'Daten in dieser Registerkarte wurden das letzte Mal $2 von $1 aktualisiert.', pr_purgedata: "Klickt, um alle Abschlussdaten in der aktuellen Registerkarte zu löschen.
Nur der Benuzter, der die Daten hochgeladen hat, darf sie löschen.", diff --git a/static/js/locale_enus.js b/static/js/locale_enus.js index 40eb796d..980b0cbe 100644 --- a/static/js/locale_enus.js +++ b/static/js/locale_enus.js @@ -816,6 +816,16 @@ var mn_currencies = [ [1,"Miscellaneous","?currencies=1"], [2,"Player vs. Player","?currencies=2"] ]; +var mn_enchantments = [ + [1,"Proc Spell","?enchantments&filter=ty=1"], + [3,"Equip Spell","?enchantments&filter=ty=3"], + [7,"Use Spell","?enchantments&filter=ty=7"], + [8,"Prismatic Socket","?enchantments&filter=ty=8"], + [5,"Statistics","?enchantments&filter=ty=5"], + [2,"Weapon Damage","?enchantments&filter=ty=2"], + [6,"DPS","?enchantments&filter=ty=6"], + [4,"Defense","?enchantments&filter=ty=4"] +]; var mn_talentCalc = [ [6,"Death Knight","?talent#j",,{className:"c6",tinyIcon:"class_deathknight"}], [11,"Druid","?talent#0",,{className:"c11",tinyIcon:"class_druid"}], @@ -882,7 +892,8 @@ var mn_database = [ [10,"Titles","?titles",mn_titles], [11,"World Events","?events",mn_holidays], [6,"Zones","?zones",mn_zones], - [100,"Emotes","?emotes",null] + [100,"Emotes","?emotes",null], + [101,"Enchantments","?enchantments",mn_enchantments] ]; var mn_tools = [ [0,"Talent Calculator","?talent",mn_talentCalc], @@ -2652,6 +2663,7 @@ var LANG = { lvnote_arenateamsfound: "$1 total arena teams", lvnote_arenateamsfound2: "$1 total arena teams, $2 matching", lvnote_currenciesfound: "$1 currencies found ($2 displayed)", + lvnote_enchantmentsfound: "$1 enchantments found ($2 displayed)", lvnote_createafilter: 'Create a filter', lvnote_filterresults: 'Filter these results', @@ -3223,23 +3235,25 @@ var LANG = { myaccount_purgesuccess: "Announcement data has been successfully purged!", types: { - 1: ["NPC", "NPC" , "NPCs", "NPCs"], - 2: ["Object", "object", "Objects", "objects"], - 3: ["Item", "item", "Items", "items"], - 4: ["Item Set", "item set", "Item Sets", "item sets"], - 5: ["Quest", "quest", "Quests", "quests"], - 6: ["Spell", "spell", "Spells", "spells"], - 7: ["Zone", "zone", "Zones", "zones"], - 8: ["Faction", "faction", "Factions", "factions"], - 9: ["Pet", "pet", "Pets", "pets"], - 10: ["Achievement", "achievement", "Achievements", "achievements"], - 11: ["Title", "title", "Titles", "titles"], - 12: ["World Event", "world event", "World Events", "world events"], - 13: ["Class", "class", "Classes", "classes"], - 14: ["Race", "race", "Races", "races"], - 15: ["Skill", "skill", "Skills", "skills"], - 16: ["Statistic", "statistic", "Statistics", "statistics"], - 17: ["Currency", "currency", "Currencies", "currencies"] + 1: ["NPC", "NPC" , "NPCs", "NPCs"], + 2: ["Object", "object", "Objects", "objects"], + 3: ["Item", "item", "Items", "items"], + 4: ["Item Set", "item set", "Item Sets", "item sets"], + 5: ["Quest", "quest", "Quests", "quests"], + 6: ["Spell", "spell", "Spells", "spells"], + 7: ["Zone", "zone", "Zones", "zones"], + 8: ["Faction", "faction", "Factions", "factions"], + 9: ["Pet", "pet", "Pets", "pets"], + 10: ["Achievement", "achievement", "Achievements", "achievements"], + 11: ["Title", "title", "Titles", "titles"], + 12: ["World Event", "world event", "World Events", "world events"], + 13: ["Class", "class", "Classes", "classes"], + 14: ["Race", "race", "Races", "races"], + 15: ["Skill", "skill", "Skills", "skills"], + 16: ["Statistic", "statistic", "Statistics", "statistics"], + 17: ["Currency", "currency", "Currencies", "currencies"], + 501: ["Emote", "emote", "Emotes", "emotes"], + 502: ["Enchantment", "enchantment", "Enchantments", "enchantments"] }, timeunitssg: ["year", "month", "week", "day", "hour", "minute", "second"], @@ -3912,6 +3926,18 @@ var LANG = { teamcontrib5v5: "5v5 arena team contribution" }, + // custom + fienchantments: { + id: "ID", + hascondition: "Requires a combination of gems", + requiresprof: "Requires a profession", + + sepcommunity: "Community", + hascomments: "Has comments", + hasscreenshots: "Has screenshots", + hasvideos: "Has videos" + }, + pr_notice: 'First time? – Don\'t be shy! Just check out our Help page!   close', pr_datasource: 'Data in this tab was last updated $2 by $1.', pr_purgedata: "Click to delete all completion data in the current tab.
Only the user who uploaded the data may purge it.", diff --git a/static/js/locale_eses.js b/static/js/locale_eses.js index 8effe0e0..17cb6a11 100644 --- a/static/js/locale_eses.js +++ b/static/js/locale_eses.js @@ -770,6 +770,16 @@ var mn_currencies = [ [1,"Miscelánea","?currencies=1"], [2,"Jugador contra Jugador","?currencies=2"] ]; +var mn_enchantments = [ + [1,"[Proc Spell]","?enchantments&filter=ty=1"], + [3,"[Equip Spell]","?enchantments&filter=ty=3"], + [7,"[Use Spell]","?enchantments&filter=ty=7"], + [8,"Ranura prismática","?enchantments&filter=ty=8"], + [5,"Atributos","?enchantments&filter=ty=5"], + [2,"Daño de arma","?enchantments&filter=ty=2"], + [6,"DPS","?enchantments&filter=ty=6"], + [4,"Defensa","?enchantments&filter=ty=4"] +]; var mn_talentCalc = [ [6,"Caballero de la muerte","?talent#j",,{className:"c6",tinyIcon:"class_deathknight"}], [11,"Druida","?talent#0",,{className:"c11",tinyIcon:"class_druid"}], @@ -836,7 +846,8 @@ var mn_database = [ [10,"Títulos","?titles",mn_titles], [11,"Eventos del mundo","?events",mn_holidays], [6,"Zonas","?zones",mn_zones], - [100,"Emociones","?emotes",null] + [100,"Emociones","?emotes",null], + [101,"Encantamientos","?enchantments",mn_enchantments] ]; var mn_tools = [ [0,"Calculadora de talentos","?talent",mn_talentCalc], @@ -2607,6 +2618,7 @@ var LANG = { lvnote_arenateamsfound: "$1 equipos de arena en total", lvnote_arenateamsfound2: "$1 equipos de arena en total, $2 coincidente(s)", lvnote_currenciesfound: "$1 monedas encontradas ($2 mostradas)", + lvnote_enchantmentsfound: "$1 encantamientos encontrados (mostrados $2)", lvnote_createafilter: 'Crea un filtro', lvnote_filterresults: 'Filtrar estos resultados', @@ -3178,23 +3190,25 @@ var LANG = { myaccount_purgesuccess: "¡Se han purgado los datos de los anuncios correctamente!", types: { - 1: ["PNJ", "PNJ" , "PNJs", "PNJs"], - 2: ["Entidad", "entidad", "Entidades", "entidades"], - 3: ["Objeto", "objeto", "Objetos", "objetos"], - 4: ["Conjunto de objetos", "conjunto de objetos", "Conjuntos de objetos", "conjuntos de objetos"], - 5: ["Misión", "misión", "Misiones", "misiones"], - 6: ["Hechizo", "hechizo", "Hechizos", "hechizos"], - 7: ["Zona", "zona", "Zonas", "zonas"], - 8: ["Facción", "facción", "Facciones", "facciones"], - 9: ["Mascota", "mascota", "Mascotas", "mascotas"], - 10: ["Logro", "logro", "Logros", "logros"], - 11: ["Título", "título", "Títulos", "títulos"], - 12: ["Suceso mundial", "evento del mundo", "Eventos del mundo", "eventos del mundo"], - 13: ["Clase", "Clase", "Clases", "Clases"], - 14: ["Raza", "raza", "Razas", "razas"], - 15: ["Habilidad", "habilidad", "Habilidades", "habilidades"], - 16: ["Atributo", "atributo", "Atributos", "atributos"], - 17: ["Monedas", "monedas", "Monedas", "monedas"] + 1: ["PNJ", "PNJ" , "PNJs", "PNJs"], + 2: ["Entidad", "entidad", "Entidades", "entidades"], + 3: ["Objeto", "objeto", "Objetos", "objetos"], + 4: ["Conjunto de objetos", "conjunto de objetos", "Conjuntos de objetos", "conjuntos de objetos"], + 5: ["Misión", "misión", "Misiones", "misiones"], + 6: ["Hechizo", "hechizo", "Hechizos", "hechizos"], + 7: ["Zona", "zona", "Zonas", "zonas"], + 8: ["Facción", "facción", "Facciones", "facciones"], + 9: ["Mascota", "mascota", "Mascotas", "mascotas"], + 10: ["Logro", "logro", "Logros", "logros"], + 11: ["Título", "título", "Títulos", "títulos"], + 12: ["Suceso mundial", "evento del mundo", "Eventos del mundo", "eventos del mundo"], + 13: ["Clase", "Clase", "Clases", "Clases"], + 14: ["Raza", "raza", "Razas", "razas"], + 15: ["Habilidad", "habilidad", "Habilidades", "habilidades"], + 16: ["Atributo", "atributo", "Atributos", "atributos"], + 17: ["Monedas", "monedas", "Monedas", "monedas"], + 501: ["Emoción", "emoción", "Emociones", "emociones"], + 502: ["Encantamiento", "encantamiento", "Encantamientos", "encantamientos"] }, timeunitssg: ["año", "mes", "semana", "día", "hora", "minuto", "segundo"], @@ -3870,6 +3884,18 @@ var LANG = { teamcontrib5v5: "Contribución de equipo de arena 5v5" }, + // custom + fienchantments: { + id: "ID", + hascondition: "[Requires a combination of gems]", + requiresprof: "Requiere una profesión", + + sepcommunity: "Comunidad", + hascomments: "Tiene comentarios", + hasscreenshots: "Tiene capturas de pantalla", + hasvideos: "Tiene vídeos", + }, + pr_notice: '¿La primera vez? – ¡No temas! ¡Visita nuestra página de ayuda!   cerrar', pr_datasource: 'Los datos de esta pestaña se actualizarón por última vez el $2 por $1.', pr_purgedata: "Haz click para eliminar todos los datos recogidos en la pestaña actual.
Solo aquel que ha subido los datos puede hacerlo.", diff --git a/static/js/locale_frfr.js b/static/js/locale_frfr.js index 67cb6ddc..92aa75fc 100644 --- a/static/js/locale_frfr.js +++ b/static/js/locale_frfr.js @@ -770,6 +770,16 @@ var mn_currencies = [ [1,"Divers","?currencies=1"], [2,"JcJ","?currencies=2"] ]; +var mn_enchantments = [ + [1,"[Proc Spell]","?enchantments&filter=ty=1"], + [3,"[Equip Spell]","?enchantments&filter=ty=3"], + [7,"[Use Spell]","?enchantments&filter=ty=7"], + [8,"Châsse prismatique","?enchantments&filter=ty=8"], + [5,"Statistiques","?enchantments&filter=ty=5"], + [2,"Dégâts d'arme","?enchantments&filter=ty=2"], + [6,"DPS","?enchantments&filter=ty=6"], + [4,"Défense","?enchantments&filter=ty=4"] +]; var mn_talentCalc = [ [6,"Chevalier de la mort","?talent#j",,{className:"c6",tinyIcon:"class_deathknight"}], [11,"Druide","?talent#0",,{className:"c11",tinyIcon:"class_druid"}], @@ -836,7 +846,8 @@ var mn_database = [ [10,"Titres","?titles",mn_titles], [11,"Évènements mondiaux","?events",mn_holidays], [6,"Zones","?zones",mn_zones], - [100,"Emotes","?emotes",null] + [100,"Emotes","?emotes",null], + [101,"Enchantements","?enchantments",mn_enchantments] ]; var mn_tools = [ [0,"Calculateur de talents","?talent",mn_talentCalc], @@ -2595,6 +2606,7 @@ var LANG = { lvnote_arenateamsfound: "Total de $1 équipes d'aréna", lvnote_arenateamsfound2: "Total de $1 équipes d'aréna, $2 qui coïncides", lvnote_currenciesfound: "$1 monnaies trouvées ($2 affichées)", + lvnote_enchantmentsfound: "$1 enchantements trouvés ($2 affichés)", lvnote_createafilter: 'Créer un filtre', lvnote_filterresults: 'Filtrer ces résultats', @@ -3166,23 +3178,25 @@ var LANG = { myaccount_purgesuccess: "Les données d'annonce ont été purgées correctement!", types: { - 1: ["PNJ", "PNJ" , "PNJs", "PNJs"], - 2: ["Entité", "entité", "Entités", "entités"], - 3: ["Objet", "objet", "Objets", "objets"], - 4: ["Ensemble d'objets", "ensemble d'objets", "Ensembles d'objets", "ensembles d'objets"], - 5: ["Quête", "quête", "Quêtes", "quêtes"], - 6: ["Sort", "sort", "Sorts", "sorts"], - 7: ["Zone", "zone", "Zones", "zones"], - 8: ["Faction", "faction", "Factions", "factions"], - 9: ["Familier", "familier", "Familiers", "familiers"], - 10: ["Haut fait", "haut fait", "Hauts faits", "hauts faits"], - 11: ["Titre", "titre", "Titres", "titres"], - 12: ["Événement mondial", "évènement mondial", "Évènements mondiaux", "évènements mondiaux"], - 13: ["Classe", "classe", "Classes", "classes"], - 14: ["Race", "race", "Races", "races"], - 15: ["Compétence", "compétence", "Compétences", "compétences"], - 16: ["Statistique", "statistique", "Statistiques", "statistiques"], - 17: ["Monnaies", "monnaie", "Monnaies", "monnaies"] + 1: ["PNJ", "PNJ" , "PNJs", "PNJs"], + 2: ["Entité", "entité", "Entités", "entités"], + 3: ["Objet", "objet", "Objets", "objets"], + 4: ["Ensemble d'objets", "ensemble d'objets", "Ensembles d'objets", "ensembles d'objets"], + 5: ["Quête", "quête", "Quêtes", "quêtes"], + 6: ["Sort", "sort", "Sorts", "sorts"], + 7: ["Zone", "zone", "Zones", "zones"], + 8: ["Faction", "faction", "Factions", "factions"], + 9: ["Familier", "familier", "Familiers", "familiers"], + 10: ["Haut fait", "haut fait", "Hauts faits", "hauts faits"], + 11: ["Titre", "titre", "Titres", "titres"], + 12: ["Événement mondial", "évènement mondial", "Évènements mondiaux", "évènements mondiaux"], + 13: ["Classe", "classe", "Classes", "classes"], + 14: ["Race", "race", "Races", "races"], + 15: ["Compétence", "compétence", "Compétences", "compétences"], + 16: ["Statistique", "statistique", "Statistiques", "statistiques"], + 17: ["Monnaies", "monnaie", "Monnaies", "monnaies"], + 501: ["Emote", "emote", "Emotes", "emotes"], + 502: ["Enchantement", "enchantement", "Enchantements", "enchantements"] }, timeunitssg: ["année", "mois", "semaine", "jour", "heure", "minute", "seconde"], @@ -3857,6 +3871,18 @@ var LANG = { teamcontrib5v5: "Contribution d'un équipe d'aréna 5v5" }, + // custom + fienchantments: { + id: "ID", + hascondition: "[Requires a combination of gems]", + requiresprof: "Requiert un métier", + + sepcommunity: "Communauté", + hascomments: "A des commentaires", + hasscreenshots: "A des captures d'écrans", + hasvideos: "A des vidéos", + }, + pr_notice: 'Première fois? Ne soyez pas gêné! Visitez notre page d\'aide!   close', pr_datasource: 'Les données dans cette table ont été updatées $2 par $1.', pr_purgedata: "Cliquer pour supprimer toutes les données d'accomplissement dans l'onglet présent.
Seul l'utilisateur qui a uploadé les données peut les effacer.", diff --git a/static/js/locale_ruru.js b/static/js/locale_ruru.js index 04153054..3b8876f8 100644 --- a/static/js/locale_ruru.js +++ b/static/js/locale_ruru.js @@ -770,6 +770,16 @@ var mn_currencies = [ [1,"Разное","?currencies=22"], [2,"PvP","?currencies=2"] ]; +var mn_enchantments = [ + [1,"[Proc Spell]","?enchantments&filter=ty=1"], + [3,"[Equip Spell]","?enchantments&filter=ty=3"], + [7,"[Use Spell]","?enchantments&filter=ty=7"], + [8,"Бесцветное гнездо","?enchantments&filter=ty=8"], + [5,"Характеристики","?enchantments&filter=ty=5"], + [2,"Урон оружия","?enchantments&filter=ty=2"], + [6,"УВС","?enchantments&filter=ty=6"], + [4,"Защита","?enchantments&filter=ty=4"] +]; var mn_talentCalc = [ [6,"Рыцарь смерти","?talent#j",,{className:"c6",tinyIcon:"class_deathknight"}], [11,"Друид","?talent#0",,{className:"c11",tinyIcon:"class_druid"}], @@ -836,7 +846,8 @@ var mn_database = [ [10,"Звания","?titles",mn_titles], [11,"Игровые события","?events",mn_holidays], [6,"Местности","?zones",mn_zones], - [100,"Эмоции", "?emotes", null] + [100,"Эмоции","?emotes",null], + [101,"Улучшения","?enchantments",mn_enchantments] ]; var mn_tools = [ [0,"Расчёт талантов","?talent",mn_talentCalc], @@ -2595,6 +2606,7 @@ var LANG = { lvnote_arenateamsfound: "Команд арены: $1", lvnote_arenateamsfound2: "Команд арены: $1, подходящих: $2", lvnote_currenciesfound: "Найдено валюты: $1 (показано: $2)", + lvnote_enchantmentsfound: "Найдено улучшения: $1 (показано: $2)", lvnote_createafilter: 'Применить фильтр', lvnote_filterresults: 'Отфильтровать результаты', @@ -3166,23 +3178,25 @@ var LANG = { myaccount_purgesuccess: "Закрытые объявления успешно сброшены!", types: { - 1: ["НИП", "НИП" , "НИП", "НИП"], - 2: ["Объект", "объект", "Объекты", "объекты"], - 3: ["Предмет", "предмет", "Предметы", "предметы"], - 4: ["Комплект", "комплект", "Комплекты", "комплекты"], - 5: ["Задание", "задание", "Задания", "задание"], - 6: ["Заклинание", "заклинание", "Заклинания", "заклинания"], - 7: ["Игровая зона", "Игровая зона", "Местности", "местности"], - 8: ["Фракция", "фракция", "Фракции", "фракции"], - 9: ["Питомец", "питомец", "Питомцы", "питомцы"], - 10: ["Достижение", "достижение", "Достижения", "достижения"], - 11: ["Звание", "звание", "Звания", "звания"], - 12: ["Событие", "игровое событие", "Игровые события", "игровые события"], - 13: ["Класс", "класс", "Классы", "классы"], - 14: ["Раса", "раса", "Расы", "расы"], - 15: ["Уровень навыка", "навык", "Умения", "навыки"], - 16: ["Статистика", "характеристика", "Характеристики", "характеристики"], - 17: ["Валюта", "валюта", "Валюта", "валюта"] + 1: ["НИП", "НИП" , "НИП", "НИП"], + 2: ["Объект", "объект", "Объекты", "объекты"], + 3: ["Предмет", "предмет", "Предметы", "предметы"], + 4: ["Комплект", "комплект", "Комплекты", "комплекты"], + 5: ["Задание", "задание", "Задания", "задание"], + 6: ["Заклинание", "заклинание", "Заклинания", "заклинания"], + 7: ["Игровая зона", "Игровая зона", "Местности", "местности"], + 8: ["Фракция", "фракция", "Фракции", "фракции"], + 9: ["Питомец", "питомец", "Питомцы", "питомцы"], + 10: ["Достижение", "достижение", "Достижения", "достижения"], + 11: ["Звание", "звание", "Звания", "звания"], + 12: ["Событие", "игровое событие", "Игровые события", "игровые события"], + 13: ["Класс", "класс", "Классы", "классы"], + 14: ["Раса", "раса", "Расы", "расы"], + 15: ["Уровень навыка", "навык", "Умения", "навыки"], + 16: ["Статистика", "характеристика", "Характеристики", "характеристики"], + 17: ["Валюта", "валюта", "Валюта", "валюта"], + 501: ["Эмоция", "эмоция", "Эмоции", "эмоции"], + 502: ["Улучшение", "улучшение", "Улучшения", "улучшения"] }, timeunitssg: ["год", "месяц", "неделя", "день", "час", "минута", "секунда"], @@ -3858,6 +3872,18 @@ var LANG = { teamcontrib5v5: "Очки команды арены 5х5" }, + // custom + fienchantments: { + id: "Номер", + hascondition: "[Requires a combination of gems]", + requiresprof: "Требуется профессия", + + sepcommunity: "Сообщество", + hascomments: "Есть комментарии", + hasscreenshots: "Есть изображения", + hasvideos: "Есть видео", + }, + pr_notice: 'Первый раз? – Не стесняйтесь! Взгляните на страницу помощи!   закрыть', pr_datasource: 'Данные в этой вкладке были последний раз обновлены пользователем $1 $2.', pr_purgedata: "Нажмите, чтобы удалить все собранные данные в текущей вкладке.
Только тот, кто загрузил данные, может их удалить.", diff --git a/template/listviews/enchantment.tpl.php b/template/listviews/enchantment.tpl.php new file mode 100644 index 00000000..2527e3f8 --- /dev/null +++ b/template/listviews/enchantment.tpl.php @@ -0,0 +1,158 @@ +Listview.templates.enchantment = { + sort: [1], + searchable: 1, + filtrable: 1, + + columns: [ + { + id: 'name', + name: LANG.name, + type: 'text', + align: 'left', + value: 'name', + compute: function(enchantment, td, tr) { + var + wrapper = $WH.ce('div'); + + var a = $WH.ce('a'); + a.style.fontFamily = 'Verdana, sans-serif'; + a.href = this.getItemLink(enchantment); + + if (!enchantment.name) { + var i = $WH.ce('i'); + i.className = 'q0'; + + $WH.ae(i, $WH.ct('<' + LANG.pr_header_noname + '>')); + $WH.ae(a, i); + } + else + $WH.ae(a, $WH.ct(enchantment.name)); + + $WH.ae(wrapper, a); + + $WH.ae(td, wrapper); + }, + sortFunc: function(a, b, col) { + return $WH.strcmp(a.name, b.name); + }, + getVisibleText: function(enchantment) { + return enchantment.name || LANG.pr_header_noname; + } + }, + { + id: 'trigger', + name: LANG.types[6][2], + type: 'text', + align: 'left', + value: 'name', + width: '10%', + hidden: 1, + compute: function(enchantment, td, tr) { + if (enchantment.spells) { + var d = $WH.ce('div'); + d.style.width = (26 * Object.keys(enchantment.spells).length) + 'px'; + d.style.margin = '0 auto'; + + $.each(enchantment.spells, function (spellId, charges) { + var icon = g_spells.createIcon(spellId, 0, charges); + icon.style.cssFloat = icon.style.styleFloat = 'left'; + $WH.ae(d, icon); + }); + + $WH.ae(td, d); + } + }, + getVisibleText: function(enchantment) { + if (!enchantment.spells) + return null; // no spell + + var spellId = $(enchantment.spells).first(); + if (g_spells[spellId]) + return g_spells[spellId]['name_' + Locale.getName()]; + + return ''; // unk spell + }, + sortFunc: function(a, b, col) { + return $WH.strcmp(this.getVisibleText(a), this.getVisibleText(b)); + } + }, + { + id: 'skill', + name: LANG.skill, + type: 'text', + width: '16%', + getValue: function(enchantment) { + return enchantment.reqskillrank || 0; + }, + compute: function(enchantment, td, tr) { + if (enchantment.reqskill != null) { + var div = $WH.ce('div'); + div.className = 'small'; + + // DK is the only class in use + if (enchantment.reqskill == 776) { + var a = $WH.ce('a'); + a.className = 'q0'; + a.href = '?class=6'; + + $WH.ae(a, $WH.ct(g_chr_classes[6])); + $WH.ae(div, a); + $WH.ae(div, $WH.ce('br')); + } + + var a = $WH.ce('a'); + a.className = 'q1'; + a.href = '?skill=' + enchantment.reqskill; + + $WH.ae(a, $WH.ct(g_spell_skills[enchantment.reqskill])); + $WH.ae(div, a); + + if (enchantment.reqskillrank > 0) { + var sp = $WH.ce('span'); + + sp.className = 'q0'; + $WH.ae(sp, $WH.ct(' (' + enchantment.reqskillrank + ')')); + $WH.ae(div, sp); + } + + $WH.ae(td, div); + } + }, + getVisibleText: function(enchantment) { + var buff = ''; + if (g_spell_skills[enchantment.reqskill]) { + buff += g_spell_skills[enchantment.reqskill]; + + if (enchantment.reqskillrank > 0) { + buff += ' ' + enchantment.reqskillrank; + } + } + return buff; + }, + sortFunc: function(a, b, col) { + return $WH.strcmp(g_spell_skills[a.reqskill], g_spell_skills[b.reqskill]) || $WH.strcmp(a.reqskillrank, b.reqskillrank); + } + }, + ], + getItemLink: function(enchantment) { + return '?enchantment=' + enchantment.id; + } +} + +new Listview({ + template:'enchantment', + $v): + if ($v[0] == '$'): + echo $k.':'.substr($v, 1).','; + elseif ($v): + echo $k.":'".$v."',"; + endif; + endforeach; +?> + data: +}); diff --git a/template/pages/enchantment.tpl.php b/template/pages/enchantment.tpl.php new file mode 100644 index 00000000..b453f315 --- /dev/null +++ b/template/pages/enchantment.tpl.php @@ -0,0 +1,118 @@ +brick('header'); ?> + +
+
+
+ +brick('announcement'); + + $this->brick('pageTemplate'); + + $this->brick('infobox'); +?> + +
+ +brick('redButtons'); ?> + +

name; ?>

+ +
+ +brick('article'); ?> + + +

+ + + + + + + +activateCondition)): +?> + + + + +effects as $i => $e): +?> + + + + + +
activateCondition; ?>
+)' : '').''; + + if (isset($e['value'])): + echo '
'.Lang::spell('_value').Lang::main('colon').$e['value']; + endif; + + if (!empty($e['proc'])): + echo '
'; + + if ($e['proc'] < 0): + echo sprintf(Lang::spell('ppm'), -$e['proc']); + elseif ($e['proc'] < 100.0): + echo Lang::spell('procChance').Lang::main('colon').$e['proc'].'%'; + endif; + endif; + + echo "
\n"; + + if (!empty($e['tip'])): +?> + + + + + +'.(strpos($e['icon']['name'], '#') ? $e['icon']['name'] : sprintf('%s', $e['icon']['id'], $e['icon']['name']))."\n"; +?> + + +
+ + +
+ +

+
+ +brick('lvTabs', ['relTabs' => true]); + +$this->brick('contribute'); +?> +
+
+
+ +brick('footer'); ?> diff --git a/template/pages/enchantments.tpl.php b/template/pages/enchantments.tpl.php new file mode 100644 index 00000000..735adb3d --- /dev/null +++ b/template/pages/enchantments.tpl.php @@ -0,0 +1,76 @@ +brick('header'); +$f = $this->filter; // shorthand +?> + +
+
+
+ +brick('announcement'); + +$this->brick('pageTemplate', ['fi' => empty($f['query']) ? null : ['query' => $f['query'], 'menuItem' => 1]]); +?> + +
+
+
+
+ +
+ +
+ + + + + +
+ + +
 />
+
+ +
+
+ +
+ /> /> +
+ +
+ +
+ + +
+ +
+
+
+ + + +brick('lvTabs'); ?> + +
+
+
+ +brick('footer'); ?> diff --git a/template/pages/item.tpl.php b/template/pages/item.tpl.php index 9b710a68..1df5b188 100644 --- a/template/pages/item.tpl.php +++ b/template/pages/item.tpl.php @@ -43,8 +43,13 @@ if (!empty($this->subItems)): subItems['data'] as $k => $i): if ($k < (count($this->subItems['data']) / 2)): + $eText = []; + foreach ($i['enchantment'] as $eId => $txt): + $eText[] = ''.$txt.''; + endforeach; + echo '
  • ...'.$i['name'].''; - echo ' '.sprintf(Lang::item('_chance'), $i['chance']).'
    '.$i['enchantment'].'
  • '; + echo ' '.sprintf(Lang::item('_chance'), $i['chance']).'
    '.implode(', ', $eText).''; endif; endforeach; ?> @@ -58,8 +63,13 @@ if (!empty($this->subItems)): subItems['data'] as $k => $i): if ($k >= (count($this->subItems['data']) / 2)): + $eText = []; + foreach ($i['enchantment'] as $eId => $txt): + $eText[] = ''.$txt.''; + endforeach; + echo '
  • ...'.$i['name'].''; - echo ' '.sprintf(Lang::item('_chance'), $i['chance']).'
    '.$i['enchantment'].'
  • '; + echo ' '.sprintf(Lang::item('_chance'), $i['chance']).'
    '.implode(', ', $eText).''; endif; endforeach; ?> diff --git a/template/pages/spell.tpl.php b/template/pages/spell.tpl.php index fd58e553..ae6724b8 100644 --- a/template/pages/spell.tpl.php +++ b/template/pages/spell.tpl.php @@ -215,7 +215,7 @@ foreach ($this->effects as $i => $e):