From e0150feda6535f3e44be262be892dd02c27cff9d Mon Sep 17 00:00:00 2001 From: Sarjuuk Date: Sat, 30 Jun 2018 23:43:57 +0200 Subject: [PATCH] implemented type areatrigger * staff only --- includes/ajaxHandler/filter.class.php | 3 + includes/basetype.class.php | 11 +- includes/defines.php | 9 +- includes/types/areatrigger.class.php | 110 +++++++++++ includes/types/enchantment.class.php | 8 +- includes/types/sound.class.php | 12 +- includes/utilities.php | 34 ++++ index.php | 2 + localization/lang.class.php | 1 + localization/locale_dede.php | 7 + localization/locale_enus.php | 7 + localization/locale_eses.php | 9 +- localization/locale_frfr.php | 7 + localization/locale_ruru.php | 7 + localization/locale_zhcn.php | 7 + pages/areatrigger.php | 218 +++++++++++++++++++++ pages/areatriggers.php | 87 ++++++++ pages/genericPage.class.php | 3 +- pages/icons.php | 2 +- pages/item.php | 2 +- pages/object.php | 2 +- pages/quest.php | 46 +++-- pages/sounds.php | 11 +- pages/zone.php | 20 ++ setup/db_structure.sql | 27 ++- setup/tools/dbc.class.php | 4 +- setup/tools/sqlGen.class.php | 1 + setup/tools/sqlgen/areatrigger.func.php | 107 ++++++++++ setup/updates/1531668311_01.sql | 20 ++ static/css/global.css | 2 +- static/js/ShowOnMap.js | 2 +- static/js/filters.js | 9 +- static/js/global.js | 3 +- static/js/locale_dede.js | 38 +++- static/js/locale_enus.js | 39 +++- static/js/locale_eses.js | 36 +++- static/js/locale_frfr.js | 40 +++- static/js/locale_ruru.js | 38 +++- static/js/locale_zhcn.js | 36 +++- template/bricks/infobox.tpl.php | 34 ++-- template/bricks/lvTabs.tpl.php | 121 ++++++------ template/bricks/mapper.tpl.php | 16 +- template/listviews/areatrigger.tpl.php | 83 ++++++++ template/pages/areatriggers.tpl.php | 66 +++++++ template/pages/detail-page-generic.tpl.php | 6 +- 45 files changed, 1193 insertions(+), 160 deletions(-) create mode 100644 includes/types/areatrigger.class.php create mode 100644 pages/areatrigger.php create mode 100644 pages/areatriggers.php create mode 100644 setup/tools/sqlgen/areatrigger.func.php create mode 100644 setup/updates/1531668311_01.sql create mode 100644 template/listviews/areatrigger.tpl.php create mode 100644 template/pages/areatriggers.tpl.php diff --git a/includes/ajaxHandler/filter.class.php b/includes/ajaxHandler/filter.class.php index f01152bc..905fdc5a 100644 --- a/includes/ajaxHandler/filter.class.php +++ b/includes/ajaxHandler/filter.class.php @@ -35,6 +35,9 @@ class AjaxFilter extends AjaxHandler case 'achievements': $this->filter = (new AchievementListFilter(true, $opts)); break; + case 'areatriggers': + $this->filter = (new AreaTriggerListFilter(true, $opts)); + break; case 'enchantments': $this->filter = (new EnchantmentListFilter(true, $opts)); break; diff --git a/includes/basetype.class.php b/includes/basetype.class.php index e6f1a33c..a77a9b7d 100644 --- a/includes/basetype.class.php +++ b/includes/basetype.class.php @@ -575,6 +575,7 @@ trait spawnHelper $wpSum = []; $wpIdx = 0; $spawns = DB::Aowow()->select("SELECT * FROM ?_spawns WHERE type = ?d AND typeId = ?d", self::$type, $this->id); + if (!$spawns) return; @@ -637,7 +638,13 @@ trait spawnHelper $info[4] = Lang::game('mode').Lang::main('colon').implode(', ', $_); } - $footer = 'Click to move to different floor'; + if (self::$type == TYPE_AREATRIGGER) + { + $o = Util::O2Deg($this->getField('orientation')); + $info[5] = 'Orientation'.Lang::main('colon').$o[0].'° ('.$o[1].')'; + } + + // $footer = 'Click to move to different floor'; } if ($info) @@ -709,7 +716,7 @@ trait spawnHelper public function getSpawns($mode) { // only Creatures, GOs and SoundEmitters can be spawned - if (!self::$type || !$this->getfoundIDs() || (self::$type != TYPE_NPC && self::$type != TYPE_OBJECT && self::$type != TYPE_SOUND)) + if (!self::$type || !$this->getfoundIDs() || (self::$type != TYPE_NPC && self::$type != TYPE_OBJECT && self::$type != TYPE_SOUND && self::$type != TYPE_AREATRIGGER)) return []; switch ($mode) diff --git a/includes/defines.php b/includes/defines.php index f91971bc..56fb231b 100644 --- a/includes/defines.php +++ b/includes/defines.php @@ -35,7 +35,7 @@ define('TYPE_ARENA_TEAM', 102); define('TYPE_USER', 500); define('TYPE_EMOTE', 501); define('TYPE_ENCHANTMENT', 502); -define('TYPE_AREATRIGGER', 503); // not for display, but indexing in ?_spawns-table +define('TYPE_AREATRIGGER', 503); define('CACHE_TYPE_NONE', 0); // page will not be cached define('CACHE_TYPE_PAGE', 1); @@ -914,4 +914,11 @@ define('PR_EXCLUDE_GROUP_WRONG_PROFESSION', PR_EXCLUDE_GROUP_REQ_FISHING | PR define('PR_EXCLUDE_GROUP_REQ_CANT_BE_EXALTED', 0x400); define('PR_EXCLUDE_GROUP_ANY', 0x7FF); +// Areatrigger types +define('AT_TYPE_NONE', 0); +define('AT_TYPE_TAVERN', 1); +define('AT_TYPE_TELEPORT', 2); +define('AT_TYPE_OBJECTIVE', 3); +define('AT_TYPE_SMART', 4); +define('AT_TYPE_SCRIPT', 5); ?> diff --git a/includes/types/areatrigger.class.php b/includes/types/areatrigger.class.php new file mode 100644 index 00000000..36d621a5 --- /dev/null +++ b/includes/types/areatrigger.class.php @@ -0,0 +1,110 @@ + [['s']], + 's' => ['j' => ['?_spawns s ON s.type = 503 AND s.typeId = a.id', true], 's' => ', s.areaId'] + ); + + 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 = []; + + foreach ($this->iterate() as $__) + { + $data[$this->id] = array( + 'id' => $this->curTpl['id'], + 'type' => $this->curTpl['type'], + 'name' => $this->curTpl['name'], + ); + + if ($_ = $this->curTpl['areaId']) + $data[$this->id]['location'] = [$_]; + } + + return $data; + } + + public function getJSGlobals($addMask = GLOBALINFO_ANY) + { + $data = []; + + // foreach ($this->iterate() as $__) + // $data[TYPE_EMOTE][$this->id] = ['name' => $this->getField('cmd')]; + + return $data; + } + + public function renderTooltip() { } +} + +class AreaTriggerListFilter extends Filter +{ + protected $genericFilter = array( + 2 => [FILTER_CR_NUMERIC, 'id', NUM_CAST_INT] // id + ); + + // fieldId => [checkType, checkValue[, fieldIsArray]] + protected $inputFields = array( + 'cr' => [FILTER_V_LIST, [2], true ], // criteria ids + 'crs' => [FILTER_V_RANGE, [1, 6], true ], // criteria operators + 'crv' => [FILTER_V_RANGE, [0, 99999], true ], // criteria values - all criteria are numeric here + 'na' => [FILTER_V_REGEX, '/[\p{C};]/ui', false], // name - only printable chars, no delimiter + 'ma' => [FILTER_V_EQUAL, 1, false], // match any / all filter + 'ty' => [FILTER_V_RANGE, [0, 5], true ] // types + ); + + 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']; + + // name [str] + if (isset($_v['na'])) + if ($_ = $this->modularizeString(['name'])) + $parts[] = $_; + + // type [list] + if (isset($_v['ty'])) + $parts[] = ['type', $_v['ty']]; + + return $parts; + } +} + +?> diff --git a/includes/types/enchantment.class.php b/includes/types/enchantment.class.php index e049d095..f2e7ef5f 100644 --- a/includes/types/enchantment.class.php +++ b/includes/types/enchantment.class.php @@ -338,13 +338,7 @@ class EnchantmentListFilter extends Filter // 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']); - } + $parts[] = ['OR', ['type1', $_v['ty']], ['type2', $_v['ty']], ['type3', $_v['ty']]]; return $parts; } diff --git a/includes/types/sound.class.php b/includes/types/sound.class.php index 19858050..a37fed20 100644 --- a/includes/types/sound.class.php +++ b/includes/types/sound.class.php @@ -103,6 +103,12 @@ class SoundList extends BaseType class SoundListFilter extends Filter { + // fieldId => [checkType, checkValue[, fieldIsArray]] + protected $inputFields = array( + 'na' => [FILTER_V_REGEX, '/[\p{C};]/ui', false], // name - only printable chars, no delimiter + 'ty' => [FILTER_V_LIST, [[1, 4], 6, 9, 10, 12, 13, 14, 16, 17, [19, 23], [25, 31], 50, 52, 53], true ] // type + ); + // we have no criteria for this one... protected function createSQLForCriterium(&$cr) { @@ -111,12 +117,6 @@ class SoundListFilter extends Filter return [1]; } - // fieldId => [checkType, checkValue[, fieldIsArray]] - protected $inputFields = array( - 'na' => [FILTER_V_REGEX, '/[\p{C};]/ui', false], // name - only printable chars, no delimiter - 'ty' => [FILTER_V_LIST, [[1, 4], 6, 9, 10, 12, 13, 14, 16, 17, [19, 23], [25, 31], 50, 52, 53], true ] // type - ); - protected function createSQLForValues() { $parts = []; diff --git a/includes/utilities.php b/includes/utilities.php index 82797231..2c771cf5 100644 --- a/includes/utilities.php +++ b/includes/utilities.php @@ -1445,6 +1445,40 @@ class Util return DB::Aowow()->query('INSERT INTO ?_reports (?#) VALUES (?a)', array_keys($update), array_values($update)); } + + // orientation is 2*M_PI for a full circle, increasing counterclockwise + static function O2Deg($o) + { + // orientation values can exceed boundaries (for whatever reason) + while ($o < 0) + $o += 2*M_PI; + + while ($o >= 2*M_PI) + $o -= 2*M_PI; + + $deg = 360 * (1 - ($o / (2*M_PI) ) ); + if ($deg == 360) + $deg = 0; + + $dir = ['N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW']; + $desc = ''; + foreach ($dir as $f => $d) + { + if (!$f) + continue; + + if ( ($deg >= (45 * $f) - 22.5) && ($deg <= (45 * $f) + 22.5) ) + { + $desc = $d; + break; + } + } + + if (!$desc) + $desc = $dir[0]; + + return [(int)$deg, $desc]; + } } ?> diff --git a/index.php b/index.php index 4eaaa30b..14cb408c 100644 --- a/index.php +++ b/index.php @@ -22,6 +22,8 @@ switch ($pageCall) case 'account': // account management [nyi] case 'achievement': case 'achievements': + case 'areatrigger': + case 'areatriggers': case 'arena-team': case 'arena-teams': case 'class': diff --git a/localization/lang.class.php b/localization/lang.class.php index 346d495e..58374684 100644 --- a/localization/lang.class.php +++ b/localization/lang.class.php @@ -15,6 +15,7 @@ class Lang // types private static $achievement; + private static $areatrigger; private static $chrClass; private static $currency; private static $event; diff --git a/localization/locale_dede.php b/localization/locale_dede.php index 642539ca..54a1edc4 100644 --- a/localization/locale_dede.php +++ b/localization/locale_dede.php @@ -204,6 +204,8 @@ $lang = array( 'game' => array( 'achievement' => "Erfolg", 'achievements' => "Erfolge", + 'areatrigger' => "Areatrigger", + 'areatriggers' => "Areatrigger", 'class' => "Klasse", 'classes' => "Klassen", 'currency' => "Währung", @@ -441,6 +443,11 @@ $lang = array( 5 => "Statistik", 2 => "Waffenschaden", 6 => "DPS", 4 => "Verteidigung" ) ), + 'areatrigger' => array( + 'notFound' => "Dieser Areatrigger existiert nicht.", + 'foundIn' => "Dieser Areatrigger befindet sich in", + 'types' => ['Unbenutzt', 'Gasthaus', 'Teleporter', 'Questziel', 'Smarter Trigger', 'Script'] + ), '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 3ef6b2a2..2328c3a4 100644 --- a/localization/locale_enus.php +++ b/localization/locale_enus.php @@ -204,6 +204,8 @@ $lang = array( 'game' => array( 'achievement' => "achievement", 'achievements' => "Achievements", + 'areatrigger' => "areatrigger", + 'areatriggers' => "Areatrigger", 'class' => "class", 'classes' => "Classes", 'currency' => "currency", @@ -441,6 +443,11 @@ $lang = array( 5 => "Statistics", 2 => "Weapon Damage", 6 => "DPS", 4 => "Defense" ) ), + 'areatrigger' => array( + 'notFound' => "This areatrigger doesn't exist.", + 'foundIn' => "This areatrigger can be found in", + 'types' => ['Unused', 'Tavern', 'Teleporter', 'Quest Objective', 'Smart Trigger', 'Script'] + ), '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 5301f8b7..3e606250 100644 --- a/localization/locale_eses.php +++ b/localization/locale_eses.php @@ -204,6 +204,8 @@ $lang = array( 'game' => array( 'achievement' => "logro", 'achievements' => "Logros", + 'areatrigger' => "areatrigger", + 'areatriggers' => "Areatrigger", 'class' => "clase", 'classes' => "Clases", 'currency' => "monedas", @@ -437,10 +439,15 @@ $lang = array( 'activation' => "Activación", 'notFound' => "Este encantamiento no existe.", 'types' => array( - 1 => "Prob. Hechizo", 3 => "Equipar Hechizo", 7 => "Usar Hechizo", 8 => "Ranura prismática", + 1 => "Prob. Hechizo", 3 => "Equipar Hechizo", 7 => "Usar Hechizo", 8 => "Ranura prismática", 5 => "Atributos", 2 => "Daño de arma", 6 => "DPS", 4 => "Defensa" ) ), + 'areatrigger' => array( + 'notFound' => "This areatrigger doesn't exist.", + 'foundIn' => "This areatrigger can be found in", + 'types' => ['Unused', 'Tavern', 'Teleporter', 'Quest Objective', 'Smart Trigger', 'Script'] + ), '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 4c67ff3b..ae7a771f 100644 --- a/localization/locale_frfr.php +++ b/localization/locale_frfr.php @@ -204,6 +204,8 @@ $lang = array( 'game' => array( 'achievement' => "haut fait", 'achievements' => "Hauts faits", + 'areatrigger' => "areatrigger", + 'areatriggers' => "Areatrigger", 'class' => "classe", 'classes' => "Classes", 'currency' => "monnaies", @@ -441,6 +443,11 @@ $lang = array( 5 => "Statistiques", 2 => "Dégâts d'arme", 6 => "DPS", 4 => "Défense" ) ), + 'areatrigger' => array( + 'notFound' => "This areatrigger doesn't exist.", + 'foundIn' => "This areatrigger can be found in", + 'types' => ['Unused', 'Tavern', 'Teleporter', 'Quest Objective', 'Smart Trigger', 'Script'] + ), '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 585e5f08..8d530178 100644 --- a/localization/locale_ruru.php +++ b/localization/locale_ruru.php @@ -204,6 +204,8 @@ $lang = array( 'game' => array( 'achievement' => "достижение", 'achievements' => "Достижения", + 'areatrigger' => "areatrigger", + 'areatriggers' => "Areatrigger", 'class' => "класс", 'classes' => "Классы", 'currency' => "валюта", @@ -441,6 +443,11 @@ $lang = array( 5 => "Характеристики", 2 => "Урон оружия", 6 => "УВС", 4 => "Защита" ) ), + 'areatrigger' => array( + 'notFound' => "This areatrigger doesn't exist.", + 'foundIn' => "This areatrigger can be found in", + 'types' => ['Unused', 'Tavern', 'Teleporter', 'Quest Objective', 'Smart Trigger', 'Script'] + ), 'gameObject' => array( 'notFound' => "Такой объект не существует.", 'cat' => [0 => "Другое", 9 => "Книги", 3 => "Контейнеры", -5 => "Сундуки", 25 => "Рыболовные лунки",-3 => "Травы", -4 => "Полезные ископаемые", -2 => "Задания", -6 => "Инструменты"], diff --git a/localization/locale_zhcn.php b/localization/locale_zhcn.php index 3e89db9b..aebaaf93 100644 --- a/localization/locale_zhcn.php +++ b/localization/locale_zhcn.php @@ -205,6 +205,8 @@ $lang = array( 'game' => array( 'achievement' => "成就", 'achievements' => "成就", + 'areatrigger' => "areatrigger", + 'areatriggers' => "Areatrigger", 'class' => "职业", 'classes' => "职业", 'currency' => "货币", @@ -442,6 +444,11 @@ $lang = array( 5 => "统计", 2 => "武器伤害", 6 => "DPS", 4 => "防御" ) ), + 'areatrigger' => array( + 'notFound' => "This areatrigger doesn't exist.", + 'foundIn' => "This areatrigger can be found in", + 'types' => ['Unused', 'Tavern', 'Teleporter', 'Quest Objective', 'Smart Trigger', 'Script'] + ), 'gameObject' => array( 'notFound' => "这个对象不存在。", 'cat' => [0 => "Other", 9 => "Books", 3 => "Containers", -5 => "Chests", 25 => "Fishing Pools", -3 => "Herbs", -4 => "Mineral Veins", -2 => "Quest", -6 => "Tools"], diff --git a/pages/areatrigger.php b/pages/areatrigger.php new file mode 100644 index 00000000..549eaf05 --- /dev/null +++ b/pages/areatrigger.php @@ -0,0 +1,218 @@ +hasComContent = false; + $this->contribute = CONTRIBUTE_NONE; + + parent::__construct($pageCall, $id); + + $this->typeId = intVal($id); + + $this->subject = new AreaTriggerList(array(['id', $this->typeId])); + if ($this->subject->error) + $this->notFound(Util::ucFirst(Lang::game('areatrigger')), Lang::areatriger('notFound')); + + $this->name = $this->subject->getField('name') ?: 'AT #'.$this->typeId; + } + + protected function generatePath() + { + $this->path[] = $this->subject->getField('type'); + } + + protected function generateTitle() + { + array_unshift($this->title, $this->name, Util::ucFirst(Lang::game('areatrigger'))); + } + + protected function generateContent() + { + $this->addJS('?data=zones&locale='.User::$localeId.'&t='.$_SESSION['dataKey']); + + $_type = $this->subject->getField('type'); + + + /****************/ + /* Main Content */ + /****************/ + + // get spawns + $map = null; + if ($spawns = $this->subject->getSpawns(SPAWNINFO_FULL)) + { + $ta = $this->subject->getField('teleportA'); + $tf = $this->subject->getField('teleportF'); + $tx = $this->subject->getField('teleportX'); + $ty = $this->subject->getField('teleportY'); + $to = $this->subject->getField('teleportO'); + + // add teleport target + if ($ta && $tx && $ty) + { + $o = Util::O2Deg($to); + $endPoint = array($tx, $ty, array( + 'type' => 4, + 'tooltip' => array( + 'Teleport Destination' => array( + 'info' => ['Orientation'.Lang::main('colon').$o[0].'° ('.$o[1].')'] + ) + ) + )); + + if (isset($spawns[$ta][$tf])) + $spawns[$ta][$tf]['coords'][] = $endPoint; + else + $spawns[$ta][$tf]['coords'] = [$endPoint]; + } + + $map = array( + 'data' => ['parent' => 'mapper-generic'], + 'mapperData' => &$spawns + ); + + foreach ($spawns as $areaId => &$areaData) + $map['extra'][$areaId] = ZoneList::getName($areaId); + } + + $this->map = $map; + $this->infobox = false; + $this->redButtons = array( + BUTTON_LINKS => false, + BUTTON_WOWHEAD => false + ); + + + /**************/ + /* Extra Tabs */ + /**************/ + + if ($_type == AT_TYPE_OBJECTIVE) + { + $relQuest = new QuestList(array(['id', $this->subject->getField('quest')])); + if (!$relQuest->error) + { + $this->extendGlobalData($relQuest->getJSGlobals(GLOBALINFO_SELF | GLOBALINFO_REWARDS)); + $this->lvTabs[] = ['quest', ['data' => array_values($relQuest->getListviewData())]]; + } + } + else if ($_type == AT_TYPE_TELEPORT) + { + $relZone = new ZoneList(array(['id', $this->subject->getField('teleportA')])); + if (!$relZone->error) + { + $this->lvTabs[] = ['zone', ['data' => array_values($relZone->getListviewData())]]; + } + } + else if ($_type == AT_TYPE_SCRIPT) + { + $relTrigger = new AreaTriggerList(array(['id', $this->typeId, '!'], ['name', $this->subject->getField('name')])); + if (!$relTrigger->error) + { + $this->lvTabs[] = ['areatrigger', ['data' => array_values($relTrigger->getListviewData()), 'name' => Util::ucFirst(Lang::game('areatrigger'))], 'areatrigger']; + } + } + else if ($_type == AT_TYPE_SMART) + { + // sourceType:2 [Areatrigger] implies eventTypes: 46, 61 [onTrigger, Linked] + $scripts = DB::World()->select('SELECT id, action_type, action_param1, action_param2, action_param3, action_param4, target_type, target_param1, target_param2 FROM smart_scripts WHERE entryorguid = ?d AND source_type = ?d ORDER BY id ASC', $this->typeId, 2); + + $tbl = ''; + + foreach ($scripts as $sc) + { + $action = ''; + $resolveTarget = function ($type, $guid) { + switch ($type) + { + case 7: // invoker + return 'Invoker'; + case 10: // creature guid entry + if ($id = DB::World()->selectCell('SELECT id FROM creature WHERE guid = ?d', $guid)) + { + $this->extendGlobalIds(TYPE_NPC, $id); + return '[npc='.$id.'] (GUID: '.$guid.')'; + } + else + return 'Unknown NPC with GUID: '.$guid; + case 14: // object guid entry + if ($id = DB::World()->selectCell('SELECT id FROM gameobject WHERE guid = ?d', $guid)) + { + $this->extendGlobalIds(TYPE_OBJECT, $id); + return '[object='.$id.'] (GUID: '.$guid.')'; + } + else + return 'Unknown GameObject with GUID: '.$guid; + default: + return 'Unhandled target #'.$type; + } + }; + + switch ($sc['action_type']) + { + case 15: // complete quest for {target} + $this->extendGlobalIds(TYPE_QUEST, $sc['action_param1']); + $action = '[quest='.$sc['action_param1'].'] is completed for '.$resolveTarget($sc['target_type'], $sc['target_param1']).'.'; + break; + case 33: // kill credit for {target} + $this->extendGlobalIds(TYPE_NPC, $sc['action_param1']); + $action = 'A kill of [npc='.$sc['action_param1'].'] is credited to '.$resolveTarget($sc['target_type'], $sc['target_param1']).'.'; + break; + case 45: // set data in field in {target} + $action = '\"'.$sc['action_param2'].'\" ist stored in field '.$sc['action_param1'].' of '.$resolveTarget($sc['target_type'], $sc['target_param1']).'.'; + break; + case 51: // kill {target} + $action = $resolveTarget($sc['target_type'], $sc['target_param1']).' dies!'; + break; + case 62: // {target} is teleported to map [resolved coords already stored in areatrigger entry] + $this->extendGlobalIds(TYPE_ZONE, $this->subject->getField('teleportA')); + $action = $resolveTarget($sc['target_type'], $sc['target_param1']).' is teleported to [zone='.$this->subject->getField('teleportA').'].'; + break; + case 64: // store {target} in + $action = 'Store '.$resolveTarget($sc['target_type'], $sc['target_param1']).' as target in \"'.$sc['action_param1'].'\".'; + break; + case 70: // respawn GO for sec + $action = $resolveTarget($sc['target_type'], $sc['target_param1']).' is respawned for '.Util::formatTime($sc['action_param1'] * 1000).'.'; + break; + case 85: // invoker cast spell with flags , at {target} + $this->extendGlobalIds(TYPE_SPELL, $sc['action_param1']); + $action = 'Invoker casts [spell='.$sc['action_param1'].'] at '.$resolveTarget($sc['target_type'], $sc['target_param1']).'.'; + break; + case 86: // entity by TargetingBlock(param3, param4, param5, param6) cross cast spell at {target} + $this->extendGlobalIds(TYPE_SPELL, $sc['action_param1']); + $action = $resolveTarget($sc['action_param3'], $sc['action_param4']).' casts [spell='.$sc['action_param1'].'] at '.$resolveTarget($sc['target_type'], $sc['target_param1']).'.'; + break; + case 100: // send targets stored in to entity {target} + $action = 'Send targets stored in \"'.$sc['action_param1'].'\" to '.$resolveTarget($sc['target_type'], $sc['target_param1']).'.'; + break; + default: + $action = 'Unhandled action '.$sc['action_type']; + } + + $tbl .= '[tr][td]'.$sc['id'].'[/td][td]'.$action.'[/td][/tr]'; + } + + $this->extraText = '[pad][h3]On Trigger: SmartAI[h3][table class=grid width=750px]'.$tbl.'[/table]'; + } + } +} + +?> diff --git a/pages/areatriggers.php b/pages/areatriggers.php new file mode 100644 index 00000000..d4f78248 --- /dev/null +++ b/pages/areatriggers.php @@ -0,0 +1,87 @@ +getCategoryFromUrl($pageParam);; + if (isset($this->category[0])) + header('Location: ?areatriggers&filter=ty='.$this->category[0], true, 302); + + $this->filterObj = new AreaTriggerListFilter(); + + parent::__construct($pageCall, $pageParam); + + $this->name = Util::ucFirst(Lang::game('areatriggers')); + } + + protected function generateContent() + { + // recreate form selection + $this->filter = $this->filterObj->getForm(); + $this->filter['query'] = isset($_GET['filter']) ? $_GET['filter'] : null; + $this->filter['initData'] = ['init' => 'areatrigger']; + + if ($x = $this->filterObj->getSetCriteria()) + $this->filter['initData']['sc'] = $x; + + $conditions = []; + if ($_ = $this->filterObj->getConditions()) + $conditions[] = $_; + + $tabData = []; + $trigger = new AreaTriggerList($conditions); + if (!$trigger->error) + { + $tabData['data'] = array_values($trigger->getListviewData()); + + // create note if search limit was exceeded; overwriting 'note' is intentional + if ($trigger->getMatches() > CFG_SQL_LIMIT_DEFAULT) + { + $tabData['note'] = sprintf(Util::$tryFilteringEntityString, $trigger->getMatches(), '"'.Lang::game('areatriggers').'"', CFG_SQL_LIMIT_DEFAULT); + $tabData['_truncated'] = 1; + } + + if ($this->filterObj->error) + $tabData['_errors'] = 1; + + } + + $this->lvTabs[] = ['areatrigger', $tabData, 'areatrigger']; + } + + protected function generateTitle() + { + array_unshift($this->title, $this->name); + + $form = $this->filterObj->getForm(); + if (isset($form['ty']) && count($form['ty']) == 1) + array_unshift($this->title, Lang::areatrigger('types', $form['ty'][0])); + } + + protected function generatePath() + { + $form = $this->filterObj->getForm(); + if (isset($form['ty']) && count($form['ty']) == 1) + $this->path[] = $form['ty']; + } +} + +?> diff --git a/pages/genericPage.class.php b/pages/genericPage.class.php index 3f7eb600..8353b21d 100644 --- a/pages/genericPage.class.php +++ b/pages/genericPage.class.php @@ -198,6 +198,7 @@ class GenericPage private $lvTemplates = array( 'achievement' => ['template' => 'achievement', 'id' => 'achievements', 'parent' => 'lv-generic', 'data' => [], 'name' => '$LANG.tab_achievements' ], + 'areatrigger' => ['template' => 'areatrigger', 'id' => 'areatrigger', 'parent' => 'lv-generic', 'data' => [], ], 'calendar' => ['template' => 'holidaycal', 'id' => 'calendar', 'parent' => 'lv-generic', 'data' => [], 'name' => '$LANG.tab_calendar' ], 'class' => ['template' => 'classs', 'id' => 'classes', 'parent' => 'lv-generic', 'data' => [], 'name' => '$LANG.tab_classes' ], 'commentpreview' => ['template' => 'commentpreview', 'id' => 'comments', 'parent' => 'lv-generic', 'data' => [], 'name' => '$LANG.tab_comments' ], @@ -383,7 +384,7 @@ class GenericPage $this->postCache(); // determine contribute tabs - if (isset($this->subject)) + if (isset($this->subject) && !isset($this->contribute)) { $x = get_class($this->subject); $this->contribute = $x::$contribute; diff --git a/pages/icons.php b/pages/icons.php index 4ebdc164..d702f6d4 100644 --- a/pages/icons.php +++ b/pages/icons.php @@ -62,7 +62,7 @@ class IconsPage extends GenericPage } if ($this->filterObj->error) - $tabData['_errors'] = '$1'; + $tabData['_errors'] = 1; $this->lvTabs[] = ['icongallery', $tabData]; } diff --git a/pages/item.php b/pages/item.php index 0955375f..372eb48b 100644 --- a/pages/item.php +++ b/pages/item.php @@ -484,7 +484,7 @@ class ItemPage extends genericPage if (!$lv['quest']) continue; - $sf[4] = array_merge($sf[4], ['Listview.extraCols.condition']); + $sf[4] = array_merge($sf[4], ['$Listview.extraCols.condition']); $reqQuest[$lv['id']] = 0; diff --git a/pages/object.php b/pages/object.php index 6a7fde01..21291c7c 100644 --- a/pages/object.php +++ b/pages/object.php @@ -365,7 +365,7 @@ class ObjectPage extends GenericPage if (!$lv['quest']) continue; - $extraCols[] = 'Listview.extraCols.condition'; + $extraCols[] = '$Listview.extraCols.condition'; $reqQuest[$lv['id']] = 0; $lv['condition'][0][$this->typeId][] = [[CND_QUESTTAKEN, &$reqQuest[$lv['id']]]]; } diff --git a/pages/quest.php b/pages/quest.php index f8b080f4..67acdeaf 100644 --- a/pages/quest.php +++ b/pages/quest.php @@ -667,25 +667,35 @@ class QuestPage extends GenericPage if ($_specialFlags & QUEST_FLAG_SPECIAL_EXT_COMPLETE) { // areatrigger - if ($atir = DB::World()->selectCell('SELECT id FROM areatrigger_involvedrelation WHERE quest = ?d', $this->typeId)) + if ($atir = DB::Aowow()->selectCol('SELECT id FROM ?_areatrigger WHERE type = ?d AND quest = ?d', AT_TYPE_OBJECTIVE, $this->typeId)) { - if ($atsp = DB::AoWoW()->selectRow('SELECT guid, posX, posY, floor, areaId FROM ?_spawns WHERE `type` = ?d AND `typeId` = ?d', TYPE_AREATRIGGER, $atir)) - $mObjectives[$atsp['areaId']] = array( - 'zone' => 'Zone #'.$atsp['areaId'], - 'mappable' => 1, - 'levels' => array ( - $atsp['floor'] => array ( - array ( - 'type' => -1, // TYPE_AREATRIGGER is internal, the javascript doesn't know it - 'point' => 'requirement', - 'name' => $this->subject->parseText('end', false), - 'coord' => [$atsp['posX'], $atsp['posY']], - 'coords' => [[$atsp['posX'], $atsp['posY']]], - 'objective' => $objectiveIdx++ - ) - ) - ) - ); + if ($atSpawns = DB::AoWoW()->select('SELECT typeId AS ARRAY_KEY, posX, posY, floor, areaId FROM ?_spawns WHERE `type` = ?d AND `typeId` IN (?a)', TYPE_AREATRIGGER, $atir)) + { + foreach ($atSpawns as $atId => $atsp) + { + $atSpawn = array ( + 'type' => User::isInGroup(U_GROUP_STAFF) ? TYPE_AREATRIGGER : -1, + 'id' => $atId, + 'point' => 'requirement', + 'name' => $this->subject->parseText('end', false), + 'coord' => [$atsp['posX'], $atsp['posY']], + 'coords' => [[$atsp['posX'], $atsp['posY']]], + 'objective' => $objectiveIdx++ + ); + + if (isset($mObjectives[$atsp['areaId']]['levels'][$atsp['floor']])) + { + $mObjectives[$atsp['areaId']]['levels'][$atsp['floor']][] = $atSpawn; + continue; + } + + $mObjectives[$atsp['areaId']] = array( + 'zone' => 'Zone #'.$atsp['areaId'], + 'mappable' => 1, + 'levels' => [$atsp['floor'] => [$atSpawn]] + ); + } + } } // complete-spell else if ($endSpell = new SpellList(array('OR', ['AND', ['effect1Id', 16], ['effect1MiscValue', $this->typeId]], ['AND', ['effect2Id', 16], ['effect2MiscValue', $this->typeId]], ['AND', ['effect3Id', 16], ['effect3MiscValue', $this->typeId]]))) diff --git a/pages/sounds.php b/pages/sounds.php index 14111aee..643a3b2f 100644 --- a/pages/sounds.php +++ b/pages/sounds.php @@ -16,9 +16,14 @@ class SoundsPage extends GenericPage protected $tabId = 0; protected $mode = CACHE_TYPE_PAGE; protected $validCats = [1, 2, 3, 4, 6, 9, 10, 12, 13, 14, 16, 17, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 50, 52, 53]; + protected $js = ['filters.js']; public function __construct($pageCall, $pageParam) { + $this->getCategoryFromUrl($pageParam);; + if (isset($this->category[0])) + header('Location: ?sounds&filter=ty='.$this->category[0], true, 302); + $this->filterObj = new SoundListFilter(); parent::__construct($pageCall, $pageParam); @@ -28,8 +33,6 @@ class SoundsPage extends GenericPage protected function generateContent() { - $this->addJs('filters.js'); - $this->redButtons = array( BUTTON_WOWHEAD => true, BUTTON_PLAYLIST => true @@ -42,8 +45,8 @@ class SoundsPage extends GenericPage $this->filter = $this->filterObj->getForm(); $this->filter['query'] = isset($_GET['filter']) ? $_GET['filter'] : null; - $sounds = new SoundList($conditions); $tabData = []; + $sounds = new SoundList($conditions); if (!$sounds->error) { $tabData['data'] = array_values($sounds->getListviewData()); @@ -65,6 +68,8 @@ class SoundsPage extends GenericPage protected function generateTitle() { + array_unshift($this->title, $this->name); + $form = $this->filterObj->getForm(); if (isset($form['ty']) && count($form['ty']) == 1) array_unshift($this->title, Lang::sound('cat', $form['ty'][0])); diff --git a/pages/zone.php b/pages/zone.php index bdee187f..0c69e846 100644 --- a/pages/zone.php +++ b/pages/zone.php @@ -171,6 +171,7 @@ class ZonePage extends GenericPage // we cannot fetch spawns via lists. lists are grouped by entry $oSpawns = DB::Aowow()->select('SELECT * FROM ?_spawns WHERE areaId = ?d AND type = ?d', $this->typeId, TYPE_OBJECT); $cSpawns = DB::Aowow()->select('SELECT * FROM ?_spawns WHERE areaId = ?d AND type = ?d', $this->typeId, TYPE_NPC); + $aSpawns = User::isInGroup(U_GROUP_STAFF) ? DB::Aowow()->select('SELECT * FROM ?_spawns WHERE areaId = ?d AND type = ?d', $this->typeId, TYPE_AREATRIGGER) : []; $conditions = [CFG_SQL_LIMIT_NONE, ['s.areaId', $this->typeId]]; if (!User::isInGroup(U_GROUP_STAFF)) @@ -178,6 +179,7 @@ class ZonePage extends GenericPage $objectSpawns = new GameObjectList($conditions); $creatureSpawns = new CreatureList($conditions); + $atSpawns = new AreaTriggerList($conditions); $questsLV = $rewardsLV = []; @@ -376,6 +378,24 @@ class ZonePage extends GenericPage } } + foreach ($aSpawns as $spawn) + { + $tpl = $atSpawns->getEntry($spawn['typeId']); + if (!$tpl) + continue; + + $n = Util::localizedString($tpl, 'name'); + + $addToSOM('areatrigger', array( + 'coords' => [[$spawn['posX'], $spawn['posY']]], + 'level' => $spawn['floor'], + 'name' => $tpl['name'] ?: 'Unnamed AT #'.$spawn['typeId'], + 'type' => TYPE_AREATRIGGER, + 'id' => $spawn['typeId'], + 'description' => 'Type: '.Lang::areatrigger('types', $tpl['type']) + )); + } + // remove unwanted indizes foreach ($som as $what => &$dataz) { diff --git a/setup/db_structure.sql b/setup/db_structure.sql index bba6c4ad..5ab011f0 100644 --- a/setup/db_structure.sql +++ b/setup/db_structure.sql @@ -340,6 +340,31 @@ CREATE TABLE `aowow_announcements` ( ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; +-- +-- Table structure for table `aowow_areatrigger` +-- + +DROP TABLE IF EXISTS `aowow_areatrigger`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `aowow_areatrigger` ( + `id` int(10) unsigned NOT NULL, + `cuFlags` int(10) unsigned NOT NULL, + `type` smallint(5) unsigned NOT NULL, + `name` varchar(100) NULL DEFAULT NULL, + `orientation` float NOT NULL, + `quest` mediumint(8) unsigned NULL DEFAULT NULL, + `teleportA` smallint(5) unsigned NULL DEFAULT NULL, + `teleportX` float unsigned NULL DEFAULT NULL, + `teleportY` float unsigned NULL DEFAULT NULL, + `teleportO` float NULL DEFAULT NULL, + `teleportF` tinyint(4) unsigned NULL DEFAULT NULL, + PRIMARY KEY (`id`), + INDEX `quest` (`quest`), + INDEX `type` (`type`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE='utf8mb4_general_ci' ; +/*!40101 SET character_set_client = @saved_cs_client */; + -- -- Table structure for table `aowow_articles` -- @@ -3092,7 +3117,7 @@ UNLOCK TABLES; LOCK TABLES `aowow_dbversion` WRITE; /*!40000 ALTER TABLE `aowow_dbversion` DISABLE KEYS */; -INSERT INTO `aowow_dbversion` VALUES (1528316366,0,NULL,NULL); +INSERT INTO `aowow_dbversion` VALUES (1531668312,0,NULL,NULL); /*!40000 ALTER TABLE `aowow_dbversion` ENABLE KEYS */; UNLOCK TABLES; diff --git a/setup/tools/dbc.class.php b/setup/tools/dbc.class.php index 52fd4169..6fa4db04 100644 --- a/setup/tools/dbc.class.php +++ b/setup/tools/dbc.class.php @@ -45,7 +45,7 @@ class DBC 'achievement_category' => 'nisxsssxsxsxxxxxxxxx', 'achievement_criteria' => 'niiiiiiiisxsssxsxsxxxxxxxxiixii', 'areatable' => 'niixixxiiixsxsssxsxsxxxxxxxxixxxxxxx', - 'areatrigger' => 'niffxxxxxx', + 'areatrigger' => 'niffxxxxxf', 'battlemasterlist' => 'niixxxxxxixxxxxxxxxxxxxxxxxxixii', 'charbaseinfo' => 'bb', 'charstartoutfit' => 'nbbbXiiiiiiiiiiiiiiiiiiiixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', @@ -146,7 +146,7 @@ class DBC 'achievement_category' => 'id,parentCategory,name_loc0,name_loc2,name_loc3,name_loc4,name_loc6,name_loc8', 'achievement_criteria' => 'id,refAchievementId,type,value1,value2,value3,value4,value5,value6,name_loc0,name_loc2,name_loc3,name_loc4,name_loc6,name_loc8,completionFlags,groupFlags,timeLimit,order', 'areatable' => 'id,mapId,areaTable,flags,soundAmbience,zoneMusic,zoneIntroMusic,name_loc0,name_loc2,name_loc3,name_loc4,name_loc6,name_loc8,factionGroupMask', - 'areatrigger' => 'id,mapId,posY,posX', + 'areatrigger' => 'id,mapId,posY,posX,orientation', 'battlemasterlist' => 'id,mapId,moreMapId,areaType,maxPlayers,minLevel,maxLevel', 'charbaseinfo' => 'raceId,classId', 'charstartoutfit' => 'id,raceId,classId,gender,item1,item2,item3,item4,item5,item6,item7,item8,item9,item10,item11,item12,item13,item14,item15,item16,item17,item18,item19,item20', diff --git a/setup/tools/sqlGen.class.php b/setup/tools/sqlGen.class.php index 85a2d24f..ab7648f0 100644 --- a/setup/tools/sqlGen.class.php +++ b/setup/tools/sqlGen.class.php @@ -54,6 +54,7 @@ class SqlGen 'skillline' => [null, null, ['icons'], null], 'emotes' => [null, null, null, null], 'sounds' => [null, null, null, null], + 'areatrigger' => [null, null, null, ['areatrigger_involvedrelation', 'areatrigger_scripts', 'areatrigger_tavern', 'areatrigger_teleport', 'quest_template', 'quest_template_addon']], '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']], diff --git a/setup/tools/sqlgen/areatrigger.func.php b/setup/tools/sqlgen/areatrigger.func.php new file mode 100644 index 00000000..1c03d8e9 --- /dev/null +++ b/setup/tools/sqlgen/areatrigger.func.php @@ -0,0 +1,107 @@ +query('TRUNCATE ?_areatrigger'); + DB::Aowow()->query('INSERT INTO ?_areatrigger SELECT id, 0, 0, NULL, orientation, NULL, NULL, NULL, NULL, NULL, NULL FROM dbc_areatrigger'); + + /* notes: + * while areatrigger DO have dimensions, displaying them on a map is almost always futile, + * as they are either too small to be noticable or larger than the map itself (looking at you, oculus dungeon exit) + */ + + // 1: Taverns + CLI::write(' - fetching taverns'); + + $addData = DB::World()->select('SELECT id AS ARRAY_KEY, name, ?d AS `type` FROM areatrigger_tavern', AT_TYPE_TAVERN); + foreach ($addData as $id => $ad) + DB::Aowow()->query('UPDATE ?_areatrigger SET ?a WHERE id = ?d', $ad, $id); + + // 2: Teleporter + teleporting 4: Smart Trigger + CLI::write(' - calculation teleporter coordinates'); + + $addData = DB::World()->select(' + SELECT ID AS ARRAY_KEY, Name AS `name`, target_map AS `map`, target_position_x AS `posY`, target_position_y AS `posX`, target_orientation AS `orientation` FROM areatrigger_teleport UNION + SELECT entryorguid AS ARRAY_KEY, "TBD" AS `name`, action_param1 AS `map`, target_x AS `posY`, target_y AS `posX`, target_o AS `orientation` FROM smart_scripts WHERE source_type = 2 AND action_type = 62 + '); + foreach ($addData as $id => $ad) + { + // todo (low): unify with spawns function + $queryPost = 'SELECT dm.id, wma.areaId, IFNULL(dm.floor, 0) AS floor, ' . + '100 - ROUND(IF(dm.id IS NOT NULL, (?f - dm.minY) * 100 / (dm.maxY - dm.minY), (?f - wma.right) * 100 / (wma.left - wma.right)), 1) AS `posX`, ' . + '100 - ROUND(IF(dm.id IS NOT NULL, (?f - dm.minX) * 100 / (dm.maxX - dm.minX), (?f - wma.bottom) * 100 / (wma.top - wma.bottom)), 1) AS `posY`, ' . + '((abs(IF(dm.id IS NOT NULL, (?f - dm.minY) * 100 / (dm.maxY - dm.minY), (?f - wma.right) * 100 / (wma.left - wma.right)) - 50) / 50) * ' . + ' (abs(IF(dm.id IS NOT NULL, (?f - dm.minX) * 100 / (dm.maxX - dm.minX), (?f - wma.bottom) * 100 / (wma.top - wma.bottom)) - 50) / 50)) AS quality ' . + 'FROM dbc_worldmaparea wma ' . + 'LEFT JOIN dbc_dungeonmap dm ON dm.mapId = IF(?d AND (wma.mapId NOT IN (0, 1, 530, 571) OR wma.areaId = 4395), wma.mapId, -1) ' . + 'WHERE wma.mapId = ?d AND wma.areaId <> 0 ' . + 'HAVING (`posX` BETWEEN 0.1 AND 99.9 AND `posY` BETWEEN 0.1 AND 99.9) ' . + 'ORDER BY quality ASC'; + + $points = DB::Aowow()->select($queryPost, $ad['posX'], $ad['posX'], $ad['posY'], $ad['posY'], $ad['posX'], $ad['posX'], $ad['posY'], $ad['posY'], 1, $ad['map']); + if (!$points) + $points = DB::Aowow()->select($queryPost, $ad['posX'], $ad['posX'], $ad['posY'], $ad['posY'], $ad['posX'], $ad['posX'], $ad['posY'], $ad['posY'], 0, $ad['map']); + + if (!$points) + { + CLI::write(' * AT '.$id.' teleporter endpoint '.CLI::bold($ad['name']).' could not be matched to displayable area [M:'.$ad['map'].'; X:'.$ad['posY'].'; Y:'.$ad['posX'].']', CLI::LOG_WARN); + DB::Aowow()->query('UPDATE ?_areatrigger SET `name` = ?, `type` = ?d WHERE id = ?d', $ad['name'], AT_TYPE_TELEPORT, $id); + continue; + } + + $update = array( + 'name' => $ad['name'], + 'type' => AT_TYPE_TELEPORT, + 'teleportA' => $points[0]['areaId'], + 'teleportX' => $points[0]['posX'], + 'teleportY' => $points[0]['posY'], + 'teleportO' => $ad['orientation'], + 'teleportF' => $points[0]['floor'] + ); + + DB::Aowow()->query('UPDATE ?_areatrigger SET ?a WHERE id = ?d', $update, $id); + } + + // 3: Quest Objectives + CLI::write(' - satisfying quest objectives'); + + $addData = DB::World()->select('SELECT atir.id AS ARRAY_KEY, qt.ID AS quest, NULLIF(qt.AreaDescription, "") AS `name`, qta.SpecialFlags FROM quest_template qt LEFT JOIN quest_template_addon qta ON qta.ID = qt.ID JOIN areatrigger_involvedrelation atir ON atir.quest = qt.ID'); + foreach ($addData as $id => $ad) + { + if (!($ad['SpecialFlags'] & QUEST_FLAG_SPECIAL_EXT_COMPLETE)) + CLI::write(' * Areatrigger '.CLI::bold($id).' is involved in Quest '.CLI::bold($ad['quest']).', but Quest is not flagged for external completion (SpecialFlags & '.Util::asHex(QUEST_FLAG_SPECIAL_EXT_COMPLETE).')', CLI::LOG_WARN); + + DB::Aowow()->query('UPDATE ?_areatrigger SET name = ?, type = ?d, quest = ?d WHERE id = ?d', $ad['name'], AT_TYPE_OBJECTIVE, $ad['quest'], $id); + } + + // 4/5 Scripted + CLI::write(' - assigning scripts'); + + $addData = DB::World()->select('SELECT entry AS ARRAY_KEY, IF(ScriptName = "SmartTrigger", NULL, ScriptName) AS `name`, IF(ScriptName = "SmartTrigger", 4, 5) AS `type` FROM areatrigger_scripts'); + foreach ($addData as $id => $ad) + DB::Aowow()->query('UPDATE ?_areatrigger SET ?a WHERE id = ?d', $ad, $id); + + return true; +} + +?> diff --git a/setup/updates/1531668311_01.sql b/setup/updates/1531668311_01.sql new file mode 100644 index 00000000..56a16e66 --- /dev/null +++ b/setup/updates/1531668311_01.sql @@ -0,0 +1,20 @@ +DROP TABLE IF EXISTS `dbc_areatrigger`; +DROP TABLE IF EXISTS `aowow_areatrigger`; +CREATE TABLE `aowow_areatrigger` ( + `id` INT(10) UNSIGNED NOT NULL, + `cuFlags` INT(10) UNSIGNED NOT NULL, + `type` SMALLINT(5) UNSIGNED NOT NULL, + `name` VARCHAR(100) NULL DEFAULT NULL, + `orientation` FLOAT NOT NULL, + `quest` MEDIUMINT(8) UNSIGNED NULL DEFAULT NULL, + `teleportA` SMALLINT(5) UNSIGNED NULL DEFAULT NULL, + `teleportX` FLOAT UNSIGNED NULL DEFAULT NULL, + `teleportY` FLOAT UNSIGNED NULL DEFAULT NULL, + `teleportO` FLOAT NULL DEFAULT NULL, + `teleportF` TINYINT(4) UNSIGNED NULL DEFAULT NULL, + PRIMARY KEY (`id`), + INDEX `quest` (`quest`), + INDEX `type` (`type`) +) COLLATE='utf8mb4_general_ci' ENGINE=MyISAM; + +UPDATE `aowow_dbversion` SET `sql` = CONCAT(IFNULL(`sql`, ''), ' areatrigger'); diff --git a/static/css/global.css b/static/css/global.css index 4fce05cc..0686a794 100644 --- a/static/css/global.css +++ b/static/css/global.css @@ -591,7 +591,7 @@ html.ie678 .line var { -webkit-box-shadow: 0px 0px 3px black; } -.line.flipped { +.line .flipped { -o-transform: scaleY(-1); -moz-transform: scaleY(-1); -webkit-transform: scaleY(-1); diff --git a/static/js/ShowOnMap.js b/static/js/ShowOnMap.js index 52ab3de6..88603286 100644 --- a/static/js/ShowOnMap.js +++ b/static/js/ShowOnMap.js @@ -186,7 +186,7 @@ ShowOnMap.prototype.construct = function() { allianceDailyCoords[pin.level] = []; } - if (idx != 'rare' && idx != 'spirithealer' && idx != 'book' && idx != 'forge' && idx != 'anvil' && idx != 'hordequests' && idx != 'alliancequests' && idx != 'hordedailyquests' && idx != 'alliancedailyquests' && idx != 'boss') { + if (idx != 'rare' && idx != 'spirithealer' && idx != 'book' && idx != 'forge' && idx != 'anvil' && idx != 'hordequests' && idx != 'alliancequests' && idx != 'hordedailyquests' && idx != 'alliancedailyquests' && idx != 'boss' && idx != 'areatrigger') { // aowow - areatrigger is custom if (tooltip[1] == 2 || tooltip[1] == 0) { if (tooltip[1] == 2) { hordeLegend[2] = [LANG.som_legend_horde, null]; diff --git a/static/js/filters.js b/static/js/filters.js index 7199ebd2..39ee4cfe 100644 --- a/static/js/filters.js +++ b/static/js/filters.js @@ -505,7 +505,7 @@ var fi_filters = { { id: 11, name: 'classes', type: 'num' } ], - // custom + // aowow custom enchantments: [ { id: 1, name: 'sepgeneral' }, { id: 2, name: 'id', type: 'num', before: 'name' }, @@ -579,7 +579,14 @@ var fi_filters = { { id: 10, name: 'hascomments', type: 'yn' }, { id: 11, name: 'hasscreenshots', type: 'yn' }, { id: 12, name: 'hasvideos', type: 'yn' } + ], + + areatrigger: [ + { id: 1, name: 'sepgeneral' }, + { id: 2, name: 'id', type: 'num' } ] + + // end aowow custom }; function fi_toggle() { diff --git a/static/js/global.js b/static/js/global.js index 6ff1bb3c..6cbef854 100644 --- a/static/js/global.js +++ b/static/js/global.js @@ -22626,7 +22626,8 @@ var g_types = { 19: 'sound', 29: 'icon', 501: 'emote', - 502: 'enchantment' + 502: 'enchantment', + 503: 'areatrigger' }; // Items diff --git a/static/js/locale_dede.js b/static/js/locale_dede.js index 572a5678..b6224db6 100644 --- a/static/js/locale_dede.js +++ b/static/js/locale_dede.js @@ -834,6 +834,16 @@ mn_icons = [ // [10, "Bedrohungen", "?icons&filter=cr=10;crs=1;crv=0"], [13, "Ungenutzt", "?icons&filter=cr=13;crs=3;crv=0"] ]; +// aowow - custom start +var mn_areatrigger = [ + [0, 'Unbenutzt', '?areatriggers&filter=ty=0'], + [1, 'Gasthaus', '?areatriggers&filter=ty=1'], + [2, 'Teleporter', '?areatriggers&filter=ty=2'], + [3, 'Questziel', '?areatriggers&filter=ty=3'], + [4, 'Smarter Trigger', '?areatriggers&filter=ty=4'], + [5, 'Script', '?areatriggers&filter=ty=5'] +]; +// aowow - custom end var mn_talentCalc = [ [6,"Todesritter","?talent#j",,{className:"c6",tinyIcon:"class_deathknight"}], [11,"Druide","?talent#0",,{className:"c11",tinyIcon:"class_druid"}], @@ -907,7 +917,8 @@ var mn_database = [ [11,"Weltereignisse","?events",mn_holidays], [, "Anderes"], [19,"Klänge","?sounds",mn_sounds], - [31, "Icons", "?icons", mn_icons] + [31, "Icons", "?icons", mn_icons], + [102, 'Areatrigger', '?areatriggers', mn_areatrigger, {requiredAccess: 1726}] // aowow - custom ]; var mn_tools = [ [0,"Talentrechner","?talent",mn_talentCalc], @@ -2326,7 +2337,17 @@ var g_socket_names = { 14: 'Prismatischer Sockel' }; -/* custom */ +/* aowow custom */ +var g_trigger_types = { + 0: 'Unbenutzt', + 1: 'Gasthaus', + 2: 'Teleporter', + 3: 'Questziel', + 4: 'Smarter Trigger', + 5: 'Script' +}; + +// DRUNK_MESSAGE_* var g_drunk_states = { 0: 'nüchtern', 1: 'beschwipst', @@ -2410,7 +2431,7 @@ var g_conditions = { 37: 'Die Gesundheit des Ziels ist$: nicht; $2 $1', 37: 'Die Gesundheit des Ziels ist$: nicht; $2 $1%' }; -/* end custom */ +/* end aowow custom */ var LANG = { alltime_stc: "Allzeit", @@ -3219,7 +3240,8 @@ var LANG = { anvil: "Amboss", vein: "Erzadern", spirithealer: "Geistheiler", - boss: "Bosse" + boss: "Bosse", + areatrigger: "Areatrigger" // aowow - custom }, markup_b: "Fett", @@ -4223,7 +4245,7 @@ var LANG = { classes: "Genutzt von Klassen" }, - // custom + // aowow custom fienchantments: { id: "ID", hascondition: "Benötigt Edelsteinkombination", @@ -4235,6 +4257,12 @@ var LANG = { hasvideos: "Has videos" }, + fiareatrigger: { + sepgeneral: "Allgemein", + id: "ID" + }, + // end aowow custom + 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 26709082..4fc8a592 100644 --- a/static/js/locale_enus.js +++ b/static/js/locale_enus.js @@ -866,7 +866,7 @@ var mn_sounds = [ [50,"Zone Ambience","?sounds&filter=ty=50"], [28,"Zone Music","?sounds&filter=ty=28"] ]; -mn_icons = [ +var mn_icons = [ [3, "Achievements", "?icons&filter=cr=3;crs=1;crv=0"], // [4, "Battle Pets", "?icons&filter=cr=4;crs=1;crv=0"], // [5, "Battle Pet Abilities", "?icons&filter=cr=5;crs=1;crv=0"], @@ -880,6 +880,16 @@ mn_icons = [ // [10, "Threats", "?icons&filter=cr=10;crs=1;crv=0"], [13, "Unused", "?icons&filter=cr=13;crs=3;crv=0"] ]; +// aowow - custom start +var mn_areatrigger = [ + [0, 'Unused', '?areatriggers&filter=ty=0'], + [1, 'Tavern', '?areatriggers&filter=ty=1'], + [2, 'Teleporter', '?areatriggers&filter=ty=2'], + [3, 'Quest Objective', '?areatriggers&filter=ty=3'], + [4, 'Smart Trigger', '?areatriggers&filter=ty=4'], + [5, 'Script', '?areatriggers&filter=ty=5'] +]; +// aowow - custom end var mn_talentCalc = [ [6,"Death Knight","?talent#j",,{className:"c6",tinyIcon:"class_deathknight"}], [11,"Druid","?talent#0",,{className:"c11",tinyIcon:"class_druid"}], @@ -953,7 +963,8 @@ var mn_database = [ [6,"Zones","?zones",mn_zones], [, "Other"], [31, "Icons", "?icons", mn_icons], - [19,"Sounds","?sounds",mn_sounds] + [19,"Sounds","?sounds",mn_sounds], + [102, 'Areatrigger', '?areatriggers', mn_areatrigger, {requiredAccess: 1726}] // aowow - custom ]; var mn_tools = [ [0,"Talent Calculator","?talent",mn_talentCalc], @@ -2373,7 +2384,16 @@ var g_socket_names = { 14: 'Prismatic Socket' }; -/* custom */ +/* aowow custom */ +var g_trigger_types = { + 0: 'Unused', + 1: 'Tavern', + 2: 'Teleporter', + 3: 'Quest Objective', + 4: 'Smart Trigger', + 5: 'Script' +}; + // DRUNK_MESSAGE_* var g_drunk_states = { 0: 'sober', @@ -2458,7 +2478,7 @@ var g_conditions = { 37: 'The target\'s health is$: not; $2 $1', 37: 'The target\'s health is$: not; $2 $1%' }; -/* end custom */ +/* end aowow custom */ var LANG = { alltime_stc: "All Time", @@ -3268,7 +3288,8 @@ var LANG = { anvil: "Anvils", vein: "Mineral Veins", spirithealer: "Spirit Healers", - boss: "Bosses" + boss: "Bosses", + areatrigger: "Areatrigger" // aowow - custom }, markup_b: "Bold", @@ -4271,7 +4292,7 @@ var LANG = { classes: "Used by Classes" }, - // custom + // aowow custom fienchantments: { id: "ID", hascondition: "Requires a combination of gems", @@ -4283,6 +4304,12 @@ var LANG = { hasvideos: "Has videos" }, + fiareatrigger: { + sepgeneral: "General", + id: "ID" + }, + // end aowow custom + 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 f59da319..1a157022 100644 --- a/static/js/locale_eses.js +++ b/static/js/locale_eses.js @@ -820,7 +820,7 @@ var mn_sounds = [ [50,"Zone Ambience","?sounds&filter=ty=50"], [28,"Zone Music","?sounds&filter=ty=28"] ]; -mn_icons = [ +var mn_icons = [ [3, "Logros", "?icons&filter=cr=3;crs=1;crv=0"], // [4, "Mascotas de duelo", "?icons&filter=cr=4;crs=1;crv=0"], // [5, "Habilidades de mascota de batalla", "?icons&filter=cr=5;crs=1;crv=0"], @@ -834,6 +834,16 @@ mn_icons = [ // [10, "Amenazas", "?icons&filter=cr=10;crs=1;crv=0"], [13, "Sin uso", "?icons&filter=cr=13;crs=3;crv=0"] ]; +// aowow - custom start +var mn_areatrigger = [ + [0, 'Unused', '?areatriggers&filter=ty=0'], + [1, 'Tavern', '?areatriggers&filter=ty=1'], + [2, 'Teleporter', '?areatriggers&filter=ty=2'], + [3, 'Quest Objective', '?areatriggers&filter=ty=3'], + [4, 'Smart Trigger', '?areatriggers&filter=ty=4'], + [5, 'Script', '?areatriggers&filter=ty=5'] +]; +// aowow - custom end var mn_talentCalc = [ [6,"Caballero de la muerte","?talent#j",,{className:"c6",tinyIcon:"class_deathknight"}], [11,"Druida","?talent#0",,{className:"c11",tinyIcon:"class_druid"}], @@ -2327,6 +2337,16 @@ var g_socket_names = { 14: 'Ranura prismática' }; +/* aowow custom */ +var g_trigger_types = { + 0: 'Unused', + 1: 'Tavern', + 2: 'Teleporter', + 3: 'Quest Objective', + 4: 'Smart Trigger', + 5: 'Script' +}; + // DRUNK_MESSAGE_* var g_drunk_states = { 0: 'sobrio', @@ -2411,6 +2431,7 @@ var g_conditions = { 37: 'La salud del objetivo/s esta$: no; $2 $1', 37: 'La salud del objetivo/s esta$: no; $2 $1%' }; +/* end aowow custom */ var LANG = { alltime_stc: "Todo el tiempo", @@ -3219,7 +3240,8 @@ var LANG = { anvil: "Yunques", vein: "Venas de minerales", spirithealer: "Espíritus sanadores", - boss: "Jefes" + boss: "Jefes", + areatrigger: "Areatrigger" // aowow - custom }, markup_b: "Negrita", @@ -4225,7 +4247,7 @@ var LANG = { classes: "Usado(a) por Clases" }, - // custom + // aowow custom fienchantments: { id: "ID", hascondition: "[Requires a combination of gems]", @@ -4234,9 +4256,15 @@ var LANG = { sepcommunity: "Comunidad", hascomments: "Tiene comentarios", hasscreenshots: "Tiene capturas de pantalla", - hasvideos: "Tiene vídeos", + hasvideos: "Tiene vídeos" }, + fiareatrigger: { + sepgeneral: "General", + id: "ID" + }, + // end aowow custom + 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 8e70b89c..ede7f545 100644 --- a/static/js/locale_frfr.js +++ b/static/js/locale_frfr.js @@ -820,7 +820,7 @@ var mn_sounds = [ [50,"Zone Ambience","?sounds&filter=ty=50"], [28,"Zone Music","?sounds&filter=ty=28"] ]; -mn_icons = [ +var mn_icons = [ [3, "Hauts faits", "?icons&filter=cr=3;crs=1;crv=0"], // [4, "Mascottes de combat", "?icons&filter=cr=4;crs=1;crv=0"], // [5, "Capacités de Familiers en Combat", "?icons&filter=cr=5;crs=1;crv=0"], @@ -834,6 +834,16 @@ mn_icons = [ // [10, "Menaces", "?icons&filter=cr=10;crs=1;crv=0"], [13, "Inutilisé", "?icons&filter=cr=13;crs=3;crv=0"] ]; +// aowow - custom start +var mn_areatrigger = [ + [0, 'Unused', '?areatriggers&filter=ty=0'], + [1, 'Tavern', '?areatriggers&filter=ty=1'], + [2, 'Teleporter', '?areatriggers&filter=ty=2'], + [3, 'Quest Objective', '?areatriggers&filter=ty=3'], + [4, 'Smart Trigger', '?areatriggers&filter=ty=4'], + [5, 'Script', '?areatriggers&filter=ty=5'] +]; +// aowow - custom end var mn_talentCalc = [ [6,"Chevalier de la mort","?talent#j",,{className:"c6",tinyIcon:"class_deathknight"}], [11,"Druide","?talent#0",,{className:"c11",tinyIcon:"class_druid"}], @@ -2326,7 +2336,16 @@ var g_socket_names = { 14: 'Châsse prismatique' }; -/* custom */ +/* aowow custom */ +var g_trigger_types = { + 0: 'Unused', + 1: 'Tavern', + 2: 'Teleporter', + 3: 'Quest Objective', + 4: 'Smart Trigger', + 5: 'Script' +}; + // DRUNK_MESSAGE_* var g_drunk_states = { 0: 'sober', @@ -2411,7 +2430,7 @@ var g_conditions = { 37: 'The target\'s health is$: not; $2 $1', 37: 'The target\'s health is$: not; $2 $1%' }; -/* end custom */ +/* end aowow custom */ var LANG = { alltime_stc: "A chaque fois", @@ -3221,7 +3240,8 @@ var LANG = { anvil: "Enclume", vein: "Filons de minerai", spirithealer: "Esprits soigneurs", - boss: "Boss" + boss: "Boss", + areatrigger: "Areatrigger" // aowow - custom }, markup_b: "Gras", @@ -4120,7 +4140,7 @@ var LANG = { paladinaura: "Aura de paladin", totemspell: "Totem", bandagespell: "Sort de bandage", - onGlobalCooldown: "Sur le temps de recharge global" + onGlobalCooldown: "Sur le temps de recharge global", sepcommunity: "Communauté", hascomments: "A des commentaires", @@ -4226,7 +4246,7 @@ var LANG = { classes: "Utilisé par des Classes" }, - // custom + // aowow custom fienchantments: { id: "ID", hascondition: "[Requires a combination of gems]", @@ -4235,9 +4255,15 @@ var LANG = { sepcommunity: "Communauté", hascomments: "A des commentaires", hasscreenshots: "A des captures d'écrans", - hasvideos: "A des vidéos", + hasvideos: "A des vidéos" }, + fiareatrigger: { + sepgeneral: "Général", + id: "ID" + }, + // end aowow custom + 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 b6d0c4bf..9442ad1d 100644 --- a/static/js/locale_ruru.js +++ b/static/js/locale_ruru.js @@ -820,7 +820,7 @@ var mn_sounds = [ [50,"Zone Ambience","?sounds&filter=ty=50"], [28,"Zone Music","?sounds&filter=ty=28"] ]; -mn_icons = [ +var mn_icons = [ [3, "Достижения", "?icons&filter=cr=3;crs=1;crv=0"], // [4, "Боевые питомцы", "?icons&filter=cr=4;crs=1;crv=0"], // [5, "Способности Боевого Питомца", "?icons&filter=cr=5;crs=1;crv=0"], @@ -834,6 +834,16 @@ mn_icons = [ // [10, "Угрозы", "?icons&filter=cr=10;crs=1;crv=0"], [13, "Неиспользуемые", "?icons&filter=cr=13;crs=3;crv=0"] ]; +// aowow - custom start +var mn_areatrigger = [ + [0, 'Unused', '?areatriggers&filter=ty=0'], + [1, 'Tavern', '?areatriggers&filter=ty=1'], + [2, 'Teleporter', '?areatriggers&filter=ty=2'], + [3, 'Quest Objective', '?areatriggers&filter=ty=3'], + [4, 'Smart Trigger', '?areatriggers&filter=ty=4'], + [5, 'Script', '?areatriggers&filter=ty=5'] +]; +// aowow - custom end var mn_talentCalc = [ [6,"Рыцарь смерти","?talent#j",,{className:"c6",tinyIcon:"class_deathknight"}], [11,"Друид","?talent#0",,{className:"c11",tinyIcon:"class_druid"}], @@ -2326,7 +2336,16 @@ var g_socket_names = { 14: 'Бесцветное гнездо' }; -/* custom */ +/* aowow custom */ +var g_trigger_types = { + 0: 'Unused', + 1: 'Tavern', + 2: 'Teleporter', + 3: 'Quest Objective', + 4: 'Smart Trigger', + 5: 'Script' +}; + // DRUNK_MESSAGE_* var g_drunk_states = { 0: 'sober', @@ -2411,7 +2430,7 @@ var g_conditions = { 37: 'The target\'s health is$: not; $2 $1', 37: 'The target\'s health is$: not; $2 $1%' }; -/* end custom */ +/* end aowow custom */ var LANG = { alltime_stc: "Все время", @@ -3221,7 +3240,8 @@ var LANG = { anvil: "Наковальни", vein: "Полезные ископаемые", spirithealer: "Целители душ", - boss: "Боссы" + boss: "Боссы", + areatrigger: "Areatrigger" // aowow - custom }, markup_b: "Жирный", @@ -4230,7 +4250,7 @@ var LANG = { classes: "Используется Классы" }, - // custom + // aowow custom fienchantments: { id: "Номер", hascondition: "[Requires a combination of gems]", @@ -4239,9 +4259,15 @@ var LANG = { sepcommunity: "Сообщество", hascomments: "Есть комментарии", hasscreenshots: "Есть изображения", - hasvideos: "Есть видео", + hasvideos: "Есть видео" }, + fiareatrigger: { + sepgeneral: "Общее", + id: "ID" + }, + // end aowow custom + pr_notice: 'Первый раз? – Не стесняйтесь! Взгляните на страницу помощи!   закрыть', pr_datasource: 'Данные в этой вкладке были последний раз обновлены пользователем $1 $2.', pr_purgedata: "Нажмите, чтобы удалить все собранные данные в текущей вкладке.
Только тот, кто загрузил данные, может их удалить.", diff --git a/static/js/locale_zhcn.js b/static/js/locale_zhcn.js index b91c2251..7205a056 100644 --- a/static/js/locale_zhcn.js +++ b/static/js/locale_zhcn.js @@ -867,7 +867,7 @@ var mn_sounds = [ [50,"区域气氛","?sounds&filter=ty=50"], [28,"区域音乐","?sounds&filter=ty=28"] ]; -mn_icons = [ +var mn_icons = [ [3, "成就", "?icons&filter=cr=3;crs=1;crv=0"], // [4, "战斗宠物", "?icons&filter=cr=4;crs=1;crv=0"], // [5, "对战宠物能力", "?icons&filter=cr=5;crs=1;crv=0"], @@ -881,6 +881,16 @@ mn_icons = [ // [10, "威胁", "?icons&filter=cr=10;crs=1;crv=0"], [13, "未使用", "?icons&filter=cr=13;crs=3;crv=0"] ]; +// aowow - custom start +var mn_areatrigger = [ + [0, 'Unused', '?areatriggers&filter=ty=0'], + [1, 'Tavern', '?areatriggers&filter=ty=1'], + [2, 'Teleporter', '?areatriggers&filter=ty=2'], + [3, 'Quest Objective', '?areatriggers&filter=ty=3'], + [4, 'Smart Trigger', '?areatriggers&filter=ty=4'], + [5, 'Script', '?areatriggers&filter=ty=5'] +]; +// aowow - custom end var mn_talentCalc = [ [6,"死亡骑士","?talent#j",,{className:"c6",tinyIcon:"class_deathknight"}], [11,"德鲁伊","?talent#0",,{className:"c11",tinyIcon:"class_druid"}], @@ -2374,7 +2384,16 @@ var g_socket_names = { 14: '棱彩插槽' }; -/* custom */ +/* aowow custom */ +var g_trigger_types = { + 0: 'Unused', + 1: 'Tavern', + 2: 'Teleporter', + 3: 'Quest Objective', + 4: 'Smart Trigger', + 5: 'Script' +}; + // DRUNK_MESSAGE_* var g_drunk_states = { 0: 'sober', @@ -2459,7 +2478,7 @@ var g_conditions = { 37: 'The target\'s health is$: not; $2 $1', 37: 'The target\'s health is$: not; $2 $1%' }; -/* end custom */ +/* end aowow custom */ var LANG = { alltime_stc: "全天候", @@ -3270,6 +3289,7 @@ var LANG = { vein: "矿点", spirithealer: "灵魂医者", boss: "首领", + areatrigger: "Areatrigger" // aowow - custom }, markup_b: "勇敢", @@ -4252,7 +4272,7 @@ var LANG = { classes: "被$1使用".replace("$1", "职业") }, - // custom + // aowow custom fienchantments: { id: "ID", hascondition: "Requires a combination of gems", @@ -4261,9 +4281,15 @@ var LANG = { sepcommunity: "社区", hascomments: "有评论", hasscreenshots: "有截屏", - hasvideos: "有视频", + hasvideos: "有视频" }, + fiareatrigger: { + sepgeneral: "一般", + id: "ID" + }, + // end aowow custom + pr_notice: 'First time? – Don\'t be shy! Just check out our Help page!   close', // enUS pr_datasource: 'Data in this tab was last updated $2 by $1.', // enUS pr_purgedata: "Click to delete all completion data in the current tab.
Only the user who uploaded the data may purge it.", // enUS diff --git a/template/bricks/infobox.tpl.php b/template/bricks/infobox.tpl.php index c863e283..0a83025d 100644 --- a/template/bricks/infobox.tpl.php +++ b/template/bricks/infobox.tpl.php @@ -1,6 +1,9 @@ +infobox) || !empty($this->contributions) || !empty($this->series) || $this->hasComContent): +?> infobox)): + if (!empty($this->infobox)): ?> contributions)): + if (!empty($this->contributions)): ?> series)): - foreach ($this->series as $s): - $this->brick('series', ['list' => $s[0], 'listTitle' => $s[1]]); - endforeach; -endif; + if (!empty($this->series)): + foreach ($this->series as $s): + $this->brick('series', ['list' => $s[0], 'listTitle' => $s[1]]); + endforeach; + endif; -if (!empty($this->type) && !empty($this->typeId)): + if ($this->hasComContent): ?> community['vi'])): + if (User::isInGroup(U_GROUP_ADMIN | U_GROUP_BUREAU | U_GROUP_VIDEO) || !empty($this->community['vi'])): ?>
@@ -11,9 +14,9 @@ if (!empty($this->infobox)):
@@ -24,36 +27,37 @@ if (!empty($this->contributions)):
community['vi'])): + if (User::isInGroup(U_GROUP_ADMIN | U_GROUP_BUREAU | U_GROUP_VIDEO) || !empty($this->community['vi'])): ?> \n"; endif; -else: - echo " \n"; endif; ?> \ No newline at end of file diff --git a/template/bricks/lvTabs.tpl.php b/template/bricks/lvTabs.tpl.php index c1049698..46c0f83c 100644 --- a/template/bricks/lvTabs.tpl.php +++ b/template/bricks/lvTabs.tpl.php @@ -1,82 +1,85 @@ user) ? 'tabsRelated' : 'myTabs'; -$isTabbed = !empty($this->forceTabs) || $relTabs || count($this->lvTabs) > 1; +if (!empty($this->lvTabs) || !empty($this->user['characterData']) || !empty($this->user['profileData']) || $this->contribute): + $relTabs = !empty($relTabs); + $tabVar = $relTabs || !empty($this->user) ? 'tabsRelated' : 'myTabs'; + $isTabbed = !empty($this->forceTabs) || $relTabs || count($this->lvTabs) > 1; -// lvTab: [file, data, extraInclude] + // lvTab: [file, data, extraInclude] -if ($isTabbed): + if ($isTabbed): ?>
lvTabs as $lv): - if ($lv[0]): - continue; - endif; + foreach ($this->lvTabs as $lv): + if ($lv[0]): + continue; + endif; - echo ''; -endforeach; + echo ''; + endforeach; ?>
- + diff --git a/template/bricks/mapper.tpl.php b/template/bricks/mapper.tpl.php index 2b0a8def..f6175ed6 100644 --- a/template/bricks/mapper.tpl.php +++ b/template/bricks/mapper.tpl.php @@ -5,7 +5,21 @@ elseif (!empty($this->map['data'])): if ($this->type == TYPE_QUEST) : echo "
\n"; elseif ($this->type != TYPE_ZONE): - echo '
'.($this->type == TYPE_OBJECT ? Lang::gameObject('foundIn') : ($this->type == TYPE_SOUND ? Lang::sound('foundIn') : Lang::npc('foundIn'))).' '; + echo '
'; + + if ($this->type == TYPE_OBJECT): + echo Lang::gameObject('foundIn'); + elseif ($this->type == TYPE_SOUND): + echo Lang::sound('foundIn'); + elseif ($this->type == TYPE_NPC): + echo Lang::npc('foundIn'); + elseif ($this->type == TYPE_AREATRIGGER): + echo Lang::areatrigger('foundIn'); + else: + echo "UNKNOWN TYPE"; + endif; + + echo ' '; $extra = $this->map['extra']; echo Lang::concat($this->map['mapperData'], true, function ($areaData, $areaId) use ($extra) { diff --git a/template/listviews/areatrigger.tpl.php b/template/listviews/areatrigger.tpl.php new file mode 100644 index 00000000..4c7d8bf0 --- /dev/null +++ b/template/listviews/areatrigger.tpl.php @@ -0,0 +1,83 @@ +Listview.templates.areatrigger = { + sort: [1], + searchable: 1, + filtrable: 1, + + columns: [ + { + id: 'id', + name: 'ID', + width: '5%', + value: 'id', + compute: function(data, td) { + if (data.id) { + $WH.ae(td, $WH.ct(data.id)); + } + } + }, + { + id: 'name', + name: LANG.name, + type: 'text', + align: 'left', + value: 'name', + compute: function(areatrigger, td, tr) { + var wrapper = $WH.ce('div'); + + var a = $WH.ce('a'); + a.style.fontFamily = 'Verdana, sans-serif'; + a.href = this.getItemLink(areatrigger); + if (!areatrigger.name){ + areatrigger.name = 'Unnamed' + a.className = 'q0'; + } + + $WH.ae(a, $WH.ct(areatrigger.name)); + $WH.ae(wrapper, a); + $WH.ae(td, wrapper); + }, + sortFunc: function(a, b, col) { + return $WH.strcmp(a.name, b.name); + }, + getVisibleText: function(areatrigger) { + return areatrigger.name; + } + }, + { + id: 'location', + name: LANG.location, + type: 'text', + compute: function(areatrigger, td) { + return Listview.funcBox.location(areatrigger, td); + }, + getVisibleText: function(areatrigger) { + return Listview.funcBox.arrayText(areatrigger.location, g_zones); + }, + sortFunc: function(a, b, col) { + return Listview.funcBox.assocArrCmp(a.location, b.location, g_zones); + } + }, + { + id: 'type', + name: LANG.type, + type: 'text', + value: 'type', + width: '12%', + compute: function(areatrigger, td, tr) { + if (g_trigger_types[areatrigger.type]) + $WH.ae(td, $WH.ct(g_trigger_types[areatrigger.type])) + else + $WH.ae(td, $WH.ct(g_trigger_types[0])); + }, + sortFunc: function(a, b, col) { + return $WH.strcmp(this.getVisibleText(a), this.getVisibleText(b)); + }, + getVisibleText: function(areatrigger) { + return g_trigger_types[areatrigger.type]; + } + } + ], + getItemLink: function(areatrigger) { + return '?areatrigger=' + areatrigger.id; + } +} diff --git a/template/pages/areatriggers.tpl.php b/template/pages/areatriggers.tpl.php new file mode 100644 index 00000000..c250ad10 --- /dev/null +++ b/template/pages/areatriggers.tpl.php @@ -0,0 +1,66 @@ +brick('header'); +$f = $this->filter; // shorthand +?> + +
+
+
+ +brick('announcement'); + +$this->brick('pageTemplate', ['fi' => empty($f['query']) ? null : ['query' => $f['query'], 'menuItem' => 101]]); +?> +

name; ?> brick('redButtons'); ?>

+
+
+
+
+ +
+ +
+ + + + + +
+ + +
 />
+
+ +
+ +
+ /> /> +
+ +
+ +
+ + +
+ +
+
+
+ +brick('filter', ['fi' => $f['initData']]); ?> + +brick('lvTabs'); ?> + +
+
+
+ +brick('footer'); ?> diff --git a/template/pages/detail-page-generic.tpl.php b/template/pages/detail-page-generic.tpl.php index 26406f1f..954f119d 100644 --- a/template/pages/detail-page-generic.tpl.php +++ b/template/pages/detail-page-generic.tpl.php @@ -19,7 +19,7 @@ $this->brick('redButtons'); ?> - expansion) ? ' class="h1-icon">'.$this->name.'' : '>'.$this->name; ?> + expansion) ? ' class="h1-icon">'.$this->name.'' : '>'.$this->name); ?> brick('article'); @@ -30,7 +30,7 @@ if (isset($this->extraText)): ?>