From ee568da6ec75587d29daf8a10be0b605b92eed1a Mon Sep 17 00:00:00 2001 From: Sarjuuk Date: Wed, 29 Mar 2017 21:23:41 +0200 Subject: [PATCH] IconDB * initial implementation * this includes a complete reindexing of everything touching icons * this also means, no linking to red-rocket-site though, they index them differently --- includes/community.class.php | 1 + includes/defines.php | 1 + includes/markup.class.php | 8 +- includes/shared.php | 2 +- includes/types/achievement.class.php | 6 +- includes/types/currency.class.php | 12 +- includes/types/icon.class.php | 211 +++++++++++++ includes/types/item.class.php | 8 +- includes/types/pet.class.php | 6 +- includes/types/skill.class.php | 7 +- includes/types/spell.class.php | 11 +- includes/utilities.php | 3 + index.php | 4 +- localization/lang.class.php | 1 + localization/locale_dede.php | 5 + localization/locale_enus.php | 5 + localization/locale_eses.php | 5 + localization/locale_frfr.php | 7 +- localization/locale_ruru.php | 5 + pages/achievement.php | 2 +- pages/currency.php | 2 +- pages/event.php | 2 +- pages/genericPage.class.php | 2 + pages/icon.php | 101 +++++++ pages/icons.php | 108 +++++++ pages/item.php | 2 +- pages/spell.php | 14 +- setup/db_structure.sql | 36 ++- setup/tools/filegen/simpleImg.func.php | 8 + setup/tools/sqlGen.class.php | 64 ++-- setup/tools/sqlgen/achievement.func.php | 37 ++- setup/tools/sqlgen/currencies.func.php | 15 +- setup/tools/sqlgen/glyphproperties.func.php | 20 ++ setup/tools/sqlgen/icons.func.php | 16 +- setup/tools/sqlgen/items.func.php | 4 + setup/tools/sqlgen/pet.func.php | 4 +- setup/tools/sqlgen/skillline.func.php | 28 +- setup/tools/sqlgen/spell.func.php | 36 ++- setup/updates/1490815301_01.sql | 45 +++ static/css/aowow.css | 237 +++++++++++++++ static/js/Markup.js | 162 +++++++--- static/js/basic.js | 4 +- static/js/filters.js | 16 + static/js/global.js | 319 +++++++++++++++++++- static/js/locale_dede.js | 58 +++- static/js/locale_enus.js | 62 +++- static/js/locale_eses.js | 64 +++- static/js/locale_frfr.js | 64 +++- static/js/locale_ruru.js | 64 +++- template/pages/icon.tpl.php | 42 +++ template/pages/icons.tpl.php | 61 ++++ 51 files changed, 1796 insertions(+), 211 deletions(-) create mode 100644 includes/types/icon.class.php create mode 100644 pages/icon.php create mode 100644 pages/icons.php create mode 100644 setup/tools/sqlgen/glyphproperties.func.php create mode 100644 setup/updates/1490815301_01.sql create mode 100644 template/pages/icon.tpl.php create mode 100644 template/pages/icons.tpl.php diff --git a/includes/community.class.php b/includes/community.class.php index 03388f9a..db9ca888 100644 --- a/includes/community.class.php +++ b/includes/community.class.php @@ -124,6 +124,7 @@ class CommunityContent case TYPE_EMOTE: $obj = new EmoteList($cnd); break; case TYPE_ENCHANTMENT: $obj = new EnchantmentList($cnd); break; case TYPE_SOUND: $obj = new SoundList($cnd); break; + case TYPE_ICON: $obj = new IconList($cnd); break; default: continue; } diff --git a/includes/defines.php b/includes/defines.php index 4d9c0daa..1fb32a75 100644 --- a/includes/defines.php +++ b/includes/defines.php @@ -25,6 +25,7 @@ define('TYPE_RACE', 14); define('TYPE_SKILL', 15); define('TYPE_CURRENCY', 17); define('TYPE_SOUND', 19); +define('TYPE_ICON', 29); // internal types (not published to js) define('TYPE_USER', 500); define('TYPE_EMOTE', 501); diff --git a/includes/markup.class.php b/includes/markup.class.php index 0140b84b..b6b1d568 100644 --- a/includes/markup.class.php +++ b/includes/markup.class.php @@ -21,14 +21,15 @@ class Markup public function parseGlobalsFromText(&$jsg = []) { - if (preg_match_all('/(?text, $matches, PREG_SET_ORDER)) + if (preg_match_all('/(?text, $matches, PREG_SET_ORDER)) { foreach ($matches as $match) { if ($match[1] == 'statistic') $match[1] = 'achievement'; - - if ($match[1] == 'money') + else if ($match[1] == 'icondb') + $match[1] = 'icon'; + else if ($match[1] == 'money') { if (stripos($match[0], 'items')) { @@ -50,7 +51,6 @@ class Markup } } } - else if ($type = array_search($match[1], Util::$typeStrings)) $this->jsGlobals[$type][$match[2]] = $match[2]; } diff --git a/includes/shared.php b/includes/shared.php index 8af8fe6b..1ba7825b 100644 --- a/includes/shared.php +++ b/includes/shared.php @@ -1,6 +1,6 @@ [['si'], 'o' => 'orderInGroup ASC'], - 'si' => ['j' => ['?_icons si ON si.id = a.iconId', true], 's' => ', si.iconString'], + 'a' => [['ic'], 'o' => 'orderInGroup ASC'], + 'ic' => ['j' => ['?_icons ic ON ic.id = a.iconId', true], 's' => ', ic.name AS iconString'], 'ac' => ['j' => ['?_achievementcriteria AS `ac` ON `ac`.`refAchievementId` = `a`.`id`', true], 'g' => '`a`.`id`'] ); @@ -286,7 +286,7 @@ class AchievementListFilter extends Filter 3 => [FILTER_CR_STRING, 'reward', true ], // rewardtext 7 => [FILTER_CR_BOOLEAN, 'chainId', ], // partseries 9 => [FILTER_CR_NUMERIC, 'id', null, true], // id - 10 => [FILTER_CR_STRING, 'si.iconString', ], // icon + 10 => [FILTER_CR_STRING, 'ic.name', ], // icon 18 => [FILTER_CR_STAFFFLAG, 'flags', ], // flags 14 => [FILTER_CR_FLAG, 'cuFlags', CUSTOM_HAS_COMMENT ], // hascomments 15 => [FILTER_CR_FLAG, 'cuFlags', CUSTOM_HAS_SCREENSHOT ], // hasscreenshots diff --git a/includes/types/currency.class.php b/includes/types/currency.class.php index 346c082d..f0437552 100644 --- a/includes/types/currency.class.php +++ b/includes/types/currency.class.php @@ -13,9 +13,19 @@ class CurrencyList extends BaseType protected $queryBase = 'SELECT *, c.id AS ARRAY_KEY FROM ?_currencies c'; protected $queryOpts = array( 'c' => [['ic']], - 'ic' => ['j' => ['?_icons ic ON ic.id = c.iconId', true], 's' => ', ic.iconString'] + 'ic' => ['j' => ['?_icons ic ON ic.id = c.iconId', true], 's' => ', ic.name AS iconString'] ); + public function __construct($conditions = []) + { + parent::__construct($conditions); + + foreach ($this->iterate() as &$_curTpl) + if (!$_curTpl['iconString']) + $_curTpl['iconString'] = 'inv_misc_questionmark'; + } + + public function getListviewData() { $data = []; diff --git a/includes/types/icon.class.php b/includes/types/icon.class.php new file mode 100644 index 00000000..44df08ee --- /dev/null +++ b/includes/types/icon.class.php @@ -0,0 +1,211 @@ + '?_items', + 'nSpells' => '?_spell', + 'nAchievements' => '?_achievement', + 'nCurrencies' => '?_currencies', + 'nPets' => '?_pet' + ); + + protected $queryBase = 'SELECT ic.*, ic.id AS ARRAY_KEY FROM ?_icons ic'; + /* this works, but takes ~100x more time than i'm comfortable with .. kept as reference + protected $queryOpts = array( // 29 => TYPE_ICON + 'ic' => [['s', 'i', 'a', 'c', 'p'], 'g' => 'ic.id'], + 'i' => ['j' => ['?_items `i` ON `i`.`iconId` = `ic`.`id`', true], 's' => ', COUNT(DISTINCT `i`.`id`) AS nItems'], + 's' => ['j' => ['?_spell `s` ON `s`.`iconId` = `ic`.`id`', true], 's' => ', COUNT(DISTINCT `s`.`id`) AS nSpells'], + 'a' => ['j' => ['?_achievement `a` ON `a`.`iconId` = `ic`.`id`', true], 's' => ', COUNT(DISTINCT `a`.`id`) AS nAchievements'], + 'c' => ['j' => ['?_currencies `c` ON `c`.`iconId` = `ic`.`id`', true], 's' => ', COUNT(DISTINCT `c`.`id`) AS nCurrencies'], + 'p' => ['j' => ['?_pet `p` ON `p`.`iconId` = `ic`.`id`', true], 's' => ', COUNT(DISTINCT `p`.`id`) AS nPets'] + ); + */ + + public function __construct($conditions) + { + parent::__construct($conditions); + + if (!$this->getFoundIDs()) + return; + + foreach ($this->pseudoJoin as $var => $tbl) + { + $res = DB::Aowow()->selectCol($this->pseudoQry, $tbl, $this->getFoundIDs()); + foreach ($res as $icon => $qty) + $this->templates[$icon][$var] = $qty; + } + } + + + // use if you JUST need the name + public static function getName($id) + { + $n = DB::Aowow()->SelectRow('SELECT name FROM ?_icons 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, true), + 'icon' => $this->getField('name', true, true), + 'itemcount' => (int)$this->getField('nItems'), + 'spellcount' => (int)$this->getField('nSpells'), + 'achievementcount' => (int)$this->getField('nAchievements'), + 'npccount' => 0, // UNUSED + 'petabilitycount' => 0, // UNUSED + 'currencycount' => (int)$this->getField('nCurrencies'), + 'missionabilitycount' => 0, // UNUSED + 'buildingcount' => 0, // UNUSED + 'petcount' => (int)$this->getField('nPets'), + 'threatcount' => 0, // UNUSED + 'classcount' => 0 // class icons are hardcoeded and do not referenced in dbc + ); + } + + return $data; + } + + public function getJSGlobals($addMask = GLOBALINFO_ANY) + { + $data = []; + + foreach ($this->iterate() as $__) + $data[TYPE_ICON][$this->id] = ['name' => $this->getField('name', true, true), 'icon' => $this->getField('name', true, true)]; + + return $data; + } + + public function renderTooltip() { } +} + + +class IconListFilter extends Filter +{ + public $extraOpts = null; + + // cr => [type, field, misc, extraCol] + private $criterion2field = array( + 1 => '?_items', // items [num] + 2 => '?_spell', // spells [num] + 3 => '?_achievement', // achievements [num] + // 4 => '', // battlepets [num] + // 5 => '', // battlepetabilities [num] + 6 => '?_currencies', // currencies [num] + // 7 => '', // garrisonabilities [num] + // 8 => '', // garrisonbuildings [num] + 9 => '?_pet', // hunterpets [num] + // 10 => '', // garrisonmissionthreats [num] + 11 => '', // classes [num] + 13 => '' // used [num] + ); + private $totalUses = []; + + private function _getCnd($op, $val, $tbl) + { + switch ($op) + { + case '>': + case '>=': + case '=': + $ids = DB::Aowow()->selectCol('SELECT iconId AS ARRAY_KEY, COUNT(*) AS n FROM ?# GROUP BY iconId HAVING n '.$op.' '.$val, $tbl); + return $ids ? ['id', array_keys($ids)] : [1]; + case '<=': + if ($val) + $op = '>'; + break; + case '<': + if ($val) + $op = '>='; + break; + case '!=': + if ($val) + $op = '='; + break; + } + + $ids = DB::Aowow()->selectCol('SELECT iconId AS ARRAY_KEY, COUNT(*) AS n FROM ?# GROUP BY iconId HAVING n '.$op.' '.$val, $tbl); + return $ids ? ['id', array_keys($ids), '!'] : [1]; + } + + + protected function createSQLForCriterium(&$cr) + { + if (isset($this->criterion2field[$cr[0]])) + { + if ($cr[0] == 13 && $this->isSaneNumeric($cr[2]) && $this->int2Op($cr[1])) + { + if (!$this->totalUses) + { + foreach ($this->criterion2field as $tbl) + { + if (!$tbl) + continue; + + $res = DB::Aowow()->selectCol('SELECT iconId AS ARRAY_KEY, COUNT(*) AS n FROM ?# GROUP BY iconId', $tbl); + Util::arraySumByKey($this->totalUses, $res); + } + } + + if ($cr[1] == '=') + $cr[1] = '=='; + + $op = $cr[1]; + if ($cr[1] == '<=' && $cr[2]) + $op = '>'; + else if ($cr[1] == '<' && $cr[2]) + $op = '>='; + else if ($cr[1] == '!=' && $cr[2]) + $op = '=='; + $ids = array_filter($this->totalUses, function ($x) use ($op, $cr) { return eval('return '.$x.' '.$op.' '.$cr[2].';'); }); + + if ($cr[1] != $op) + return $ids ? ['id', array_keys($ids), '!'] : [1]; + else + return $ids ? ['id', array_keys($ids)] : ['id', array_keys($this->totalUses), '!']; + } + else if ($cr[0] == 11) + return [0]; + else if ($this->isSaneNumeric($cr[2]) && $this->int2Op($cr[1])) + return $this->_getCnd($cr[1], $cr[2], $this->criterion2field[$cr[0]]); + } + + unset($cr); + $this->error = true; + return [1]; + } + + protected function createSQLForValues() + { + $parts = []; + $_v = &$this->fiData['v']; + + //string + if (isset($_v['na'])) + if ($_ = $this->modularizeString(['name'])) + $parts[] = $_; + + return $parts; + } +} + +?> diff --git a/includes/types/item.class.php b/includes/types/item.class.php index ca157fb9..4db2efdb 100644 --- a/includes/types/item.class.php +++ b/includes/types/item.class.php @@ -27,7 +27,7 @@ class ItemList extends BaseType protected $queryBase = 'SELECT i.*, i.block AS tplBlock, i.id AS ARRAY_KEY, i.id AS id FROM ?_items i'; 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'], + 'ic' => ['j' => ['?_icons `ic` ON `ic`.`id` = `i`.`iconId`', true], 's' => ', ic.name AS 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'], @@ -715,10 +715,10 @@ class ItemList extends BaseType if (!empty($enhance['g'])) { $gems = DB::Aowow()->select(' - SELECT it.id AS ARRAY_KEY, ic.iconString, ae.*, it.gemColorMask AS colorMask + SELECT it.id AS ARRAY_KEY, ic.name AS iconString, ae.*, it.gemColorMask AS colorMask FROM ?_items it JOIN ?_itemenchantment ae ON ae.id = it.gemEnchantmentId - JOIN ?_icons ic ON ic.id = -it.displayId + JOIN ?_icons ic ON ic.id = it.iconId WHERE it.id IN (?a)', $enhance['g']); foreach ($enhance['g'] as $k => $v) @@ -1775,7 +1775,7 @@ class ItemListFilter extends Filter 59 => [FILTER_CR_NUMERIC, 'durability', null, true], // dura 104 => [FILTER_CR_STRING, 'description', true ], // flavortext 7 => [FILTER_CR_BOOLEAN, 'description_loc0', true ], // hasflavortext - 142 => [FILTER_CR_STRING, 'ic.iconString', ], // icon + 142 => [FILTER_CR_STRING, 'ic.name', ], // icon 12 => [FILTER_CR_BOOLEAN, 'itemset', ], // partofset 13 => [FILTER_CR_BOOLEAN, 'randomEnchant', ], // randomlyenchanted 14 => [FILTER_CR_BOOLEAN, 'pageTextId', ], // readable diff --git a/includes/types/pet.class.php b/includes/types/pet.class.php index d3a6cb70..0b27cd2e 100644 --- a/includes/types/pet.class.php +++ b/includes/types/pet.class.php @@ -12,7 +12,11 @@ class PetList extends BaseType public static $brickFile = 'pet'; public static $dataTable = '?_pet'; - protected $queryBase = 'SELECT *, id AS ARRAY_KEY FROM ?_pet p'; + protected $queryBase = 'SELECT *, p.id AS ARRAY_KEY FROM ?_pet p'; + protected $queryOpts = array( + 'p' => [['ic']], + 'ic' => ['j' => ['?_icons ic ON p.iconId = ic.id', true], 's' => ', ic.name AS iconString'], + ); public function getListviewData() { diff --git a/includes/types/skill.class.php b/includes/types/skill.class.php index 4b467a9f..6f095a0a 100644 --- a/includes/types/skill.class.php +++ b/includes/types/skill.class.php @@ -12,8 +12,8 @@ class SkillList extends BaseType protected $queryBase = 'SELECT *, sl.id AS ARRAY_KEY FROM ?_skillline sl'; protected $queryOpts = array( - 'sl' => [['si']], - 'si' => ['j' => '?_icons si ON si.id = sl.iconId', 's' => ', si.iconString'], + 'sl' => [['ic']], + 'ic' => ['j' => ['?_icons ic ON ic.id = sl.iconId', true], 's' => ', ic.name AS iconString'], ); public function __construct($conditions = []) @@ -32,6 +32,9 @@ class SkillList extends BaseType while (count($_) < 5) $_[] = 0; } + + if (!$_curTpl['iconId']) + $_curTpl['iconString'] = 'inv_misc_questionmark'; } } diff --git a/includes/types/spell.class.php b/includes/types/spell.class.php index 0f187d13..486227aa 100644 --- a/includes/types/spell.class.php +++ b/includes/types/spell.class.php @@ -53,9 +53,9 @@ class SpellList extends BaseType protected $queryBase = 'SELECT s.*, s.id AS ARRAY_KEY FROM ?_spell s'; protected $queryOpts = array( - 's' => [['src', 'sr', 'si', 'si', 'sia']], // 6: TYPE_SPELL - 'si' => ['j' => ['?_icons si ON si.id = s.iconId', true], 's' => ', IFNULL (si.iconString, "inv_misc_questionmark") AS iconString'], - 'sia' => ['j' => ['?_icons sia ON sia.id = s.iconIdAlt', true], 's' => ', sia.iconString AS iconStringAlt'], + 's' => [['src', 'sr', 'ic', 'ica']], // 6: TYPE_SPELL + 'ic' => ['j' => ['?_icons ic ON ic.id = s.iconId', true], 's' => ', ic.name AS iconString'], + 'ica' => ['j' => ['?_icons ica ON ica.id = s.iconIdAlt', true], 's' => ', ica.name AS iconStringAlt'], 'sr' => ['j' => ['?_spellrange sr ON sr.id = s.rangeId'], 's' => ', sr.rangeMinHostile, sr.rangeMinFriend, sr.rangeMaxHostile, sr.rangeMaxFriend, sr.name_loc0 AS rangeText_loc0, sr.name_loc2 AS rangeText_loc2, sr.name_loc3 AS rangeText_loc3, sr.name_loc6 AS rangeText_loc6, sr.name_loc8 AS rangeText_loc8'], 'src' => ['j' => ['?_source src ON type = 6 AND typeId = s.id', true], 's' => ', src1, src2, src3, src4, src5, src6, src7, src8, src9, src10, src11, src12, src13, src14, src15, src16, src17, src18, src19, src20, src21, src22, src23, src24'] ); @@ -125,6 +125,9 @@ class SpellList extends BaseType unset($_curTpl['skillLine1']); unset($_curTpl['skillLine2OrMask']); + + if (!$_curTpl['iconString']) + $_curTpl['iconString'] = 'inv_misc_questionmark'; } if ($foo) @@ -2163,7 +2166,7 @@ class SpellListFilter extends Filter 12 => [FILTER_CR_FLAG, 'cuFlags', SPELL_CU_LAST_RANK ], // lastrank 13 => [FILTER_CR_NUMERIC, 'rankNo', ], // rankno 14 => [FILTER_CR_NUMERIC, 'id', null, true], // id - 15 => [FILTER_CR_STRING, 'si.iconString', ], // icon + 15 => [FILTER_CR_STRING, 'ic.name', ], // icon 19 => [FILTER_CR_FLAG, 'attributes0', 0x80000 ], // scaling 25 => [FILTER_CR_BOOLEAN, 'skillLevelYellow' ], // rewardsskillups 11 => [FILTER_CR_FLAG, 'cuFlags', CUSTOM_HAS_COMMENT ], // hascomments diff --git a/includes/utilities.php b/includes/utilities.php index 2c937515..0efe3dbd 100644 --- a/includes/utilities.php +++ b/includes/utilities.php @@ -40,6 +40,7 @@ class Util null, 'CreatureList', 'GameObjectList', 'ItemList', 'ItemsetList', 'QuestList', 'SpellList', 'ZoneList', 'FactionList', 'PetList', 'AchievementList', 'TitleList', 'WorldEventList', 'CharClassList', 'CharRaceList', 'SkillList', null, 'CurrencyList', null, 'SoundList', + TYPE_ICON => 'IconList', TYPE_EMOTE => 'EmoteList', TYPE_ENCHANTMENT => 'EnchantmentList' ); @@ -48,6 +49,7 @@ class Util null, 'npc', 'object', 'item', 'itemset', 'quest', 'spell', 'zone', 'faction', 'pet', 'achievement', 'title', 'event', 'class', 'race', 'skill', null, 'currency', null, 'sound', + TYPE_ICON => 'icon', TYPE_USER => 'user', TYPE_EMOTE => 'emote', TYPE_ENCHANTMENT => 'enchantment' @@ -195,6 +197,7 @@ class Util public static $filterResultString = '$$WH.sprintf(LANG.lvnote_filterresults, \'%s\')'; public static $tryFilteringString = '$$WH.sprintf(%s, %s, %s) + LANG.dash + LANG.lvnote_tryfiltering.replace(\'\', \'\')'; + public static $tryFilteringEntityString = '$$WH.sprintf(LANG.lvnote_entitiesfound, %s, %s, %s) + LANG.dash + LANG.lvnote_tryfiltering.replace(\'\', \'\')'; public static $tryNarrowingString = '$$WH.sprintf(%s, %s, %s) + LANG.dash + LANG.lvnote_trynarrowing'; public static $setCriteriaString = "fi_setCriteria(%s, %s, %s);\n"; diff --git a/index.php b/index.php index 75a50795..8fb9ca48 100644 --- a/index.php +++ b/index.php @@ -39,6 +39,8 @@ switch ($pageCall) case 'factions': // case 'guild': // case 'guilds': + case 'icon': + case 'icons': case 'item': case 'items': case 'itemset': @@ -64,7 +66,7 @@ switch ($pageCall) case 'search': // tool: searches case 'skill': case 'skills': - case 'sound': // db: sounds for zone, creature, spell, ... + case 'sound': case 'sounds': case 'spell': case 'spells': diff --git a/localization/lang.class.php b/localization/lang.class.php index 6d9f55cd..2fceae55 100644 --- a/localization/lang.class.php +++ b/localization/lang.class.php @@ -19,6 +19,7 @@ class Lang private static $event; private static $faction; private static $gameObject; + private static $icon; private static $item; private static $itemset; private static $npc; diff --git a/localization/locale_dede.php b/localization/locale_dede.php index 45436e31..3e55f999 100644 --- a/localization/locale_dede.php +++ b/localization/locale_dede.php @@ -202,6 +202,8 @@ $lang = array( 'faction' => "Fraktion", 'factions' => "Fraktionen", 'cooldown' => "%s Abklingzeit", + 'icon' => "Icon", + 'icons' => "Icons", 'item' => "Gegenstand", 'items' => "Gegenstände", 'itemset' => "Ausrüstungsset", @@ -682,6 +684,9 @@ $lang = array( -2 => "Nicht kategorisiert" ) ), + 'icon' => array( + 'notFound' => "Dieses Icon existiert nicht." + ), 'title' => array( 'notFound' => "Dieser Titel existiert nicht.", '_transfer' => 'Dieser Titel wird mit %s vertauscht, wenn Ihr zur %s wechselt.', diff --git a/localization/locale_enus.php b/localization/locale_enus.php index 9a795f9f..b5819fe6 100644 --- a/localization/locale_enus.php +++ b/localization/locale_enus.php @@ -197,6 +197,8 @@ $lang = array( 'faction' => "faction", 'factions' => "Factions", 'cooldown' => "%s cooldown", + 'icon' => "icon", + 'icons' => "icons", 'item' => "item", 'items' => "Items", 'itemset' => "item Set", @@ -677,6 +679,9 @@ $lang = array( -2 => "Uncategorized" ) ), + 'icon' => array( + 'notFound' => "This icon doesn't exist." + ), 'title' => array( 'notFound' => "This title doesn't exist.", '_transfer' => 'This title will be converted to %s if you transfer to %s.', diff --git a/localization/locale_eses.php b/localization/locale_eses.php index 871d749e..053e1a7e 100644 --- a/localization/locale_eses.php +++ b/localization/locale_eses.php @@ -202,6 +202,8 @@ $lang = array( 'faction' => "facción", 'factions' => "Facciones", 'cooldown' => "%s de reutilización", + 'icon' => "icono", + 'icons' => "Iconos", 'item' => "objeto", 'items' => "Objetos", 'itemset' => "conjunto de objetos", @@ -683,6 +685,9 @@ $lang = array( -2 => "Sin categoría" ) ), + 'icon' => array( + 'notFound' => "Este icono no existe." + ), 'title' => array( 'notFound' => "Este título no existe.", '_transfer' => 'Este título será convertido a %s si lo transfieres a la %s.', diff --git a/localization/locale_frfr.php b/localization/locale_frfr.php index e3f0879f..6ce2d531 100644 --- a/localization/locale_frfr.php +++ b/localization/locale_frfr.php @@ -202,6 +202,8 @@ $lang = array( 'faction' => "faction", 'factions' => "Factions", 'cooldown' => "%s de recharge", + 'icon' => "icône", + 'icons' => "Icônes", 'item' => "objet", 'items' => "Objets", 'itemset' => "ensemble d'objets", @@ -375,7 +377,7 @@ $lang = array( 'newPassDiff' => "Votre nouveau mot de passe doit être différent de l'ancien." // message_newpassdifferent ), 'user' => array( - 'notFound' => "Utilisateur \"%s\" non trouvé !", + 'notFound' => "Utilisateur \"%s\" non trouvé!", 'removed' => "(Supprimé)", 'joinDate' => "Inscription", 'lastLogin' => "Dernière visite", @@ -681,6 +683,9 @@ $lang = array( -2 => "Non classés" ) ), + 'icon' => array( + 'notFound' => "Cette icône n'existe pas." + ), 'title' => array( 'notFound' => "Ce titre n'existe pas.", '_transfer' => 'Ce titre sera converti en %s si vous transférez en %s.', diff --git a/localization/locale_ruru.php b/localization/locale_ruru.php index a778501c..69e6b1f8 100644 --- a/localization/locale_ruru.php +++ b/localization/locale_ruru.php @@ -202,6 +202,8 @@ $lang = array( 'faction' => "фракция", 'factions' => "Фракции", 'cooldown' => "Восстановление: %s", + 'icon' => "иконка", + 'icons' => "Иконки", 'item' => "предмет", 'items' => "Предметы", 'itemset' => "комплект", @@ -682,6 +684,9 @@ $lang = array( -2 => "Разное" ) ), + 'icon' => array( + 'notFound' => "Этой иконки не существует" + ), 'title' => array( 'notFound' => "Такое звание не существует.", '_transfer' => 'Этот предмет превратится в %s, если вы перейдете за %s.', diff --git a/pages/achievement.php b/pages/achievement.php index 20616950..b0f7e746 100644 --- a/pages/achievement.php +++ b/pages/achievement.php @@ -523,7 +523,7 @@ class AchievementPage extends GenericPage $x = '$WowheadPower.registerAchievement('.$this->typeId.', '.User::$localeId.",{\n"; $x .= "\tname_".User::$localeString.": '".Util::jsEscape($this->subject->getField('name', true))."',\n"; - $x .= "\ticon: '".urlencode($this->subject->getField('iconString'))."',\n"; + $x .= "\ticon: '".rawurlencode($this->subject->getField('iconString', true, true))."',\n"; $x .= "\ttooltip_".User::$localeString.": '".$this->subject->renderTooltip()."'\n"; $x .= "});"; diff --git a/pages/currency.php b/pages/currency.php index e8092c19..47512df2 100644 --- a/pages/currency.php +++ b/pages/currency.php @@ -218,7 +218,7 @@ class CurrencyPage extends GenericPage $x = '$WowheadPower.registerCurrency('.$this->typeId.', '.User::$localeId.", {\n"; $x .= "\tname_".User::$localeString.": '".Util::jsEscape($this->subject->getField('name', true))."',\n"; - $x .= "\ticon: '".urlencode($this->subject->getField('iconString'))."',\n"; + $x .= "\ticon: '".rawurlencode($this->subject->getField('iconString', true, true))."',\n"; $x .= "\ttooltip_".User::$localeString.": '".$this->subject->renderTooltip()."'\n"; $x .= "});"; diff --git a/pages/event.php b/pages/event.php index 93eae6ec..66b17f75 100644 --- a/pages/event.php +++ b/pages/event.php @@ -336,7 +336,7 @@ class EventPage extends GenericPage $x .= "\tname_".User::$localeString.": '".Util::jsEscape($this->subject->getField('name', true))."',\n"; if ($this->subject->getField('iconString') != 'trade_engineering') - $x .= "\ticon: '".urlencode($this->subject->getField('iconString'))."',\n"; + $x .= "\ticon: '".rawurlencode($this->subject->getField('iconString', true, true))."',\n"; $x .= "\ttooltip_".User::$localeString.": '".$this->subject->renderTooltip()."'\n"; $x .= "});"; diff --git a/pages/genericPage.class.php b/pages/genericPage.class.php index ba15d610..7f4e31e9 100644 --- a/pages/genericPage.class.php +++ b/pages/genericPage.class.php @@ -120,6 +120,7 @@ class GenericPage 'event' => ['template' => 'holiday', 'id' => 'holidays', 'parent' => 'lv-generic', 'data' => [], 'name' => '$LANG.tab_holidays' ], 'faction' => ['template' => 'faction', 'id' => 'factions', 'parent' => 'lv-generic', 'data' => [], 'name' => '$LANG.tab_factions' ], 'genericmodel' => ['template' => 'genericmodel', 'id' => 'same-model-as', 'parent' => 'lv-generic', 'data' => [], 'name' => '$LANG.tab_samemodelas' ], + 'icongallery' => ['template' => 'icongallery', 'id' => 'icons', 'parent' => 'lv-generic', 'data' => [] ], 'item' => ['template' => 'item', 'id' => 'items', 'parent' => 'lv-generic', 'data' => [], 'name' => '$LANG.tab_items' ], 'itemset' => ['template' => 'itemset', 'id' => 'itemsets', 'parent' => 'lv-generic', 'data' => [], 'name' => '$LANG.tab_itemsets' ], 'model' => ['template' => 'model', 'id' => 'gallery', 'parent' => 'lv-generic', 'data' => [], 'name' => '$LANG.tab_gallery' ], @@ -696,6 +697,7 @@ class GenericPage case TYPE_SKILL: $jsg[TYPE_SKILL] = ['g_skills', [], []]; break; case TYPE_CURRENCY: $jsg[TYPE_CURRENCY] = ['g_gatheredcurrencies', [], []]; break; case TYPE_SOUND: $jsg[TYPE_SOUND] = ['g_sounds', [], []]; break; + case TYPE_ICON: $jsg[TYPE_ICON] = ['g_icons', [], []]; break; // well, this is awkward case TYPE_USER: $jsg[TYPE_USER] = ['g_users', [], []]; break; case TYPE_EMOTE: $jsg[TYPE_EMOTE] = ['g_emotes', [], []]; break; diff --git a/pages/icon.php b/pages/icon.php new file mode 100644 index 00000000..2bc67e7e --- /dev/null +++ b/pages/icon.php @@ -0,0 +1,101 @@ +typeId = intVal($id); + + $this->subject = new IconList(array(['id', $this->typeId])); + if ($this->subject->error) + $this->notFound(Util::ucFirst(Lang::game('icon')), Lang::icon('notFound')); + + $this->extendGlobalData($this->subject->getJSGlobals()); + + $this->name = Util::ucFirst($this->subject->getField('name')); + $this->icon = $this->subject->getField('name', true, true); + } + + protected function generateContent() + { + /****************/ + /* Main Content */ + /****************/ + + $this->redButtons = array( + BUTTON_LINKS => ['type' => $this->type, 'typeId' => $this->typeId], + BUTTON_WOWHEAD => false + ); + + + /**************/ + /* Extra Tabs */ + /**************/ + + // used by: spell + $ubSpells = new SpellList(array(['iconId', $this->typeId])); + if (!$ubSpells->error) + { + $this->extendGlobalData($ubSpells->getJsGlobals()); + $this->lvTabs[] = [SpellList::$brickFile, ['data' => array_values($ubSpells->getListviewData())]]; + } + + // used by: item + $ubItems = new ItemList(array(['iconId', $this->typeId])); + if (!$ubItems->error) + { + $this->extendGlobalData($ubItems->getJsGlobals()); + $this->lvTabs[] = [ItemList::$brickFile, ['data' =>array_values( $ubItems->getListviewData())]]; + } + + // used by: achievement + $ubAchievements = new AchievementList(array(['iconId', $this->typeId])); + if (!$ubAchievements->error) + { + $this->extendGlobalData($ubAchievements->getJsGlobals()); + $this->lvTabs[] = [AchievementList::$brickFile, ['data' => array_values($ubAchievements->getListviewData())]]; + } + + // used by: currency + $ubCurrencies = new CurrencyList(array(['iconId', $this->typeId])); + if (!$ubCurrencies->error) + { + $this->extendGlobalData($ubCurrencies->getJsGlobals()); + $this->lvTabs[] = [CurrencyList::$brickFile, ['data' => array_values($ubCurrencies->getListviewData())]]; + } + + // used by: hunter pet + $ubPets = new PetList(array(['iconId', $this->typeId])); + if (!$ubPets->error) + { + $this->extendGlobalData($ubPets->getJsGlobals()); + $this->lvTabs[] = [PetList::$brickFile, ['data' => array_values($ubPets->getListviewData())]]; + } + } + + protected function generateTitle() + { + array_unshift($this->title, $this->name, Util::ucFirst(Lang::game('icon'))); + } + + protected function generatePath() { } +} + +?> diff --git a/pages/icons.php b/pages/icons.php new file mode 100644 index 00000000..cbd5991d --- /dev/null +++ b/pages/icons.php @@ -0,0 +1,108 @@ +filterObj = new IconListFilter(); + $this->getCategoryFromUrl($pageParam);; + + parent::__construct($pageCall, $pageParam); + + $this->name = Util::ucFirst(Lang::game('icons')); + } + + protected function generateContent() + { + $tabData = array( + 'data' => [], + ); + + $sqlLimit = 600; // fits better onto the grid + + $conditions = [$sqlLimit]; + + if (!User::isInGroup(U_GROUP_EMPLOYEE)) + $conditions[] = [['cuFlags', CUSTOM_EXCLUDE_FOR_LISTVIEW, '&'], 0]; + + if ($_ = $this->filterObj->getConditions()) + $conditions[] = $_; + + $icons = new IconList($conditions); + + $tabData['data'] = array_values($icons->getListviewData()); + $this->extendGlobalData($icons->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(); + + if ($icons->getMatches() > $sqlLimit) + { + $tabData['note'] = sprintf(Util::$tryFilteringEntityString, $icons->getMatches(), 'LANG.types[29][3]', $sqlLimit); + $tabData['_truncated'] = 1; + } + + if ($this->filterObj->error) + $tabData['_errors'] = '$1'; + + $this->lvTabs[] = ['icongallery', $tabData]; + } + + protected function generateTitle() + { + $setCrt = $this->filterObj->getForm('setCriteria', true); + $title = $this->name; + if (isset($setCrt['cr']) && count($setCrt['cr']) == 1) + { + switch ($setCrt['cr'][0]) + { + case 1: + $title = Util::ucFirst(Lang::game('item')).' '.$title; + break; + case 2: + $title = Util::ucFirst(Lang::game('spell')).' '.$title; + break; + case 3: + $title = Util::ucFirst(Lang::game('achievement')).' '.$title; + break; + case 6: + $title = Util::ucFirst(Lang::game('currency')).' '.$title; + break; + case 9: + $title = Util::ucFirst(Lang::game('pet')).' '.$title; + break; + case 11: + $title = Util::ucFirst(Lang::game('class')).' '.$title; + break; + } + } + + array_unshift($this->title, $title); + } + + protected function generatePath() + { + $setCrt = $this->filterObj->getForm('setCriteria', true); + if (isset($setCrt['cr']) && count($setCrt['cr']) == 1) + $this->path[] = $setCrt['cr'][0]; + } +} + +?> diff --git a/pages/item.php b/pages/item.php index 7dfc2b5c..4ee0c4c1 100644 --- a/pages/item.php +++ b/pages/item.php @@ -1010,7 +1010,7 @@ class ItemPage extends genericPage $x = '$WowheadPower.registerItem(\''.$itemString.'\', '.User::$localeId.", {\n"; $x .= "\tname_".User::$localeString.": '".Util::jsEscape($this->subject->getField('name', true, $this->enhancedTT))."',\n"; $x .= "\tquality: ".$this->subject->getField('quality').",\n"; - $x .= "\ticon: '".urlencode($this->subject->getField('iconString'))."',\n"; + $x .= "\ticon: '".rawurlencode($this->subject->getField('iconString', true, true))."',\n"; $x .= "\ttooltip_".User::$localeString.": '".Util::jsEscape($this->subject->renderTooltip(false, 0, $this->enhancedTT))."'\n"; $x .= "});"; diff --git a/pages/spell.php b/pages/spell.php index c2e0ed6b..3fcc82ea 100644 --- a/pages/spell.php +++ b/pages/spell.php @@ -247,7 +247,7 @@ class SpellPage extends GenericPage if ($this->subject->getField('effect'.$i.'Id') == 74) $glyphId = $this->subject->getField('effect'.$i.'MiscValue'); - if ($_ = DB::Aowow()->selectCell('SELECT si.iconString FROM ?_glyphproperties gp JOIN ?_icons si ON gp.iconId = si.id WHERE gp.spellId = ?d { OR gp.id = ?d }', $this->typeId, $glyphId ?: DBSIMPLE_SKIP)) + if ($_ = DB::Aowow()->selectCell('SELECT ic.name FROM ?_glyphproperties gp JOIN ?_icons ic ON gp.iconId = ic.id WHERE gp.spellId = ?d { OR gp.id = ?d }', $this->typeId, $glyphId ?: DBSIMPLE_SKIP)) if (file_exists('static/images/wow/Interface/Spellbook/'.$_.'.png')) $infobox .= '[img src='.STATIC_URL.'/images/wow/Interface/Spellbook/'.$_.'.png border=0 float=center margin=15]'; @@ -1138,8 +1138,8 @@ class SpellPage extends GenericPage $pt = []; if ($n = $this->subject->getField('name', true)) $pt[] = "\tname_".User::$localeString.": '".Util::jsEscape($n)."'"; - if ($i = $this->subject->getField('iconString')) - $pt[] = "\ticon: '".urlencode($i)."'"; + if ($i = $this->subject->getField('iconString', true, true)) + $pt[] = "\ticon: '".rawurlencode($i)."'"; if ($tt = $this->subject->renderTooltip()) { $pt[] = "\ttooltip_".User::$localeString.": '".Util::jsEscape($tt[0])."'"; @@ -1186,14 +1186,14 @@ class SpellPage extends GenericPage return false; $item = DB::Aowow()->selectRow(' - SELECT name_loc0, name_loc2, name_loc3, name_loc6, name_loc8, i.id, ic.iconString, quality, + SELECT name_loc0, name_loc2, name_loc3, name_loc6, name_loc8, i.id, ic.name AS iconString, quality, IF ( (spellId1 > 0 AND spellCharges1 < 0) OR (spellId2 > 0 AND spellCharges2 < 0) OR (spellId3 > 0 AND spellCharges3 < 0) OR (spellId4 > 0 AND spellCharges4 < 0) OR (spellId5 > 0 AND spellCharges5 < 0), 1, 0) AS consumed FROM ?_items i - LEFT JOIN ?_icons ic ON ic.id = i.displayId + LEFT JOIN ?_icons ic ON ic.id = i.iconId WHERE i.id = ?d', $_iId ); @@ -1238,9 +1238,9 @@ class SpellPage extends GenericPage SELECT reagent1, reagent2, reagent3, reagent4, reagent5, reagent6, reagent7, reagent8, reagentCount1, reagentCount2, reagentCount3, reagentCount4, reagentCount5, reagentCount6, reagentCount7, reagentCount8, name_loc0, name_loc2, name_loc3, name_loc6, name_loc8, - s.id AS ARRAY_KEY, iconString + s.id AS ARRAY_KEY, ic.name AS iconString FROM ?_spell s - JOIN ?_icons si ON iconId = si.id + JOIN ?_icons ic ON s.iconId = ic.id WHERE (effect1CreateItemId = ?d AND effect1Id = 24)',// OR // (effect2CreateItemId = ?d AND effect2Id = 24) OR // (effect3CreateItemId = ?d AND effect3Id = 24)', diff --git a/setup/db_structure.sql b/setup/db_structure.sql index b7b613be..20d3f8f6 100644 --- a/setup/db_structure.sql +++ b/setup/db_structure.sql @@ -177,7 +177,8 @@ CREATE TABLE `aowow_achievement` ( `parentCat` smallint(6) NOT NULL, `points` tinyint(3) unsigned NOT NULL, `orderInGroup` tinyint(3) unsigned NOT NULL, - `iconId` mediumint(8) unsigned NOT NULL, + `iconId` smallint(5) unsigned NOT NULL DEFAULT '0', + `iconIdBak` smallint(5) unsigned NOT NULL DEFAULT '0', `flags` smallint(5) unsigned NOT NULL, `reqCriteriaCount` tinyint(3) unsigned NOT NULL, `refAchievement` smallint(5) unsigned NOT NULL, @@ -198,7 +199,8 @@ CREATE TABLE `aowow_achievement` ( `reward_loc3` varchar(92) NOT NULL, `reward_loc6` varchar(83) NOT NULL, `reward_loc8` varchar(95) NOT NULL, - PRIMARY KEY (`id`) + PRIMARY KEY (`id`), + KEY `iconId` (`iconId`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; /*!40101 SET character_set_client = @saved_cs_client */; @@ -540,7 +542,7 @@ CREATE TABLE `aowow_currencies` ( `id` int(16) NOT NULL, `category` mediumint(8) NOT NULL, `cuFlags` int(10) unsigned NOT NULL, - `iconId` mediumint(9) NOT NULL, + `iconId` smallint(5) unsigned NOT NULL DEFAULT '0', `itemId` int(16) NOT NULL, `cap` mediumint(8) unsigned NOT NULL, `name_loc0` varchar(64) NOT NULL, @@ -553,7 +555,8 @@ CREATE TABLE `aowow_currencies` ( `description_loc3` varchar(256) NOT NULL, `description_loc6` varchar(256) NOT NULL, `description_loc8` varchar(256) NOT NULL, - PRIMARY KEY (`id`) + PRIMARY KEY (`id`), + KEY `iconId` (`iconId`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; /*!40101 SET character_set_client = @saved_cs_client */; @@ -716,7 +719,8 @@ CREATE TABLE `aowow_glyphproperties` ( `id` smallint(5) unsigned NOT NULL, `spellId` mediumint(11) unsigned NOT NULL, `typeFlags` tinyint(3) unsigned NOT NULL, - `iconId` smallint(5) unsigned NOT NULL, + `iconId` smallint(5) unsigned NOT NULL DEFAULT '0', + `iconIdBak` smallint(5) unsigned NOT NULL DEFAULT '0', PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; /*!40101 SET character_set_client = @saved_cs_client */; @@ -1146,6 +1150,7 @@ CREATE TABLE `aowow_items` ( `name_loc3` varchar(127) DEFAULT NULL, `name_loc6` varchar(127) DEFAULT NULL, `name_loc8` varchar(127) DEFAULT NULL, + `iconId` smallint(5) unsigned NOT NULL DEFAULT '0', `displayId` mediumint(8) unsigned NOT NULL DEFAULT '0', `spellVisualId` smallint(5) unsigned NOT NULL DEFAULT '0', `quality` tinyint(3) unsigned NOT NULL DEFAULT '0', @@ -1293,7 +1298,8 @@ CREATE TABLE `aowow_items` ( KEY `idx_name` (`name_loc0`), KEY `items_index` (`class`), KEY `idx_model` (`displayId`), - KEY `idx_faction` (`requiredFaction`) + KEY `idx_faction` (`requiredFaction`). + KEY `iconId` (`iconId`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; /*!40101 SET character_set_client = @saved_cs_client */; @@ -1488,7 +1494,7 @@ CREATE TABLE `aowow_pet` ( `name_loc3` varchar(64) NOT NULL, `name_loc6` varchar(64) NOT NULL, `name_loc8` varchar(64) NOT NULL, - `iconString` varchar(128) NOT NULL, + `iconId` smallint(5) unsigned NOT NULL DEFAULT '0', `skillLineId` mediumint(9) NOT NULL, `spellId1` mediumint(9) NOT NULL, `spellId2` mediumint(9) NOT NULL, @@ -1497,7 +1503,8 @@ CREATE TABLE `aowow_pet` ( `armor` mediumint(9) NOT NULL, `damage` mediumint(9) NOT NULL, `health` mediumint(9) NOT NULL, - PRIMARY KEY (`id`) + PRIMARY KEY (`id`), + KEY `iconId` (`iconId`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; /*!40101 SET character_set_client = @saved_cs_client */; @@ -1891,7 +1898,8 @@ CREATE TABLE `aowow_skillline` ( `description_loc3` text NOT NULL, `description_loc6` text NOT NULL, `description_loc8` text NOT NULL, - `iconId` smallint(5) unsigned NOT NULL, + `iconId` smallint(5) unsigned NOT NULL DEFAULT '0', + `iconIdBak` smallint(5) unsigned NOT NULL DEFAULT '0', `professionMask` smallint(5) unsigned NOT NULL, `recipeSubClass` tinyint(3) unsigned NOT NULL, `specializations` varchar(30) NOT NULL COMMENT 'space-separated spellIds', @@ -2126,8 +2134,9 @@ CREATE TABLE `aowow_spell` ( `effect1BonusMultiplier` float NOT NULL, `effect2BonusMultiplier` float NOT NULL, `effect3BonusMultiplier` float NOT NULL, - `iconId` smallint(5) unsigned NOT NULL, - `iconIdAlt` mediumint(9) NOT NULL, + `iconId` smallint(5) unsigned NOT NULL DEFAULT '0', + `iconIdBak` smallint(5) unsigned NOT NULL DEFAULT '0', + `iconIdAlt` smallint(5) unsigned NOT NULL DEFAULT '0', `rankNo` tinyint(3) unsigned NOT NULL, `spellVisualId` smallint(5) unsigned NOT NULL, `name_loc0` varchar(85) NOT NULL, @@ -2173,7 +2182,8 @@ CREATE TABLE `aowow_spell` ( KEY `category` (`typeCat`), KEY `spell` (`id`) USING BTREE, KEY `effects` (`effect1Id`,`effect2Id`,`effect3Id`), - KEY `items` (`effect1CreateItemId`,`effect2CreateItemId`,`effect3CreateItemId`) + KEY `items` (`effect1CreateItemId`,`effect2CreateItemId`,`effect3CreateItemId`), + KEY `iconId` (`iconId`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; /*!40101 SET character_set_client = @saved_cs_client */; @@ -2656,7 +2666,7 @@ UNLOCK TABLES; LOCK TABLES `aowow_dbversion` WRITE; /*!40000 ALTER TABLE `aowow_dbversion` DISABLE KEYS */; -INSERT INTO `aowow_dbversion` VALUES (1490789226,0,NULL,NULL); +INSERT INTO `aowow_dbversion` VALUES (1490815302,0,NULL,NULL); /*!40000 ALTER TABLE `aowow_dbversion` ENABLE KEYS */; UNLOCK TABLES; diff --git a/setup/tools/filegen/simpleImg.func.php b/setup/tools/filegen/simpleImg.func.php index 95ec1db7..0c05d070 100644 --- a/setup/tools/filegen/simpleImg.func.php +++ b/setup/tools/filegen/simpleImg.func.php @@ -450,6 +450,14 @@ if (!CLI) if ($missing = array_diff(array_map('strtolower', $dbcEntries), array_map('strtolower', $allPaths))) { + // hide affected icons from listviews + $iconNames = array_map(function($path) { + preg_match('/\/([^\/]+)\.blp$/i', $path, $m); + return $m ? $m[1] : null; + }, $missing); + var_dump($iconNames); + DB::Aowow()->query('UPDATE ?_icons SET cuFlags = cuFlags | ?d WHERE name IN (?a)', CUSTOM_EXCLUDE_FOR_LISTVIEW, $iconNames); + asort($missing); CLISetup::log('the following '.count($missing).' images where referenced by DBC but not in the mpqData directory. They may need to be converted by hand later on.', CLISetup::LOG_WARN); foreach ($missing as $m) diff --git a/setup/tools/sqlGen.class.php b/setup/tools/sqlGen.class.php index 4946017d..0a97b7f9 100644 --- a/setup/tools/sqlGen.class.php +++ b/setup/tools/sqlGen.class.php @@ -28,7 +28,6 @@ class SqlGen private static $tables = array( // [dbcName, saveDbc, AowowDeps, TCDeps] 'achievementcategory' => ['achievement_category', false, null, null], 'achievementcriteria' => ['achievement_criteria', false, null, null], - 'glyphproperties' => ['glyphproperties', true, null, null], 'itemenchantmentcondition' => ['spellitemenchantmentcondition', false, null, null], 'itemextendedcost' => ['itemextendedcost', false, null, null], 'itemlimitcategory' => ['itemlimitcategory', false, null, null], @@ -41,37 +40,38 @@ class SqlGen 'spellrange' => ['spellrange', false, null, null], 'spellvariables' => ['spelldescriptionvariables', false, null, null], 'totemcategory' => ['totemcategory', false, null, null], - 'talents' => [null, null, null, null], - 'classes' => [null, null, null, null], - 'factions' => [null, null, null, null], - 'factiontemplate' => [null, null, null, null], - 'holidays' => [null, null, null, null], - 'icons' => [null, null, null, null], - 'itemrandomenchant' => [null, null, null, null], - 'races' => [null, null, null, null], - 'shapeshiftforms' => [null, null, null, null], - 'skillline' => [null, null, null, null], - 'emotes' => [null, null, null, null], - 'sounds' => [null, null, null, null], - 'itemenchantment' => [null, null, null, ['spell_enchant_proc_data']], - 'achievement' => [null, null, null, ['dbc_achievement', 'disables']], - 'creature' => [null, null, null, ['creature_template', 'creature_template_locale', 'creature_classlevelstats', 'instance_encounters']], - 'currencies' => [null, null, null, ['item_template', 'locales_item']], - 'events' => [null, null, null, ['game_event', 'game_event_prerequisite']], - 'objects' => [null, null, null, ['gameobject_template', 'gameobject_template_locale', 'gameobject_questitem']], - 'pet' => [null, null, null, ['creature_template', 'creature']], - 'quests' => [null, null, null, ['quest_template', 'quest_template_addon', 'locales_quest', 'game_event', 'game_event_seasonal_questrelation', 'disables']], - 'quests_startend' => [null, null, null, ['creature_queststarter', 'creature_questender', 'game_event_creature_quest', 'gameobject_queststarter', 'gameobject_questender', 'game_event_gameobject_quest', 'item_template']], - 'spell' => [null, null, null, ['skill_discovery_template', 'item_template', 'creature_template', 'creature_template_addon', 'smart_scripts', 'npc_trainer', 'disables', 'spell_ranks', 'spell_dbc']], - 'spelldifficulty' => [null, null, null, ['spelldifficulty_dbc']], - 'taxi' /* nodes + paths */ => [null, null, null, ['creature_template', 'creature']], - 'titles' => [null, null, null, ['quest_template', 'game_event_seasonal_questrelation', 'game_event', 'achievement_reward']], - 'items' => [null, null, null, ['item_template', 'locales_item', 'spell_group', 'game_event']], - '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' /* + ench */ => [null, null, ['items', 'spell'], null], - 'source' => [null, null, ['spell', 'achievement'], ['npc_vendor', 'game_event_npc_vendor', 'creature', 'quest_template', 'quest_template_addon', 'playercreateinfo_item', 'npc_trainer', 'skill_discovery_template', 'playercreateinfo_skills', 'achievement_reward', 'skill_perfect_item_template']] + 'icons' => [null, null, null, null], + 'glyphproperties' => [null, true, ['icons'], null], + 'talents' => [null, null, null, null], + 'classes' => [null, null, null, null], + 'factions' => [null, null, null, null], + 'factiontemplate' => [null, null, null, null], + 'holidays' => [null, null, null, null], + 'itemrandomenchant' => [null, null, null, null], + 'races' => [null, null, null, null], + 'shapeshiftforms' => [null, null, null, null], + 'skillline' => [null, null, ['icons'], null], + 'emotes' => [null, null, null, null], + 'sounds' => [null, null, null, null], + 'itemenchantment' => [null, null, null, ['spell_enchant_proc_data']], + 'achievement' => [null, null, ['icons'], ['dbc_achievement', 'disables']], + 'creature' => [null, null, null, ['creature_template', 'creature_template_locale', 'creature_classlevelstats', 'instance_encounters']], + 'currencies' => [null, null, null, ['item_template', 'locales_item']], + 'events' => [null, null, null, ['game_event', 'game_event_prerequisite']], + 'objects' => [null, null, null, ['gameobject_template', 'gameobject_template_locale', 'gameobject_questitem']], + 'pet' => [null, null, ['icons'], ['creature_template', 'creature']], + 'quests' => [null, null, null, ['quest_template', 'quest_template_addon', 'locales_quest', 'game_event', 'game_event_seasonal_questrelation', 'disables']], + 'quests_startend' => [null, null, null, ['creature_queststarter', 'creature_questender', 'game_event_creature_quest', 'gameobject_queststarter', 'gameobject_questender', 'game_event_gameobject_quest', 'item_template']], + 'spell' => [null, null, ['icons'], ['skill_discovery_template', 'item_template', 'creature_template', 'creature_template_addon', 'smart_scripts', 'npc_trainer', 'disables', 'spell_ranks', 'spell_dbc']], + 'spelldifficulty' => [null, null, null, ['spelldifficulty_dbc']], + 'taxi' /* nodes + paths */ => [null, null, null, ['creature_template', 'creature']], + 'titles' => [null, null, null, ['quest_template', 'game_event_seasonal_questrelation', 'game_event', 'achievement_reward']], + 'items' => [null, null, ['icons'], ['item_template', 'locales_item', 'spell_group', 'game_event']], + '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' /* + ench */ => [null, null, ['items', 'spell'], null], + 'source' => [null, null, ['spell', 'achievement'], ['npc_vendor', 'game_event_npc_vendor', 'creature', 'quest_template', 'quest_template_addon', 'playercreateinfo_item', 'npc_trainer', 'skill_discovery_template', 'playercreateinfo_skills', 'achievement_reward', 'skill_perfect_item_template']] ); public static $cliOpts = []; diff --git a/setup/tools/sqlgen/achievement.func.php b/setup/tools/sqlgen/achievement.func.php index c2fbcb24..fc789b80 100644 --- a/setup/tools/sqlgen/achievement.func.php +++ b/setup/tools/sqlgen/achievement.func.php @@ -16,14 +16,47 @@ if (!CLI) $customData = array( 1956 => ['itemExtra' => 44738] ); -$reqDBC = ['achievement_category', 'achievement']; +$reqDBC = ['achievement_category', 'achievement', 'spellicon']; function achievement(array $ids = []) { if ($ids) DB::Aowow()->query('DELETE FROM ?_achievement WHERE id IN (?a)', $ids); else - DB::Aowow()->query('INSERT IGNORE INTO ?_achievement SELECT a.id, 2 - a.faction, a.map, 0, 0, a.category, ac.parentCategory, a.points, a.orderInGroup, a.iconId, a.flags, a.reqCriteriaCount, a.refAchievement, 0, 0, a.name_loc0, a.name_loc2, a.name_loc3, a.name_loc6, a.name_loc8, a.description_loc0, a.description_loc2, a.description_loc3, a.description_loc6, a.description_loc8, a.reward_loc0, a.reward_loc2, a.reward_loc3, a.reward_loc6, a.reward_loc8 FROM dbc_achievement a LEFT JOIN dbc_achievement_category ac ON ac.id = a.category'); + { + DB::Aowow()->query(' + REPLACE INTO + ?_achievement + SELECT + a.id, + 2 - a.faction, + a.map, + 0, + 0, + a.category, + ac.parentCategory, + a.points, + a.orderInGroup, + IFNULL(i.id, 0), + a.iconId, + a.flags, + a.reqCriteriaCount, + a.refAchievement, + 0, + 0, + a.name_loc0, a.name_loc2, a.name_loc3, a.name_loc6, a.name_loc8, + a.description_loc0, a.description_loc2, a.description_loc3, a.description_loc6, a.description_loc8, + a.reward_loc0, a.reward_loc2, a.reward_loc3, a.reward_loc6, a.reward_loc8 + FROM + dbc_achievement a + LEFT JOIN + dbc_achievement_category ac ON ac.id = a.category + LEFT JOIN + dbc_spellicon si ON si.id = a.iconId + LEFT JOIN + ?_icons i ON LOWER(SUBSTRING_INDEX(si.iconPath, "\\\\", -1)) = i.name + '); + } // serverside achievements $serverAchievements = DB::World()->select('SELECT ID, IF(requiredFaction = -1, 3, IF(requiredFaction = 0, 2, 1)) AS "faction", mapID, points, flags, count, refAchievement FROM achievement_dbc{ WHERE id IN (?a)}', diff --git a/setup/tools/sqlgen/currencies.func.php b/setup/tools/sqlgen/currencies.func.php index c2b439d6..c71626ae 100644 --- a/setup/tools/sqlgen/currencies.func.php +++ b/setup/tools/sqlgen/currencies.func.php @@ -40,7 +40,7 @@ function currencies(array $ids = []) else { CLISetup::log('item #'.$itemId.' required by currency #'.$cId.' not in item_template', CLISetup::LOG_WARN); - $strings = ['name_loc0' => 'Item #'.$itemId.' not in DB', 'iconId' => -1240, 'cuFlags' => CUSTOM_EXCLUDE_FOR_LISTVIEW, 'category' => 3]; + $strings = ['name_loc0' => 'Item #'.$itemId.' not in DB', 'iconId' => 0, 'cuFlags' => CUSTOM_EXCLUDE_FOR_LISTVIEW, 'category' => 3]; } DB::Aowow()->query('UPDATE ?_currencies SET ?a WHERE itemId = ?d', $strings, $itemId); @@ -49,7 +49,18 @@ function currencies(array $ids = []) // apply icons $displayIds = DB::World()->selectCol('SELECT entry AS ARRAY_KEY, displayid FROM item_template WHERE entry IN (?a)', $moneyItems); foreach ($displayIds as $itemId => $iconId) - DB::Aowow()->query('UPDATE ?_currencies SET iconId = ?d WHERE itemId = ?d', -$iconId, $itemId); + DB::Aowow()->query(' + UPDATE + ?_currencies c, + ?_icons i, + dbc_itemdisplayinfo idi + SET + c.iconId = i.id + WHERE + i.name = LOWER(idi.inventoryIcon1) AND + idi.id = ?d AND + c.itemId = ?d + ', $iconId, $itemId); return true; } diff --git a/setup/tools/sqlgen/glyphproperties.func.php b/setup/tools/sqlgen/glyphproperties.func.php new file mode 100644 index 00000000..748a3e39 --- /dev/null +++ b/setup/tools/sqlgen/glyphproperties.func.php @@ -0,0 +1,20 @@ +query('REPLACE INTO ?_glyphproperties SELECT id, spellId, typeFlags, 0, iconId FROM dbc_glyphproperties'); + + DB::Aowow()->query('UPDATE ?_glyphproperties gp, ?_icons ic, dbc_spellicon si SET gp.iconId = ic.id WHERE gp.iconIdBak = si.id AND ic.name = LOWER(SUBSTRING_INDEX(si.iconPath, "\\\\", -1))'); + + return true; +} + +?> diff --git a/setup/tools/sqlgen/icons.func.php b/setup/tools/sqlgen/icons.func.php index f73d8c28..184497e3 100644 --- a/setup/tools/sqlgen/icons.func.php +++ b/setup/tools/sqlgen/icons.func.php @@ -13,12 +13,20 @@ $reqDBC = ['spellicon', 'itemdisplayinfo']; function icons() { + DB::Aowow()->query('TRUNCATE ?_icons'); + DB::Aowow()->query('ALTER TABLE ?_icons AUTO_INCREMENT = 1'); + $baseQuery = ' - REPLACE INTO - ?_icons - SELECT Id, LOWER(SUBSTRING_INDEX(iconPath, "\\\\", -1)) FROM dbc_spellicon + INSERT INTO ?_icons (`name`) SELECT x FROM + ( + (SELECT LOWER(SUBSTRING_INDEX(iconPath, "\\\\", -1)) AS x FROM dbc_spellicon WHERE iconPath LIKE "%icons%") UNION - SELECT -Id, LOWER(inventoryIcon1) FROM dbc_itemdisplayinfo'; + (SELECT LOWER(inventoryIcon1) AS x FROM dbc_itemdisplayinfo WHERE inventoryIcon1 <> "") + ) y + GROUP BY + x + ORDER BY + x ASC'; DB::Aowow()->query($baseQuery); diff --git a/setup/tools/sqlgen/items.func.php b/setup/tools/sqlgen/items.func.php index 1ffd9612..093482c3 100644 --- a/setup/tools/sqlgen/items.func.php +++ b/setup/tools/sqlgen/items.func.php @@ -36,6 +36,7 @@ function items(array $ids = []) SoundOverrideSubclass, IFNULL(sg.id, 0) AS subSubClass, name, IFNULL(li.name_loc2, ""), IFNULL(li.name_loc3, ""), IFNULL(li.name_loc6, ""), IFNULL(li.name_loc8, ""), + 0 AS iconId, displayid, 0 AS spellVisualId, Quality, @@ -153,6 +154,9 @@ function items(array $ids = []) // get modelString DB::Aowow()->query('UPDATE ?_items i, dbc_itemdisplayinfo idi SET i.model = IF(idi.leftModelName = "", idi.rightModelName, idi.leftModelName) WHERE i.displayId = idi.id'); + // get iconId + DB::Aowow()->query('UPDATE ?_items i, dbc_itemdisplayinfo idi, ?_icons ic SET i.iconId = ic.id WHERE i.displayId = idi.id AND LOWER(idi.inventoryIcon1) = ic.name'); + // unify slots: Robes => Chest; Ranged (right) => Ranged DB::Aowow()->query('UPDATE ?_items SET slot = 15 WHERE slotbak = 26'); DB::Aowow()->query('UPDATE ?_items SET slot = 5 WHERE slotbak = 20'); diff --git a/setup/tools/sqlgen/pet.func.php b/setup/tools/sqlgen/pet.func.php index 3909cd8d..b861c9c0 100644 --- a/setup/tools/sqlgen/pet.func.php +++ b/setup/tools/sqlgen/pet.func.php @@ -33,12 +33,14 @@ function pet(array $ids = []) 0, -- exotic 0, -- expansion name_loc0, name_loc2, name_loc3, name_lo6, name_loc8, - LOWER(SUBSTRING_INDEX(iconString, "\\\\", -1)), + ic.id, skillLine1, 0, 0, 0, 0, -- spell[1-4] 0, 0, 0 -- armor, damage, health FROM dbc_creaturefamily f + LEFT JOIN + ?_icons ic ON ic.name = LOWER(SUBSTRING_INDEX(f.iconString, "\\\\", -1)) WHERE petTalentType <> -1'; diff --git a/setup/tools/sqlgen/skillline.func.php b/setup/tools/sqlgen/skillline.func.php index 9f883b55..8ea087e4 100644 --- a/setup/tools/sqlgen/skillline.func.php +++ b/setup/tools/sqlgen/skillline.func.php @@ -7,7 +7,7 @@ if (!CLI) die('not in cli mode'); $customData = array( - 393 => ['professionMask' => 0x0000, 'iconId' => 736], // Skinning + 393 => ['professionMask' => 0x0000], // Skinning 171 => ['professionMask' => 0x0001, 'recipeSubClass' => 6, 'specializations' => '28677 28675 28672'], // Alchemy 164 => ['professionMask' => 0x0002, 'recipeSubClass' => 4, 'specializations' => '9788 9787 17041 17040 17039'], // Blacksmithing 185 => ['professionMask' => 0x0004, 'recipeSubClass' => 5], // Cooking @@ -21,7 +21,6 @@ $customData = array( 356 => ['professionMask' => 0x0400, 'recipeSubClass' => 9], // Fishing 182 => ['professionMask' => 0x0800], // Herbalism 773 => ['professionMask' => 0x1000, 'recipeSubClass' => 11], // Inscription - 633 => ['iconId' => 936], // lockpicking 785 => ['name_loc0' => 'Pet - Wasp'], // Pet - Wasp 781 => ['name_loc2' => 'Familier - diablosaure exotique'], // Pet - Exotic Devilsaur 758 => ['name_loc6' => 'Mascota: Evento - Control remoto', 'name_loc3' => 'Tier - Ereignis Ferngesteuert', 'categoryId' => 7], // Pet - Event - Remote Control @@ -35,7 +34,7 @@ function skillline() REPLACE INTO ?_skillline SELECT - Id, categoryId, 0, categoryId, name_loc0, name_loc2, name_loc3, name_loc6, name_loc8, description_loc0, description_loc2, description_loc3, description_loc6, description_loc8, iconId, 0, 0, "" + Id, categoryId, 0, categoryId, name_loc0, name_loc2, name_loc3, name_loc6, name_loc8, description_loc0, description_loc2, description_loc3, description_loc6, description_loc8, 0, iconId, 0, 0, "" FROM dbc_skillline'; @@ -47,11 +46,30 @@ function skillline() DB::Aowow()->query('UPDATE ?_skillline SET typeCat = -6 WHERE id IN (778, 788, 758) OR (categoryId = 7 AND name_loc0 LIKE "%pet%")'); // more complex fixups - DB::Aowow()->query('UPDATE ?_skillline sl, dbc_spell s, dbc_skilllineability sla SET sl.iconId = s.iconId WHERE (s.effect1Id IN (25, 26, 40) OR s.effect2Id = 60) AND sla.spellId = s.id AND sl.id = sla.skillLineId'); DB::Aowow()->query('UPDATE ?_skillline SET name_loc8 = REPLACE(name_loc8, " - ", ": ") WHERE categoryId = 7 OR id IN (758, 788)'); - DB::Aowow()->query('UPDATE ?_skillline SET iconId = ?d WHERE iconId = 0', 1776); // inv_misc_questionmark DB::Aowow()->query('UPDATE ?_skillline SET cuFlags = ?d WHERE id IN (?a)', CUSTOM_EXCLUDE_FOR_LISTVIEW, [142, 148, 149, 150, 152, 155, 183, 533, 553, 554, 713, 769]); + // apply icons + DB::Aowow()->query('UPDATE ?_skillline sl, ?_icons ic, dbc_spellicon si SET sl.iconId = ic.id WHERE sl.iconIdBak = si.id AND ic.name = LOWER(SUBSTRING_INDEX(si.iconPath, "\\\\", -1))'); + DB::Aowow()->query(' + UPDATE + ?_skillline sl, + dbc_spell s, + dbc_skilllineability sla, + ?_icons ic, + dbc_spellicon si + SET + sl.iconId = ic.id + WHERE + (s.effect1Id IN (25, 26, 40) OR s.effect2Id = 60) AND + ic.name = LOWER(SUBSTRING_INDEX(si.iconPath, "\\\\", -1)) AND + s.iconId = si.id AND + sla.spellId = s.id AND + sl.id = sla.skillLineId + '); + DB::Aowow()->query('UPDATE ?_skillline sl, ?_icons ic SET sl.iconId = ic.id WHERE ic.name = ? AND sl.id = ?d', 'inv_misc_pelt_wolf_01', 393); + DB::Aowow()->query('UPDATE ?_skillline sl, ?_icons ic SET sl.iconId = ic.id WHERE ic.name = ? AND sl.id = ?d', 'inv_misc_key_03', 633); + return true; } diff --git a/setup/tools/sqlgen/spell.func.php b/setup/tools/sqlgen/spell.func.php index 7260824b..4b317c42 100644 --- a/setup/tools/sqlgen/spell.func.php +++ b/setup/tools/sqlgen/spell.func.php @@ -32,7 +32,8 @@ $reqDBC = [ 'skillraceclassinfo', 'talent', 'talenttab', - 'glyphproperties' + 'glyphproperties', + 'spellicon' ]; function spell() @@ -85,8 +86,8 @@ function spell() EffectSpellClassMaskA1, EffectSpellClassMaskA2, EffectSpellClassMaskA3, EffectSpellClassMaskB1, EffectSpellClassMaskB2, EffectSpellClassMaskB3, EffectSpellClassMaskC1, EffectSpellClassMaskC2, EffectSpellClassMaskC3, - 0 AS spellVisualId1, 0 AS spellVisualId2, - 0 AS iconId, 0 AS iconIdActive, + 0 AS iconId, 0 AS iconIdAlt, + 0 AS rankId, 0 AS spellVisualId1, CONCAT("Serverside - ",Comment) AS name_loc0,CONCAT("Serverside - ",Comment) AS name_loc2,CONCAT("Serverside - ",Comment) AS name_loc3,CONCAT("Serverside - ",Comment) AS name_loc6,CONCAT("Serverside - ",Comment) AS name_loc8, "" AS rank_loc0, "" AS rank_loc2, "" AS rank_loc3, "" AS rank_loc6, "" AS rank_loc8, "" AS description_loc0, "" AS description_loc2, "" AS description_loc3, "" AS description_loc6, "" AS description_loc8, @@ -175,9 +176,8 @@ function spell() effect1SpellClassMaskC, effect2SpellClassMaskC, effect3SpellClassMaskC, effect1DamageMultiplier, effect2DamageMultiplier, effect3DamageMultiplier, effect1BonusMultiplier, effect2BonusMultiplier, effect3BonusMultiplier, - iconId, 0 AS iconIdAlt, - 0 AS rankId, - spellVisualId1, + 0 AS iconId, iconId AS iconIdBak, 0 AS iconIdAlt, + 0 AS rankId, spellVisualId1, name_loc0, name_loc2, name_loc3, name_loc6, name_loc8, rank_loc0, rank_loc2, rank_loc3, rank_loc6, rank_loc8, description_loc0, description_loc2, description_loc3, description_loc6, description_loc8, @@ -286,6 +286,8 @@ function spell() ABILITY_LEARNED_ON_GET_RACE_OR_CLASS_SKILL = 2 not used for now */ + CLISetup::log(' - linking with skillineability'); + $results = DB::Aowow()->select('SELECT spellId AS ARRAY_KEY, Id AS ARRAY_KEY2, skillLineId, reqRaceMask, reqClassMask, reqSkillLevel, acquireMethod, skillLevelGrey, skillLevelYellow FROM dbc_skilllineability sla'); foreach ($results as $spellId => $sets) { @@ -443,6 +445,8 @@ function spell() /* talent related */ /******************/ + CLISetup::log(' - linking with talent'); + for ($i = 1; $i < 6; $i++) { // classMask @@ -463,6 +467,8 @@ function spell() /* Other */ /*********/ + CLISetup::log(' - misc fixups & icons'); + // FU [FixUps] DB::Aowow()->query('UPDATE ?_spell SET reqRaceMask = ?d WHERE skillLine1 = ?d', 1 << 10, 760); // Draenai Racials DB::Aowow()->query('UPDATE ?_spell SET reqRaceMask = ?d WHERE skillLine1 = ?d', 1 << 9, 756); // Bloodelf Racials @@ -494,7 +500,7 @@ function spell() $itemInfo = DB::World()->select('SELECT entry AS ARRAY_KEY, displayId AS d, Quality AS q FROM item_template WHERE entry IN (?a)', $itemSpells); foreach ($itemSpells as $sId => $itemId) if (isset($itemInfo[$itemId])) - DB::Aowow()->query('UPDATE ?_spell SET iconIdAlt = ?d, cuFlags = cuFlags | ?d WHERE id = ?d', -$itemInfo[$itemId]['d'], ((7 - $itemInfo[$itemId]['q']) << 8), $sId); + DB::Aowow()->query('UPDATE ?_spell s, ?_icons ic, dbc_spellicon si SET s.iconIdAlt = ?d, s.cuFlags = s.cuFlags | ?d WHERE s.iconIdBak = si.id AND ic.name = LOWER(SUBSTRING_INDEX(si.iconPath, "\\\\", -1)) AND s.id = ?d', -$itemInfo[$itemId]['d'], ((7 - $itemInfo[$itemId]['q']) << 8), $sId); // apply specializations [trainerTemplate => reqSpell] $specs = array( @@ -516,11 +522,15 @@ function spell() DB::Aowow()->query('UPDATE ?_spell SET reqSpellId = id WHERE id IN (?a)', [9788, 9787, 20222, 20219, 10660, 10656, 10658, 26797, 26798, 26801, 17039, 17040, 17041]); + // setting icons + DB::Aowow()->query('UPDATE ?_spell s, ?_icons ic, dbc_spellicon si SET s.iconId = ic.id WHERE s.iconIdBak = si.id AND ic.name = LOWER(SUBSTRING_INDEX(si.iconPath, "\\\\", -1))'); /**************/ /* Categories */ /**************/ + CLISetup::log(' - applying categories'); + // player talents (-2) DB::Aowow()->query('UPDATE ?_spell s, dbc_talent t SET s.typeCat = -2 WHERE t.tabId NOT IN (409, 410, 411) AND (s.Id = t.rank1 OR s.Id = t.rank2 OR s.Id = t.rank3 OR s.Id = t.rank4 OR s.Id = t.rank5)'); @@ -635,6 +645,8 @@ function spell() /* Glyphs */ /**********/ + CLISetup::log(' - fixing glyph data'); + // glyphSpell => affectedSpell $glyphAffects = array( 63959 => 50842, // Pestilence @@ -667,8 +679,10 @@ function spell() ); $queryIcons = ' - SELECT s.id, s.name_loc0, s.skillLine1 as skill, s.iconId as icon, s.typeCat * s.typeCat AS prio + SELECT s.id, s.name_loc0, s.skillLine1 as skill, ic.id as icon, s.typeCat * s.typeCat AS prio FROM ?_spell s + LEFT JOIN dbc_spellicon si ON s.iconIdBak = si.id + LEFT JOIN ?_icons ic ON ic.name = LOWER(SUBSTRING_INDEX(si.iconPath, "\\\\", -1)) WHERE [WHERE] AND (s.cuFlags & ?d) = 0 AND s.typeCat IN (0, 7, -2) -- not triggered; class spells first, talents second, unk last ORDER BY prio DESC '; @@ -704,10 +718,8 @@ function spell() // first: manuall replace if ($applyId == 57144) // has no skillLine.. :/ { - $icons = [ - 'skill' => 253, - 'icon' => 163 // ability_poisonsting - ]; + DB::Aowow()->query('UPDATE ?_spell s, ?_icons ic SET s.skillLine1 = ?d, s.iconIdAlt = ic.id WHERE s.id = ?d AND ic.name = ?', 253, 57144, 'ability_poisonsting'); + continue; } // second: search by name and Family equality diff --git a/setup/updates/1490815301_01.sql b/setup/updates/1490815301_01.sql new file mode 100644 index 00000000..4f3608c0 --- /dev/null +++ b/setup/updates/1490815301_01.sql @@ -0,0 +1,45 @@ +DROP TABLE IF EXISTS `aowow_icons`; +CREATE TABLE `aowow_icons` ( + `id` SMALLINT(5) UNSIGNED NOT NULL AUTO_INCREMENT, + `cuFlags` INT(11) UNSIGNED NOT NULL DEFAULT '0', + `name` VARCHAR(55) NOT NULL DEFAULT '', + PRIMARY KEY (`id`), + INDEX `name` (`name`) +) COLLATE='utf8_general_ci' ENGINE=MyISAM AUTO_INCREMENT=1; + +ALTER TABLE `aowow_items` + ADD COLUMN `iconId` SMALLINT(5) UNSIGNED NOT NULL DEFAULT '0' AFTER `name_loc8`, + ADD INDEX `iconId` (`iconId`); + +ALTER TABLE `aowow_spell` + CHANGE COLUMN `iconId` `iconId` SMALLINT(5) UNSIGNED NOT NULL DEFAULT '0' AFTER `effect3BonusMultiplier`, + ADD COLUMN `iconIdBak` SMALLINT(5) UNSIGNED NOT NULL DEFAULT '0' AFTER `iconId`, + CHANGE COLUMN `iconIdAlt` `iconIdAlt` SMALLINT(5) UNSIGNED NOT NULL DEFAULT '0' AFTER `iconIdBak`, + ADD INDEX `iconId` (`iconId`); + +ALTER TABLE `aowow_achievement` + ALTER `iconId` DROP DEFAULT; +ALTER TABLE `aowow_achievement` + CHANGE COLUMN `iconId` `iconId` SMALLINT(5) UNSIGNED NOT NULL DEFAULT '0' AFTER `orderInGroup`, + ADD COLUMN `iconIdBak` SMALLINT(5) UNSIGNED NOT NULL DEFAULT '0' AFTER `iconId`, + ADD INDEX `iconId` (`iconId`); + +ALTER TABLE `aowow_skillline` + CHANGE COLUMN `iconId` `iconId` SMALLINT(5) UNSIGNED NOT NULL DEFAULT '0' AFTER `description_loc8`, + ADD COLUMN `iconIdBak` SMALLINT(5) UNSIGNED NOT NULL DEFAULT '0' AFTER `iconId`; + +ALTER TABLE `aowow_glyphproperties` + CHANGE COLUMN `iconId` `iconId` SMALLINT(5) UNSIGNED NOT NULL DEFAULT '0' AFTER `typeFlags`, + ADD COLUMN `iconIdBak` SMALLINT(5) UNSIGNED NOT NULL DEFAULT '0' AFTER `iconId`; + +ALTER TABLE `aowow_currencies` + ALTER `iconId` DROP DEFAULT; +ALTER TABLE `aowow_currencies` + CHANGE COLUMN `iconId` `iconId` SMALLINT(5) UNSIGNED NOT NULL DEFAULT '0' AFTER `cuFlags`, + ADD INDEX `iconId` (`iconId`); + +ALTER TABLE `aowow_pet` + CHANGE COLUMN `iconString` `iconId` SMALLINT(5) UNSIGNED NOT NULL DEFAULT '0' AFTER `name_loc8`, + ADD INDEX `iconId` (`iconId`); + +UPDATE `aowow_dbversion` SET `sql` = CONCAT(IFNULL(`sql`, ''), ' icons glyphproperties skillline items spell pet achievement'), `build` = CONCAT(IFNULL(`build`, ''), ' simpleImg'); diff --git a/static/css/aowow.css b/static/css/aowow.css index 748f197f..5f012512 100644 --- a/static/css/aowow.css +++ b/static/css/aowow.css @@ -1790,6 +1790,47 @@ Variations: padding: 3px; } +.listview-mode-flexgrid { + display:-ms-flexbox; + display:-webkit-flex; + display:flex; + -webkit-flex-direction:row; + -ms-flex-direction:row; + flex-direction:row; + -webkit-flex-wrap:wrap; + -ms-flex-wrap:wrap; + flex-wrap:wrap; + -webkit-justify-content:flex-start; + -ms-flex-pack:start; + justify-content:flex-start; + -webkit-align-content:flex-start; + -ms-flex-line-pack:start; + align-content:flex-start; + -webkit-align-items:stretch; + -ms-flex-align:stretch; + align-items:stretch; +} + +.listview-mode-flexgrid:after { + clear:both; + content:' '; + display:block; +} + +.listview-mode-flexgrid > div { + float:left; + width:20%; +} + +.listview-mode-flexgrid.clickable > div { + border-radius:4px; + cursor:pointer; +} + +.listview-mode-flexgrid.clickable > div:hover { + background:#1b1b1b; +} + .listview tr.mergerow { background-color: #131d1a; } @@ -1868,6 +1909,187 @@ td.checked .listview-cb:hover { font-family:Verdana, "Open Sans", Arial, "Helvetica Neue", Helvetica, sans-serif; } +.listview-sort-options { + cursor:default; +} + +.listview-sort-options a { + background:#1c1c1c; + display:inline-block; + height:22px; + line-height:22px; + margin:0 1px 4px; + padding:0 8px; + text-shadow:-1px -1px 1px rgba(0, 0, 0, 0.3); +} + +.listview-sort-options a:first-child { + border-radius:99px 0 0 99px; + padding-left:10px; +} + +.listview-sort-options a:last-child { + border-radius:0 99px 99px 0; + padding-right:10px; +} + +.listview-sort-options a:first-child:last-child { + border-radius:99px; +} + +.listview-sort-options .active { + background-color:#333 !important; + color:#fff; + cursor:default; + text-decoration:none; +} + +.listview-sort-options .sortasc, .listview-sort-options .sortdesc { + padding-right:8px !important; +} + +.listview-sort-options .sortasc:last-child, .listview-sort-options .sortdesc:last-child { + padding-right:10px !important; +} + +.listview-sort-options .sortasc:after, .listview-sort-options .sortdesc:after { + display:inline-block; + font:normal normal normal 14px/1 FontAwesome; + font-size:inherit; + text-rendering:auto; + -webkit-font-smoothing:antialiased; + -moz-osx-font-smoothing:grayscale; +} + +.listview-sort-options .sortasc:after, .listview-sort-options .sortdesc:after { + color:#9d9d9d; + margin-left:5px; +} + +.listview-sort-options .sortasc:after { + content:"\f0d8"; + position:relative; + top:-2px; +} + +.listview-sort-options .sortdesc:after { + content:"\f0d7"; +} + +.icon-cell { + padding:10px 0; + position:relative; + text-align:center; +} + +.icon-cell .iconlarge { + float:none; + margin:0 auto; +} + +.icon-cell .icon-cell-name { + margin:0 auto; + overflow:hidden; + text-align:center; + text-overflow:ellipsis; + white-space:nowrap; + width:calc(100% - 10px); +} + +.icon-cell .icon-cell-overlay-placer { + display:none; + left:50%; + position:absolute; + top:-20px; + z-index:2; +} + +.icon-cell:hover .icon-cell-overlay-placer { + display:block; +} + +.icon-cell:hover>.iconlarge { + visibility:hidden; +} + +.icon-cell .icon-cell-overlay { + background:rgba(27, 27, 27, 0); + border-radius:4px; + box-shadow:0 3px 10px rgba(0, 0, 0, 0); + box-sizing:border-box; + left:-87px; + padding:10px; + position:absolute; + transition:150ms; + transition-timing-function:ease-out; + width:174px; +} + +.icon-cell:hover.animate .icon-cell-overlay { + background:rgba(27, 27, 27, 1); + box-shadow:0 3px 10px rgba(0, 0, 0, .35); +} + +.icon-cell .icon-cell-overlay * { + opacity:0; + transition:opacity 150ms; + transition-timing-function:ease-out; +} + +.icon-cell:hover.animate .icon-cell-overlay * { + opacity:1; +} + +.icon-cell .icon-cell-overlay .iconlarge { + margin-bottom:5px; + position:relative; + top:20px; + transition:top 150ms !important; +} + +.icon-cell .icon-cell-overlay .iconlarge, .icon-cell .icon-cell-overlay .iconlarge * { + opacity:1 !important; +} + +.icon-cell:hover.animate .icon-cell-overlay .iconlarge { + top:0; +} + +.icon-cell .icon-cell-overlay input[type="text"] { + box-sizing:border-box; + font-size:11px; + margin:0; + padding:3px 6px; + width:calc(100% - 38px); +} + +.icon-cell .icon-cell-overlay .btn { + margin:0 0 0 10px; + padding:4px 6px; +} + +.icon-cell .icon-cell-overlay .btn.fa:before { + padding-right:0 !important; +} + +.icon-cell .icon-cell-overlay .icon-cell-overlay-name { + position:relative; + z-index:1; +} + +.icon-cell .icon-cell-overlay .icon-cell-overlay-name .ui-effects-wrapper { + display:inline; +} + +.icon-cell .icon-cell-overlay .icon-cell-overlay-counts { + font-size:11px; + margin:5px 0 0; +} + +.icon-cell .icon-cell-overlay .icon-cell-overlay-counts div { + line-height:1.5; +} + .live-search { position: absolute; z-index: 100000001; @@ -4107,3 +4329,18 @@ span#toplinks-rep a { margin: 0px; color: #0C9722; } + +/* icondb fa-replacement custom */ +input.button-copy { + background: #333 url(../images/icons/pages.gif) no-repeat scroll center; + margin-left: 5px; + padding: 2px; + box-shadow: 1px 1px 5px 2px rgba(0,0,0,1); + border: 0px; + border-radius: 3px; + width: 24px +} + +input.button-copy:hover { + background-color: #444; +} diff --git a/static/js/Markup.js b/static/js/Markup.js index 4d02628e..b00ceefe 100644 --- a/static/js/Markup.js +++ b/static/js/Markup.js @@ -27,6 +27,11 @@ MarkupSourceMap[MARKUP_SOURCE_LIVE] = 'live'; MarkupSourceMap[MARKUP_SOURCE_PTR] = 'ptr'; MarkupSourceMap[MARKUP_SOURCE_BETA] = 'beta'; +var MarkupDomainRegexMap = { + betaPtrLang: /^(beta|legion|wod|mop|ptr|www|ko|fr|de|cn|es|ru|pt|it)$/, + lang: /^(www|fr|de|es|ru)$/ // Aowowo - /^(www|ko|fr|de|cn|es|ru|pt|it)$/ +}; + var Markup = { MODE_COMMENT: MARKUP_MODE_COMMENT, MODE_REPLY: MARKUP_MODE_REPLY, @@ -193,8 +198,8 @@ var Markup = { unnamed: { req: true, valid: /^[0-9]+$/ }, diff: { req: false, valid: /^[0-9]+$/ }, icon: { req: false, valid: /^false$/ }, - 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)$/ }, + domain: { req: false, valid: MarkupDomainRegexMap.lang }, + site: { req: false, valid: MarkupDomainRegexMap.lang }, tempname: { req: false } }, @@ -347,8 +352,8 @@ var Markup = { { unnamed: { req: true, valid: /^[0-9]+$/ }, icon: { req: false, valid: /^false$/i }, - 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)$/ } + domain: { req: false, valid: MarkupDomainRegexMap.lang }, + site: { req: false, valid: MarkupDomainRegexMap.lang } }, validate: function(attr) { @@ -444,8 +449,8 @@ var Markup = { unnamed: { req: true, valid: /^[0-9]+$/ }, amount: { req: false, valid: /^[0-9\:]+$/ }, icon: { req: false, valid: /^false$/i }, - 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)$/ } + domain: { req: false, valid: MarkupDomainRegexMap.lang }, + site: { req: false, valid: MarkupDomainRegexMap.lang } }, allowedClass: MARKUP_CLASS_STAFF, validate: function(attr) @@ -605,8 +610,8 @@ var Markup = { 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)$/ } + domain: { req: false, valid: MarkupDomainRegexMap.lang }, + site: { req: false, valid: MarkupDomainRegexMap.lang } }, validate: function(attr) { @@ -645,8 +650,8 @@ var Markup = { 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)$/ } + domain: { req: false, valid: MarkupDomainRegexMap.lang }, + site: { req: false, valid: MarkupDomainRegexMap.lang } }, validate: function(attr) { @@ -685,8 +690,8 @@ var Markup = { 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)$/ } + domain: { req: false, valid: MarkupDomainRegexMap.lang }, + site: { req: false, valid: MarkupDomainRegexMap.lang } }, allowedClass: MARKUP_CLASS_STAFF, validate: function(attr) @@ -727,8 +732,8 @@ var Markup = { 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)$/ } + domain: { req: false, valid: MarkupDomainRegexMap.lang }, + site: { req: false, valid: MarkupDomainRegexMap.lang } }, validate: function(attr) { @@ -921,7 +926,8 @@ var Markup = { preset : { req: false, valid: /\S+/ } }, allowedClass: MARKUP_CLASS_STAFF, - presets: { + presets: + { boss: g_staticUrl + '/images/icons/boss.gif', heroic: g_staticUrl + '/images/icons/heroic.gif' }, @@ -980,6 +986,80 @@ var Markup = { } } }, + icondb: + { + empty: true, + allowInReplies: true, + attr: + { + unnamed: { req: true, valid: /^[0-9]+$/ }, + block: { req: false, valid: /^(true|false)$/ }, + size: { req: false, valid: /^(tiny|small|medium|large)$/ }, + name: { req: false, valid: /^true$/ }, + domain: { req: false, valid: MarkupDomainRegexMap.lang }, + site: { req: false, valid: MarkupDomainRegexMap.lang }, + diff: { req: false, valid: /^[0-9]+$/ }, + tempname: { req: false } + }, + validate: function(attr) + { + if ((attr.domain || attr.site) && Markup.dbpage) + return false; + return true + }, + toHtml: function(attr) { + var size = attr.size ? attr.size : 'small'; + var hasName = attr.name == 'true'; + var id = attr.unnamed; + var domain = Markup._getDatabaseDomainInfo(attr); + var url = domain[0]; + var href = url + '?icon=' + id; + var rel = []; + var tempname = null; + + if (attr.diff); + rel.push('diff=' + attr.diff); + if (attr.tempname) + tempname = attr.tempname; + + if (g_icons[id] && g_icons[id].name) + { + // href += '/' + $WH.urlize(g_icons[id].name); AoWoW - not used + var icon = g_icons[id]; + if (hasName) + { + if (size == 'tiny') + return ' ' + Markup._safeHtml(icon.name) + '' + else + { + var a = $WH.ce('a', { href: href }); + var div = $WH.ce('div', null, a); + $WH.ae(a, Icon.create(icon.name, Icon.sizeIds[size], null, false, null, null, null, null, true)); + a.innerHTML += Markup._safeHtml(icon.name); + + return div.innerHTML; + } + } + else + { + var div = $WH.ce('div'); + $WH.ae(div, Icon.create(icon.name, Icon.sizeIds[size], null, href, null, null, null, null, attr.block != 'true')); + + return div.innerHTML; + } + } + + return '' + (tempname ? tempname : ('(' + LANG.types[29][0] + ' #' + id + ')')) + ''; + }, + toText: function(attr) + { + var id = attr.unnamed; + + if(g_icons[id] && g_icons[id].name) + return Markup._safeHtml(g_icons[id].name); + return LANG.types[29][0] + ' #' + id; + } + }, iconlist: { empty: false, @@ -988,7 +1068,7 @@ var Markup = { rtrim: true, attr: { - domain: { req: false, valid: /^(beta|mop|ptr|www|de|es|fr|ru|pt)$/ } + domain: { req: false, valid: MarkupDomainRegexMap.lang } }, taglessSkip: true, allowedClass: MARKUP_CLASS_STAFF, @@ -1187,8 +1267,8 @@ var Markup = { { unnamed: { req: true, valid: /^[0-9]+$/ }, icon: { req: false, valid: /^false$/i }, - 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)$/ }, + domain: { req: false, valid: MarkupDomainRegexMap.lang }, + site: { req: false, valid: MarkupDomainRegexMap.lang }, tempname: { req: false } }, validate: function(attr) @@ -1234,8 +1314,8 @@ var Markup = { 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)$/ } + domain: { req: false, valid: MarkupDomainRegexMap.lang }, + site: { req: false, valid: MarkupDomainRegexMap.lang } }, validate: function(attr) { @@ -1656,8 +1736,8 @@ var Markup = { 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)$/ } + domain: { req: false, valid: MarkupDomainRegexMap.lang }, + site: { req: false, valid: MarkupDomainRegexMap.lang } }, validate: function(attr) { @@ -1697,8 +1777,8 @@ var Markup = { 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)$/ } + domain: { req: false, valid: MarkupDomainRegexMap.lang }, + site: { req: false, valid: MarkupDomainRegexMap.lang } }, validate: function(attr) { @@ -1820,8 +1900,8 @@ var Markup = { { unnamed: { req: true, valid: /^[0-9]+$/ }, icon: { req: false, valid: /^false$/ }, - 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)$/ } + domain: { req: false, valid: MarkupDomainRegexMap.lang }, + site: { req: false, valid: MarkupDomainRegexMap.lang } }, validate: function(attr) { @@ -1881,8 +1961,8 @@ var Markup = { { unnamed: { req: true, valid: /^[0-9]+$/ }, icon: { req: false, valid: /^false$/ }, - 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)$/ } + domain: { req: false, valid: MarkupDomainRegexMap.lang }, + site: { req: false, valid: MarkupDomainRegexMap.lang } }, validate: function(attr) { @@ -2045,8 +2125,8 @@ var Markup = { unnamed: { req: true, valid: /^[0-9]+$/ }, gender: { req: false, valid: /^(0|1)$/ }, icon: { req: false, valid: /^false$/ }, - 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)$/ } + domain: { req: false, valid: MarkupDomainRegexMap.lang }, + site: { req: false, valid: MarkupDomainRegexMap.lang } }, validate: function(attr) { @@ -2263,8 +2343,8 @@ var Markup = { { unnamed: { req: true, valid: /^[0-9]+$/ }, icon: { req: false, valid: /^false$/ }, - 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)$/ } + domain: { req: false, valid: MarkupDomainRegexMap.lang }, + site: { req: false, valid: MarkupDomainRegexMap.lang } }, validate: function(attr) { @@ -2335,7 +2415,7 @@ var Markup = { type: { req: false, valid: /\S+/ }, src2: { req: false, valid: /\S+/ }, type2: { req: false, valid: /\S+/ }, - domain: { req: false, valid: /^(beta|mop|ptr|www|de|es|fr|ru|pt)$/ } + domain: { req: false, valid: MarkupDomainRegexMap.lang } }, validate: function (attr) { @@ -2498,8 +2578,8 @@ var Markup = { unnamed: { req: true, valid: /^[0-9]+$/ }, diff: { req: false, valid: /^[0-9]+$/ }, icon: { req: false, valid: /^false$/ }, - 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)$/ }, + domain: { req: false, valid: MarkupDomainRegexMap.lang }, + site: { req: false, valid: MarkupDomainRegexMap.lang }, buff: { req: false, valid: /^true$/ }, tempname: { req: false } }, @@ -2563,8 +2643,8 @@ var Markup = { { unnamed: { req: true, valid: /^[0-9]+$/ }, icon: { req: false, valid: /^false$/ }, - 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)$/ } + domain: { req: false, valid: MarkupDomainRegexMap.lang }, + site: { req: false, valid: MarkupDomainRegexMap.lang } }, validate: function(attr) { @@ -3368,8 +3448,8 @@ var Markup = { 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)$/ } + domain: { req: false, valid: MarkupDomainRegexMap.lang }, + site: { req: false, valid: MarkupDomainRegexMap.lang } }, validate: function(attr) { @@ -3408,8 +3488,8 @@ var Markup = { 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)$/ } + domain: { req: false, valid: MarkupDomainRegexMap.lang }, + site: { req: false, valid: MarkupDomainRegexMap.lang } }, validate: function(attr) { diff --git a/static/js/basic.js b/static/js/basic.js index 4663696c..1a6360d5 100644 --- a/static/js/basic.js +++ b/static/js/basic.js @@ -2259,7 +2259,7 @@ $WH.g_createButton = function(text, href, opts) href = 'javascript:;'; if (typeof opts['float'] != 'undefined' && !opts['float']) - styles.push('float:inherit'); + styles.push('float:right'); if (typeof opts.style == 'string') styles.push(opts.style); @@ -2267,7 +2267,7 @@ $WH.g_createButton = function(text, href, opts) if (typeof opts.click == 'function' && !opts.disabled) func = opts.click; - var btn = RedButton.create(text, !opts.disabled, func); + var btn = RedButton.create(text || '\0', !opts.disabled, func); if (styles.length) $(btn).attr('style', styles.join(';')); diff --git a/static/js/filters.js b/static/js/filters.js index fa411035..8e9b1da1 100644 --- a/static/js/filters.js +++ b/static/js/filters.js @@ -403,6 +403,22 @@ var fi_filters = { { id: 20, name: 'teamcontrib5v5', type: 'num' } ], + icons: [ + { id: 9999, name: 'sepuses' }, + { id: 13, name: 'used', type: 'num' }, + { id: 1, name: 'items', type: 'num' }, + { id: 2, name: 'spells', type: 'num' }, + { id: 3, name: 'achievements', type: 'num' }, + // { id: 4, name: 'battlepets', type: 'num' }, + // { id: 5, name: 'battlepetabilities', type: 'num' }, + { id: 6, name: 'currencies', type: 'num' }, + // { id: 7, name: 'garrisonabilities', type: 'num' }, + // { id: 8, name: 'garrisonbuildings', type: 'num' }, + { id: 9, name: 'hunterpets', type: 'num' }, + // { id: 10, name: 'garrisonmissionthreats', type: 'num' }, + { id: 11, name: 'classes', type: 'num' } + ], + // custom enchantments: [ { id: 1, name: 'sepgeneral' }, diff --git a/static/js/global.js b/static/js/global.js index 7d7766fa..dcf1f72e 100644 --- a/static/js/global.js +++ b/static/js/global.js @@ -4880,6 +4880,10 @@ function Listview(opt) { this.createNote = this.template.createNote; } + if (this.sortOptions == null && this.template.sortOptions != null) { + this.sortOptions = this.template.sortOptions; + } + if (this.customFilter == null && this.template.customFilter != null) { this.customFilter = this.template.customFilter; } @@ -5042,12 +5046,23 @@ function Listview(opt) { }); } - for (var i = 0, len = this.columns.length; i < len; ++i) { - var col = this.columns[i]; - if (visibleCols[col.id] != null || (!col.hidden && hiddenCols[col.id] == null)) { - this.visibility.push(i); + if ($.isArray(this.sortOptions)) { + for (var i = 0, len = this.sortOptions.length; i < len; ++i) { + var sortOpt = this.sortOptions[i]; + if (visibleCols[sortOpt.id] != null || (!sortOpt.hidden && hiddenCols[sortOpt.id] == null)) { + this.visibility.push(i); + } } } + else { + for (var i = 0, len = this.columns.length; i < len; ++i) { + var col = this.columns[i]; + if (visibleCols[col.id] != null || (!col.hidden && hiddenCols[col.id] == null)) { + this.visibility.push(i); + } + } + } + // ************************ // Sort @@ -5160,6 +5175,7 @@ Listview.MODE_CHECKBOX = 1; Listview.MODE_DIV = 2; Listview.MODE_TILED = 3; Listview.MODE_CALENDAR = 4; +Listview.MODE_FLEXGRID = 5; Listview.prototype = { initialize: function() { @@ -5204,6 +5220,29 @@ Listview.prototype = { this.mainContainer.className = 'listview-mode-div'; } } + else if (this.mode == Listview.MODE_FLEXGRID) { + /* iconDB todo evaluate */ + this.mainContainer = this.mainDiv = $WH.ce('div', { className: 'listview-mode-flexgrid' }); + this.mainContainer.setAttribute('data-cell-min-width', this.template.cellMinWidth); + if (this.clickable) + this.mainContainer.className += ' clickable'; + + var layout = $('.layout'); + var totalWidth = parseInt(layout.css('max-width')) - (parseInt(layout.css('padding-left')) || 0) - (parseInt(layout.css('padding-right')) || 0); + var slots = Math.floor(totalWidth / this.template.cellMinWidth); + var extraStyle = '.listview-mode-flexgrid[data-cell-min-width="' + this.template.cellMinWidth + '"] > div {min-width:' + this.template.cellMinWidth + "px;width:" + (100 / slots) + "%}"; + while (slots--) + { + if (slots) + { + extraStyle += "\n@media screen and (max-width: " + (((slots + 1) * this.template.cellMinWidth) - 1 + 40) + "px) {"; + extraStyle += '\n .listview-mode-flexgrid[data-cell-min-width="' + this.template.cellMinWidth + '"] > div {width:' + (100 / slots) + "%}"; + extraStyle += "\n}" + } + } + + $("