From 9019c3b8114dfd11b5ad8c99b85e590a00528228 Mon Sep 17 00:00:00 2001 From: Sarjuuk Date: Tue, 5 Mar 2013 20:31:38 +0100 Subject: [PATCH] Types dropped single-item classes for all types, because it doesn't make much difference to use a list with a single item instead, especially if it's preselected. Additionally it is now easier to chain certain queries together and execute them all at once. additionally, additionally certain data can now be cahced and shared between types of the same .. type, that were previously in different instances alltogether. And you may now specify a limit to sql-queries (while setting up a typeList), it will default to the config-limit if no value is given. --- includes/class.achievement.php | 294 +++---- includes/class.item.php | 865 ++++++++++-------- includes/class.quest.php | 227 +++-- includes/class.spell.php | 965 +++++++++++---------- includes/class.title.php | 132 ++- includes/class.worldevent.php | 2 +- includes/defines.php | 13 +- includes/kernel.php | 4 +- includes/utilities.php | 208 +++-- opensearch.php | 10 +- pages/account.php | 25 +- pages/compare.php | 23 +- pages/item.php | 25 +- pages/spell.php | 44 +- pages/title.php | 60 +- pages/titles.php | 63 +- setup/tools/dataset-assembler/enchants.php | 51 +- setup/tools/dataset-assembler/glyphs.php | 24 +- setup/tools/dataset-assembler/itemsets.php | 2 +- setup/tools/dataset-assembler/talents.php | 4 +- template/titles.tpl | 2 +- 21 files changed, 1614 insertions(+), 1429 deletions(-) diff --git a/includes/class.achievement.php b/includes/class.achievement.php index c0ea8e62..e0448b11 100644 --- a/includes/class.achievement.php +++ b/includes/class.achievement.php @@ -3,51 +3,133 @@ if (!defined('AOWOW_REVISION')) die('illegal access'); -class Achievement extends BaseType +class AchievementList extends BaseType { public $criteria = []; - public $tooltip = ''; + public $tooltip = []; - protected $setupQuery = "SELECT * FROM ?_achievement WHERE `Id` = ?"; + protected $setupQuery = 'SELECT *, Id AS ARRAY_KEY FROM ?_achievement WHERE [filter] [cond] GROUP BY Id ORDER BY `orderInGroup` ASC'; + protected $matchQuery = 'SELECT COUNT(1) FROM ?_achievement WHERE [filter] [cond]'; - public function __construct($data) + public function __construct($conditions) { - parent::__construct($data); + parent::__construct($conditions); // post processing - if (!$this->template['iconString']) - $this->template['iconString'] = 'INV_Misc_QuestionMark'; + while ($this->iterate()) + { + if (!$this->curTpl['iconString']) + $this->templates[$this->Id]['iconString'] = 'INV_Misc_QuestionMark'; + + //"rewards":[[11,137],[3,138]] [type, typeId] + if (!empty($this->curTpl['rewardIds'])) + { + $rewards = []; + $rewIds = explode(" ", $this->curTpl['rewardIds']); + foreach ($rewIds as $rewId) + $rewards[] = ($rewId > 0 ? [TYPE_ITEM => $rewId] : ($rewId < 0 ? [TYPE_TITLE => -$rewId] : NULL)); + + $this->templates[$this->Id]['rewards'] = $rewards; + } + } + + $this->reset(); // restore 'iterator' + } + + public function addRewardsToJScript(&$refs) + { + // collect Ids to execute in single query + $lookup = []; + + while ($this->iterate()) + { + $rewards = explode(" ", $this->curTpl['rewardIds']); + + foreach ($rewards as $reward) + { + if ($reward > 0) + $lookup['item'][] = $reward; + else if ($reward < 0) + $lookup['title'][] = -$reward; + } + } + + if (isset($lookup['item'])) + (new ItemList(array(['i.entry', array_unique($lookup['item'])])))->addGlobalsToJscript($refs); + + if (isset($lookup['title'])) + (new TitleList(array(['Id', array_unique($lookup['title'])])))->addGlobalsToJscript($refs); + } + + public function addGlobalsToJscript(&$refs) + { + if (!isset($refs['gAchievements'])) + $refs['gAchievements'] = []; + + while ($this->iterate()) + { + $refs['gAchievements'][$this->Id] = array( + 'icon' => $this->curTpl['iconString'], + 'name' => Util::localizedString($this->curTpl, 'name') + ); + } } public function getListviewData() { - return array( - 'id' => $this->Id, - 'name' => Util::localizedString($this->template, 'name'), - 'description' => Util::localizedString($this->template, 'description'), - 'points' => $this->template['points'], - 'faction' => $this->template['faction'] + 1, - 'category' => $this->template['category'], - 'parentCat' => $this->template['parentCat'], - 'rewards' => empty($this->template['rewards']) ? NULL : $this->template['rewards'], - 'reward' => empty($this->template['reward_loc'.User::$localeId]) ? NULL : Util::localizedString($this->template, 'reward'), - ); + $data = []; + + while ($this->iterate()) + { + $data[$this->Id] = array( + 'id' => $this->Id, + 'name' => Util::localizedString($this->curTpl, 'name'), + 'description' => Util::localizedString($this->curTpl, 'description'), + 'points' => $this->curTpl['points'], + 'faction' => $this->curTpl['faction'] + 1, + 'category' => $this->curTpl['category'], + 'parentCat' => $this->curTpl['parentCat'], + ); + + if (!empty($this->curTpl['rewards'])) + { + $rewards = []; + + foreach ($this->curTpl['rewards'] as $pair) + $rewards[] = '['.key($pair).','.current($pair).']'; + + $data[$this->Id]['rewards'] = '['.implode(',', $rewards).']'; + } + else if (!empty ($this->curTpl['reward'])) + $data[$this->Id]['reward'] = Util::localizedString($this->curTpl, 'reward'); + + } + + return $data; } // hmm, really needed? .. probably .. needs rename? .. also probably public function getDetailedData() { - return array( - 'id' => $this->Id, - 'name' => Util::localizedString($this->template, 'name'), - 'description' => Util::localizedString($this->template, 'description'), - 'points' => $this->template['points'], - 'iconname' => $this->template['iconString'], - 'count' => $this->template['reqCriteriaCount'], - 'reward' => empty($this->template['reward_loc'.User::$localeId]) ? NULL : Util::localizedString($this->template, 'reward'), - ); + $data = []; + + while ($this->iterate()) + { + $data[$this->Id] = array( + 'id' => $this->Id, + 'name' => Util::localizedString($this->curTpl, 'name'), + 'description' => Util::localizedString($this->curTpl, 'description'), + 'points' => $this->curTpl['points'], + 'iconname' => $this->curTpl['iconString'], + 'count' => $this->curTpl['reqCriteriaCount'], + 'reward' => empty($this->curTpl['reward_loc'.User::$localeId]) ? NULL : Util::localizedString($this->curTpl, 'reward') + ); + } + + return $data; } + // only for current template public function getCriteria($idx = -1) { if (empty($this->criteria)) @@ -57,63 +139,29 @@ class Achievement extends BaseType return []; if (is_array($result[0])) - $this->criteria = $result; + $this->criteria[$this->Id] = $result; else - $this->criteria[] = $result; + $this->criteria[$this->Id][] = $result; } if ($idx < 0) - return $this->criteria; + return $this->criteria[$this->Id]; else - return $this->criteria[$idx]; + return $this->criteria[$this->Id][$idx]; } - public function addGlobalsToJScript(&$gAchievements) + public function renderTooltip() { - $gAchievements[$this->Id] = array( - 'icon' => $this->template['iconString'], - 'name' => Util::localizedString($this->template, 'name'), - ); - } - - public function addRewardsToJscript(&$gItems, &$gTitles) - { - $rewards = explode(" ", $this->template['rewardIds']); - - $lookup = []; - foreach ($rewards as $reward) - { - if ($reward > 0) - $lookup['item'][] = $reward; - else if ($reward < 0) - $lookup['title'][] = -$reward; - } - - if (isset($lookup['item'])) - { - $rewItems = new ItemList(array(['i.entry', $lookup['item']])); - $rewItems->addGlobalsToJScript($gItems); - } - - if (isset($lookup['title'])) - { - $rewTitles = new TitleList(array(['Id', $lookup['title']])); - $rewTitles->addGlobalsToJScript($gTitles); - } - } - - public function createTooltip() - { - if (!empty($this->tooltip)) - return $this->tooltip; + if (!empty($this->tooltip[$this->Id])) + return $this->tooltip[$this->Id]; $criteria = $this->getCriteria(); - $tmp = []; + $tmp = []; $rows = []; - $i = 0; + $i = 0; foreach ($criteria as $_row) { - if($i++ % 2) + if ($i++ % 2) $tmp[] = $_row; else $rows[] = $_row; @@ -121,9 +169,9 @@ class Achievement extends BaseType if ($tmp) $rows = array_merge($rows, $tmp); - $description = Util::localizedString($this->template, 'description'); - $name = Util::localizedString($this->template, 'name'); - $criteria = ''; + $description = Util::localizedString($this->curTpl, 'description'); + $name = Util::localizedString($this->curTpl, 'name'); + $criteria = ''; $i = 0; foreach ($rows as $crt) @@ -148,7 +196,7 @@ class Achievement extends BaseType case ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM: case ACHIEVEMENT_CRITERIA_TYPE_EQUIP_ITEM: if (!$crtName) - $crtName = Item::getName($crt['value1']); + $crtName = Util::getItemName($crt['value1']); break; case ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION: if (!$crtName) @@ -184,88 +232,29 @@ class Achievement extends BaseType $x .= ''; // Completed - $this->tooltip = $x; + $this->tooltip[$this->Id] = $x; - return $this->tooltip; + return $this->tooltip[$this->Id]; } public function getSourceData() { - return array( - "n" => Util::localizedString($this->template, 'name'), - "s" => $this->template['faction'], - "t" => TYPE_ACHIEVEMENT, - "ti" => $this->Id - ); - } -} + $data = []; - - -class AchievementList extends BaseTypeList -{ - protected $setupQuery = 'SELECT *, Id AS ARRAY_KEY FROM ?_achievement WHERE [filter] [cond] GROUP BY Id ORDER BY `orderInGroup` ASC'; - - public function __construct($conditions) - { - // may be called without filtering - if (class_exists('AchievementFilter')) + while ($this->iterate()) { - $this->filter = new AchievementFilter(); - if (($fiData = $this->filter->init()) === false) - return; + $data[$this->Id] = array( + "n" => Util::localizedString($this->curTpl, 'name'), + "s" => $this->curTpl['faction'], + "t" => TYPE_ACHIEVEMENT, + "ti" => $this->Id + ); } - parent::__construct($conditions); - - // post processing - foreach ($this->container as $k => $acv) - { - //"rewards":[[11,137],[3,138]] [what, entry] 3:item; 11:title, 6:spell(unused) - if (!empty($acv->template['rewardIds'])) - { - $rewards = []; - $rewIds = explode(" ", $acv->template['rewardIds']); - foreach ($rewIds as $rewId) - $rewards[] = ($rewId > 0 ? "[3,".$rewId."]" : ($rewId < 0 ? "[11,".-$rewId."]" : NULL)); - - $this->container[$k]->template['rewards'] = "[".implode(",",$rewards)."]"; - } - } + return $data; } - public function addRewardsToJScript(&$gItems, &$gTitles) - { - // collect Ids to execute in single query - $lookup = []; - - foreach ($this->container as $id => $data) - { - $rewards = explode(" ", $data->template['rewardIds']); - - foreach ($rewards as $reward) - { - if ($reward > 0) - $lookup['item'][] = $reward; - else if ($reward < 0) - $lookup['title'][] = -$reward; - } - } - - if (isset($lookup['item'])) - { - $rewItems = new ItemList(array(['i.entry', array_unique($lookup['item'])])); - $rewItems->addGlobalsToJScript($gItems); - } - - if (isset($lookup['title'])) - { - $rewTitles = new TitleList(array(['Id', array_unique($lookup['title'])])); - $rewTitles->addGlobalsToJScript($gTitles); - } - } - - // run once + // run once .. should this even be here..? public function setupAchievements() { set_time_limit(120); @@ -309,21 +298,21 @@ class AchievementList extends BaseTypeList world.achievement_dbc" ); - foreach ($this->container as $acv) + while ($this->iterate()) { // set iconString - $icon = DB::Aowow()->SelectCell('SELECT iconname FROM ?_spellicons WHERE id = ?d', $acv->template['iconId']); + $icon = DB::Aowow()->SelectCell('SELECT iconname FROM ?_spellicons WHERE id = ?d', $this->curTpl['iconId']); // set parentCat - $parentCat = DB::Aowow()->SelectCell('SELECT parentCategory FROM ?_achievementcategory WHERE Id = ?d', $acv->template['category']); + $parentCat = DB::Aowow()->SelectCell('SELECT parentCategory FROM ?_achievementcategory WHERE Id = ?d', $this->curTpl['category']); // series parent(16) << child(16) - $series = $acv->template['parent'] << 16; + $series = $this->curTpl['parent'] << 16; $series |= DB::Aowow()->SelectCell('SELECT Id FROM ?_achievement WHERE parent = ?d', $acv->Id); // set rewards $rewardIds = []; - if ($rStr = $acv->template['reward_loc0']) + if ($rStr = $this->curTpl['reward_loc0']) { // i can haz title? @@ -384,4 +373,5 @@ class AchievementList extends BaseTypeList } } } -?> \ No newline at end of file + +?> diff --git a/includes/class.item.php b/includes/class.item.php index e9f36d65..db9b7bb8 100644 --- a/includes/class.item.php +++ b/includes/class.item.php @@ -3,117 +3,34 @@ if (!defined('AOWOW_REVISION')) die('illegal access'); -class Item extends BaseType +class ItemList extends BaseType { - public $name = ''; public $tooltip = ''; public $json = []; public $itemMods = []; - private $ssd = null; - protected $setupQuery = 'SELECT * FROM item_template i LEFT JOIN ?_item_template_addon iX ON i.entry = iX.id LEFT JOIN locales_item l ON i.entry = l.entry WHERE i.entry = ?d'; + public $rndEnchIds = []; + public $subItems = []; - public function __construct($data) + private $ssd = []; + + protected $setupQuery = 'SELECT *, i.entry AS ARRAY_KEY FROM item_template i LEFT JOIN ?_item_template_addon iX ON i.entry = iX.id LEFT JOIN locales_item l ON i.entry = l.entry WHERE [filter] [cond] GROUP BY i.entry ORDER BY i.Quality DESC'; + protected $matchQuery = 'SELECT COUNT(1) FROM item_template i LEFT JOIN ?_item_template_addon iX ON i.entry = iX.id LEFT JOIN locales_item l ON i.entry = l.entry WHERE [filter] [cond]'; + + public function __construct($conditions) { - parent::__construct($data); + parent::__construct($conditions); - // post processing - $this->name = Util::localizedString($this->template, 'name'); - - // item is scaling; overwrite other values - if ($this->template['ScalingStatDistribution'] > 0 && $this->template['ScalingStatValue'] > 0) + while ($this->iterate()) { - $this->ssd = DB::Aowow()->selectRow("SELECT * FROM ?_scalingstatdistribution WHERE id = ?", $this->template['ScalingStatDistribution']); + // item is scaling; overwrite other values + if ($this->curTpl['ScalingStatDistribution'] > 0 && $this->curTpl['ScalingStatValue'] > 0) + $this->initScalingStats(); - // stats and ratings - for ($i = 1; $i <= 10; $i++) - { - if ($this->ssd['statMod'.$i] <= 0) - { - $this->template['stat_type'.$i] = 0; - $this->template['stat_value'.$i] = 0; - } - else - { - $this->template['stat_type'.$i] = $this->ssd['statMod'.$i]; - $this->template['stat_value'.$i] = intVal(($this->getSSDMod('stats') * $this->ssd['modifier'.$i]) / 10000); - } - } - - // armor: only replace if set - if ($ssvArmor = $this->getSSDMod('armor')) - $this->template['armor'] = $ssvArmor; - - // If set dpsMod in ScalingStatValue use it for min (70% from average), max (130% from average) damage - if ($extraDPS = $this->getSSDMod('dps')) - { - $average = $extraDPS * $this->template['delay'] / 1000; - $this->template['dmg_min1'] = number_format(0.7 * $average); // dmg_2 not used for heirlooms - $this->template['dmg_max1'] = number_format(1.3 * $average); - } - - // Apply Spell Power from ScalingStatValue if set - if ($spellBonus = $this->getSSDMod('spell')) - { - $this->template['stat_type10'] = ITEM_MOD_SPELL_POWER; - $this->template['stat_value10'] = $spellBonus; - } + $this->initJsonStats(); } - // create json values; zero-values are filtered later - $this->json['id'] = $this->Id; - $this->json['name'] = (ITEM_QUALITY_HEIRLOOM - $this->template['Quality']).$this->name; - $this->json['icon'] = $this->template['icon']; - $this->json['classs'] = $this->template['class']; - $this->json['subclass'] = $this->template['subclass']; - $this->json['slot'] = $this->template['InventoryType']; - $this->json['slotbak'] = $this->template['InventoryType']; - $this->json['level'] = $this->template['ItemLevel']; - $this->json['reqlevel'] = $this->template['RequiredLevel']; - $this->json['displayid'] = $this->template['displayid']; - $this->json['commondrop'] = ($this->template['RandomProperty'] > 0 || $this->template['RandomSuffix'] > 0) ? 'true' : null; // string required :( - $this->json['holres'] = $this->template['holy_res']; - $this->json['firres'] = $this->template['fire_res']; - $this->json['natres'] = $this->template['nature_res']; - $this->json['frores'] = $this->template['frost_res']; - $this->json['shares'] = $this->template['shadow_res']; - $this->json['arcres'] = $this->template['arcane_res']; - $this->json['armorbonus'] = $this->template['ArmorDamageModifier']; - $this->json['armor'] = $this->template['armor']; - $this->json['itemset'] = $this->template['itemset']; - $this->json['socket1'] = $this->template['socketColor_1']; - $this->json['socket2'] = $this->template['socketColor_2']; - $this->json['socket3'] = $this->template['socketColor_3']; - $this->json['nsockets'] = ($this->json['socket1'] > 0 ? 1 : 0) + ($this->json['socket2'] > 0 ? 1 : 0) + ($this->json['socket3'] > 0 ? 1 : 0); - $this->json['socketbonus'] = $this->template['socketBonus']; - $this->json['scadist'] = $this->template['ScalingStatDistribution']; - $this->json['scaflags'] = $this->template['ScalingStatValue']; - if ($this->template['class'] == ITEM_CLASS_WEAPON || $this->template['class'] == ITEM_CLASS_AMMUNITION) - { - $this->json['dmgtype1'] = $this->template['dmg_type1']; - $this->json['dmgmin1'] = $this->template['dmg_min1'] + $this->template['dmg_min2']; - $this->json['dmgmax1'] = $this->template['dmg_max1'] + $this->template['dmg_max2']; - $this->json['dps'] = !$this->template['delay'] ? 0 : number_format(($this->json['dmgmin1'] + $this->json['dmgmax1']) / (2 * $this->template['delay'] / 1000), 1); - $this->json['speed'] = number_format($this->template['delay'] / 1000, 2); - - if (in_array($this->json['subclass'], [2, 3, 18, 19])) - { - $this->json['rgddmgmin'] = $this->json['dmgmin1']; - $this->json['rgddmgmax'] = $this->json['dmgmax1']; - $this->json['rgdspeed'] = $this->json['speed']; - $this->json['rgddps'] = $this->json['dps']; - } - else if ($this->template['class'] != ITEM_CLASS_AMMUNITION) - { - $this->json['mledmgmin'] = $this->json['dmgmin1']; - $this->json['mledmgmax'] = $this->json['dmgmax1']; - $this->json['mlespeed'] = $this->json['speed']; - $this->json['mledps'] = $this->json['dps']; - } - - if ($this->json['classs'] == ITEM_CLASS_WEAPON && in_array($this->json['subclass'], [5, 6, 10]) && $this->json['dps'] > 54.8) - $this->json['feratkpwr'] = max(0, round((($this->json['dmgmin1'] + $this->json['dmgmax1']) / (2 * $this->template['delay'] / 1000) - 54.8) * 14, 0)); - } + $this->reset(); // restore 'iterator' } // use if you JUST need the name @@ -151,40 +68,108 @@ class Item extends BaseType } // end static use - public function getListviewData() + public function getListviewData($addInfoMask = 0x0) { - return array( - 'id' => $this->Id, - 'name' => $this->name, - ); + /* looks like this data differs per occasion + * + * maybe split in groups, like: + * ITEMINFO_JSON (0x1): itemMods (including spells) and subitems parsed + * ITEMINFO_SUBITEMS (0x2): searched by comparison + * ITEMINFO_VENDOR (0x4): costs-obj, when displayed as vendor + * ITEMINFO_LOOT (0x8): count, stack, pctstack, modes when displaying loot + */ + + $data = []; + while ($this->iterate()) + { + // random item is random + if ($this->curTpl['RandomProperty'] > 0 || $this->curTpl['RandomSuffix'] > 0) + if ($addInfoMask & ITEMINFO_SUBITEMS) + $this->initSubItems(); + + if ($addInfoMask & ITEMINFO_JSON) + $this->extendJsonStats(); + + $tmp = array_merge($this->json[$this->Id], array( + 'name' => $this->names[$this->Id], + 'quality' => 7 - $this->curTpl['Quality'], + 'reqskill' => $this->curTpl['RequiredSkill'], + 'reqskillrank' => $this->curTpl['RequiredSkillRank'], + 'reqspell' => $this->curTpl['requiredspell'], + 'reqfaction' => $this->curTpl['RequiredReputationFaction'], + 'reqrep' => $this->curTpl['RequiredReputationRank'], + 'side' => Util::sideByRaceMask($this->curTpl['AllowableRace']), // FlagsExtra zur Rate ziehen? 0:Beide; 1: Horde; 2:Allianz + 'heroic' => (string)($this->curTpl['Flags'] & 0x8), + 'nslots' => $this->curTpl['ContainerSlots'], + 'buyprice' => $this->curTpl['BuyPrice'], + 'sellprice' => $this->curTpl['SellPrice'] + )); + + // complicated data + if (!in_array($this->curTpl['AllowableRace'], [-1, 0, RACE_MASK_ALL, RACE_MASK_ALLIANCE, RACE_MASK_HORDE])) + $tmp['reqrace'] = $this->curTpl['AllowableRace']; + + if (!in_array($this->curTpl['AllowableClass'], [-1, 0, CLASS_MASK_ALL])) + $tmp['reqclass'] = $this->curTpl['AllowableClass']; // $tmp['classes'] ?? + + $data[$this->Id] = $tmp; + } + + /* even more complicated crap + "source":[5], + "sourcemore":[{"z":3703}], + + {"source":[5],"sourcemore":[{"n":"Commander Oxheart","t":1,"ti":64606,"z":5842}], + + cost:[] format unk 0:copper, 1:[items]? 2, 3, 4, 5 + stack [unk, unk] + avail unk + rel unk + glyph major | minor (as id) + modelviewer + + */ + + return $data; } - public function addGlobalsToJScript(&$gItems) + public function addGlobalsToJscript(&$refs) { - $gItems[$this->Id] = array( - 'name' => $this->name, - 'quality' => $this->template['Quality'], - 'icon' => $this->template['icon'], - ); + if (!isset($refs['gItems'])) + $refs['gItems'] = []; + + while ($this->iterate()) + { + $refs['gItems'][$this->Id] = array( + 'name' => $this->names[$this->Id], + 'quality' => $this->curTpl['Quality'], + 'icon' => $this->curTpl['icon'], + ); + } } /* - enhance (set by comparison tool or formatet external links) + enhance (set by comparison tool or formated external links) ench: enchantmentId sock: bool (extraScoket (gloves, belt)) gems: array (:-separated itemIds) rand: >0: randomPropId; <0: randomSuffixId interactive (set to place javascript/anchors to manipulate level and ratings or link to filters (static tooltips vs popup tooltip)) */ - public function createTooltip($enhance = [], $interactive = false) + public function renderTooltip($enhance = [], $interactive = false) { - if (!empty($this->tooltip)) - return $this->tooltip; + if ($this->error) + return; - if (isset($enhance['rand'])) + $name = $this->names[$this->Id]; + + if (!empty($this->tooltip[$this->Id])) + return $this->tooltip[$this->Id]; + + if (!empty($enhance['rand'])) { $rndEnch = DB::Aowow()->selectRow('SELECT * FROM ?_itemrandomenchant WHERE Id = ?d', $enhance['rand']); - $this->name .= ' '.Util::localizedString($rndEnch, 'name'); + $name .= ' '.Util::localizedString($rndEnch, 'name'); $randEnchant['stats'] = ''; for ($i = 1; $i < 6; $i++) @@ -210,90 +195,90 @@ class Item extends BaseType $x .= '
'; // name; quality - $x .= ''.$this->name.''; + $x .= ''.$name.''; // heroic tag - if (($this->template['Flags'] & ITEM_FLAG_HEROIC) && $this->template['Quality'] == ITEM_QUALITY_EPIC) + if (($this->curTpl['Flags'] & ITEM_FLAG_HEROIC) && $this->curTpl['Quality'] == ITEM_QUALITY_EPIC) $x .= '
'.Lang::$item['heroic'].''; // requires map (todo: reparse ?_zones for non-conflicting data; generate Link to zone) - if ($this->template['Map']) + if ($this->curTpl['Map']) { - $map = DB::Aowow()->selectRow('SELECT * FROM ?_zones WHERE mapid=?d LIMIT 1', $this->template['Map']); + $map = DB::Aowow()->selectRow('SELECT * FROM ?_zones WHERE mapid=?d LIMIT 1', $this->curTpl['Map']); $x .= '
'.Util::localizedString($map, 'name'); } // requires area - if ($this->template['area']) + if ($this->curTpl['area']) { - $area = DB::Aowow()->selectRow('SELECT * FROM ?_areatable WHERE Id=?d LIMIT 1', $this->template['area']); + $area = DB::Aowow()->selectRow('SELECT * FROM ?_areatable WHERE Id=?d LIMIT 1', $this->curTpl['area']); $x .= '
'.Util::localizedString($area, 'name'); } // conjured - if ($this->template['Flags'] & ITEM_FLAG_CONJURED) + if ($this->curTpl['Flags'] & ITEM_FLAG_CONJURED) $x .= '
'.Lang::$game['conjured']; // bonding - if (($this->template['Flags'] & ITEM_FLAG_ACCOUNTBOUND) && $this->template['Quality'] == ITEM_QUALITY_HEIRLOOM) + if (($this->curTpl['Flags'] & ITEM_FLAG_ACCOUNTBOUND) && $this->curTpl['Quality'] == ITEM_QUALITY_HEIRLOOM) $x .= '
'.Lang::$item['bonding'][0]; - else if ($this->template['bonding']) - $x .= '
'.Lang::$item['bonding'][$this->template['bonding']]; + else if ($this->curTpl['bonding']) + $x .= '
'.Lang::$item['bonding'][$this->curTpl['bonding']]; // unique || unique-equipped || unique-limited - if ($this->template['maxcount'] == 1) + if ($this->curTpl['maxcount'] == 1) $x .= '
'.Lang::$item['unique']; - else if ($this->template['Flags'] & ITEM_FLAG_UNIQUEEQUIPPED) + else if ($this->curTpl['Flags'] & ITEM_FLAG_UNIQUEEQUIPPED) $x .= '
'.Lang::$item['uniqueEquipped']; - else if ($this->template['ItemLimitCategory']) + else if ($this->curTpl['ItemLimitCategory']) { - $limit = DB::Aowow()->selectRow("SELECT * FROM ?_itemlimitcategory WHERE id = ?", $this->template['ItemLimitCategory']); + $limit = DB::Aowow()->selectRow("SELECT * FROM ?_itemlimitcategory WHERE id = ?", $this->curTpl['ItemLimitCategory']); $x .= '
'.($limit['isGem'] ? Lang::$item['uniqueEquipped'] : Lang::$item['unique']).': '.Util::localizedString($limit, 'name').' ('.$limit['count'].')'; } // max duration - if ($this->template['duration'] > 0) - $x .= "
".Lang::$item['duration'] . ' '. Util::formatTime($this->template['duration'] * 1000) . ($this->template['duration'] < 0 ? ' ('.Lang::$game['realTime'].')' : null); + if ($this->curTpl['duration'] > 0) + $x .= "
".Lang::$item['duration'] . ' '. Util::formatTime($this->curTpl['duration'] * 1000) . ($this->curTpl['duration'] < 0 ? ' ('.Lang::$game['realTime'].')' : null); // required holiday - if ($this->template['HolidayId']) + if ($this->curTpl['HolidayId']) { - $hDay = DB::Aowow()->selectRow("SELECT * FROM ?_holidays WHERE id = ?", $this->template['HolidayId']); - $x .= '
'.Lang::$game['requires'].' '.Util::localizedString($hDay, 'name').''; + $hDay = DB::Aowow()->selectRow("SELECT * FROM ?_holidays WHERE id = ?", $this->curTpl['HolidayId']); + $x .= '
'.Lang::$game['requires'].' '.Util::localizedString($hDay, 'name').''; } // maxcount - if ($this->template['maxcount'] > 1) - $x .= ' ('.$this->template['maxcount'].')'; + if ($this->curTpl['maxcount'] > 1) + $x .= ' ('.$this->curTpl['maxcount'].')'; // item begins a quest - if ($this->template['startquest']) - $x .= '
'.Lang::$item['startQuest'].''; + if ($this->curTpl['startquest']) + $x .= '
'.Lang::$item['startQuest'].''; // containerType (slotCount) - if ($this->template['ContainerSlots'] > 1) + if ($this->curTpl['ContainerSlots'] > 1) { // word order differs <_< if (in_array(User::$localeId, [LOCALE_FR, LOCALE_ES, LOCALE_RU])) - $x .= '
'.sprintf(Lang::$item['bagSlotString'], Lang::$item['bagFamily'][$this->template['BagFamily']], $this->template['ContainerSlots']); + $x .= '
'.sprintf(Lang::$item['bagSlotString'], Lang::$item['bagFamily'][$this->curTpl['BagFamily']], $this->curTpl['ContainerSlots']); else - $x .= '
'.sprintf(Lang::$item['bagSlotString'], $this->template['ContainerSlots'], Lang::$item['bagFamily'][$this->template['BagFamily']]); + $x .= '
'.sprintf(Lang::$item['bagSlotString'], $this->curTpl['ContainerSlots'], Lang::$item['bagFamily'][$this->curTpl['BagFamily']]); } - if (in_array($this->template['class'], [ITEM_CLASS_ARMOR, ITEM_CLASS_WEAPON, ITEM_CLASS_AMMUNITION])) + if (in_array($this->curTpl['class'], [ITEM_CLASS_ARMOR, ITEM_CLASS_WEAPON, ITEM_CLASS_AMMUNITION])) { $x .= ''; // Class - $x .= ''; + $x .= ''; // Subclass - if ($this->template['class'] == ITEM_CLASS_ARMOR && $this->template['subclass'] > 0) - $x .= ''; - else if ($this->template['class'] == ITEM_CLASS_WEAPON) - $x .= ''; - else if ($this->template['class'] == ITEM_CLASS_AMMUNITION) - $x .= ''; + if ($this->curTpl['class'] == ITEM_CLASS_ARMOR && $this->curTpl['subclass'] > 0) + $x .= ''; + else if ($this->curTpl['class'] == ITEM_CLASS_WEAPON) + $x .= ''; + else if ($this->curTpl['class'] == ITEM_CLASS_AMMUNITION) + $x .= ''; $x .= '
'.Lang::$item['inventoryType'][$this->template['InventoryType']].''.Lang::$item['inventoryType'][$this->curTpl['InventoryType']].''.Lang::$item['armorSubclass'][$this->template['subclass']].''.Lang::$item['weaponSubClass'][$this->template['subclass']].''.Lang::$item['projectileSubClass'][$this->template['subclass']].''.Lang::$item['armorSubclass'][$this->curTpl['subclass']].''.Lang::$item['weaponSubClass'][$this->curTpl['subclass']].''.Lang::$item['projectileSubClass'][$this->curTpl['subclass']].'
'; } @@ -301,61 +286,64 @@ class Item extends BaseType $x .= '
'; // Weapon Stats - if (isset($this->json['speed'])) + if ($this->curTpl['delay'] > 0) { + $speed = $this->curTpl['delay'] / 1000; + $dmgmin1 = $this->curTpl['dmg_min1'] + $this->curTpl['dmg_min2']; + $dmgmax1 = $this->curTpl['dmg_max1'] + $this->curTpl['dmg_max2']; + $dps = $speed ? ($dmgmin1 + $dmgmax1) / (2 * $speed) : 0; + // regular weapon - if ($this->template['class'] != ITEM_CLASS_AMMUNITION) + if ($this->curTpl['class'] != ITEM_CLASS_AMMUNITION) { $x .= ''; - $x .= ''; - $x .= ''; + $x .= ''; + $x .= ''; $x .= '
'.sprintf($this->template['dmg_type1'] ? Lang::$item['damageMagic'] : Lang::$item['damagePhys'], $this->template['dmg_min1'].' - '.$this->template['dmg_max1'], Lang::$game['sc'][$this->template['dmg_type1']]).''.Lang::$item['speed'].' '.$this->json['speed'].''.sprintf($this->curTpl['dmg_type1'] ? Lang::$item['damageMagic'] : Lang::$item['damagePhys'], $this->curTpl['dmg_min1'].' - '.$this->curTpl['dmg_max1'], Lang::$game['sc'][$this->curTpl['dmg_type1']]).''.Lang::$item['speed'].' '.number_format($speed, 2).'
'; // secondary damage is set - if ($this->template['dmg_min2']) - $x .= '+'.sprintf($this->template['dmg_type2'] ? Lang::$item['damageMagic'] : Lang::$item['damagePhys'], $this->template['dmg_min2'].' - '.$this->template['dmg_max2'], Lang::$game['sc'][$this->template['dmg_type2']]).'
'; + if ($this->curTpl['dmg_min2']) + $x .= '+'.sprintf($this->curTpl['dmg_type2'] ? Lang::$item['damageMagic'] : Lang::$item['damagePhys'], $this->curTpl['dmg_min2'].' - '.$this->curTpl['dmg_max2'], Lang::$game['sc'][$this->curTpl['dmg_type2']]).'
'; - $x .= '('.$this->json['dps'].' '.Lang::$item['dps'].')
'; + $x .= '('.number_format($dps, 1).' '.Lang::$item['dps'].')
'; // display FeralAttackPower if set - if (isset($this->json['feratkpwr'])) - $x .= '('.$this->json['feratkpwr'].' '.Lang::$item['fap'].')
'; + if (in_array($this->curTpl['subclass'], [5, 6, 10]) && $dps > 54.8) + $x .= '('.round(($dps - 54.8) * 14, 0).' '.Lang::$item['fap'].')
'; } // ammunition else - $x .= Lang::$item['addsDps'].' '.number_format(($this->json['dmgmin1'] + $this->json['dmgmax1']) / 2, 1).' '.Lang::$item['dps2'].'
'; + $x .= Lang::$item['addsDps'].' '.number_format(($dmgmin1 + $dmgmax1) / 2, 1).' '.Lang::$item['dps2'].'
'; } // Armor - if ($this->template['class'] == ITEM_CLASS_ARMOR && $this->template['ArmorDamageModifier'] > 0) - $x .= ''.($this->template['armor'] + $this->template['ArmorDamageModifier']).' '.Lang::$item['armor'].'
'; - else if ($this->template['armor']) - $x .= ''.$this->template['armor'].' '.Lang::$item['armor'].'
'; + if ($this->curTpl['class'] == ITEM_CLASS_ARMOR && $this->curTpl['ArmorDamageModifier'] > 0) + $x .= ''.($this->curTpl['armor'] + $this->curTpl['ArmorDamageModifier']).' '.Lang::$item['armor'].'
'; + else if ($this->curTpl['armor']) + $x .= ''.$this->curTpl['armor'].' '.Lang::$item['armor'].'
'; // Block - if ($this->template['block']) - $x .= ''.$this->template['block'].' '.Lang::$item['block'].'
'; - - // Random Enchantment - if (($this->template['RandomProperty'] || $this->template['RandomSuffix']) && !isset($enhance['rand'])) - $x .= ''.Lang::$item['randEnchant'].'
'; + if ($this->curTpl['block']) + $x .= ''.$this->curTpl['block'].' '.Lang::$item['block'].'
'; // Item is a gem (don't mix with sockets) - if ($this->template['GemProperties']) + if ($this->curTpl['GemProperties']) { - $gemText = DB::Aowow()->selectRow('SELECT e.* FROM ?_itemenchantment e, ?_gemproperties p WHERE (p.Id = ?d and e.Id = p.itemenchantmentID)', $this->template['GemProperties']); + $gemText = DB::Aowow()->selectRow('SELECT e.* FROM ?_itemenchantment e, ?_gemproperties p WHERE (p.Id = ?d and e.Id = p.itemenchantmentID)', $this->curTpl['GemProperties']); $x .= Util::localizedString($gemText, 'text').'
'; } - // if random enchantment is set, prepend stats from it - if (isset($enhance['rand'])) + // Random Enchantment - if random enchantment is set, prepend stats from it + if (($this->curTpl['RandomProperty'] || $this->curTpl['RandomSuffix']) && !isset($enhance['rand'])) + $x .= ''.Lang::$item['randEnchant'].'
'; + else if (isset($enhance['rand'])) $x .= $randEnchant['stats']; // itemMods (display stats and save ratings for later use) for ($j = 1; $j <= 10; $j++) { - $type = $this->template['stat_type'.$j]; - $qty = $this->template['stat_value'.$j]; + $type = $this->curTpl['stat_type'.$j]; + $qty = $this->curTpl['stat_value'.$j]; if (!$qty || $type <= 0) continue; @@ -364,13 +352,13 @@ class Item extends BaseType if ($type >= ITEM_MOD_AGILITY && $type <= ITEM_MOD_STAMINA) $x .= '+'.$qty.' '.Lang::$item['statType'][$type].'
'; else // rating with % for reqLevel - $green[] = $this->parseRating($type, $qty, $this->template['RequiredLevel'], $interactive); + $green[] = $this->parseRating($type, $qty, $interactive); } // magic resistances foreach (Util::$resistanceFields as $j => $rowName) - if ($rowName && $this->template[$rowName] != 0) - $x .= '+'.$this->template[$rowName].' '.Lang::$game['resistances'][$j].'
'; + if ($rowName && $this->curTpl[$rowName] != 0) + $x .= '+'.$this->curTpl[$rowName].' '.Lang::$game['resistances'][$j].'
'; // Enchantment if (isset($enhance['ench'])) @@ -407,7 +395,7 @@ class Item extends BaseType $enhance['gems'] = []; // zero fill empty sockets - $sockCount = $this->json['nsockets'] + (isset($enhance['sock']) ? 1 : 0); + $sockCount = $this->curTpl['socketColor_1'] + $this->curTpl['socketColor_2'] + $this->curTpl['socketColor_3'] + (isset($enhance['sock']) ? 1 : 0); while ($sockCount > count($enhance['gems'])) $enhance['gems'][] = 0; @@ -417,11 +405,11 @@ class Item extends BaseType // fill native sockets for ($j = 1; $j <= 3; $j++) { - if (!$this->template['socketColor_'.$j]) + if (!$this->curTpl['socketColor_'.$j]) continue; for ($i = 0; $i < 4; $i++) - if (($this->template['socketColor_'.$j] & (1 << $i))) + if (($this->curTpl['socketColor_'.$j] & (1 << $i))) $colorId = $i; $pop = array_pop($enhance['gems']); @@ -452,59 +440,59 @@ class Item extends BaseType else // prismatic socket placeholder $x .= ''; - if ($this->template['socketBonus']) + if ($this->curTpl['socketBonus']) { - $sbonus = DB::Aowow()->selectRow('SELECT * FROM ?_itemenchantment WHERE Id = ?d', $this->template['socketBonus']); + $sbonus = DB::Aowow()->selectRow('SELECT * FROM ?_itemenchantment WHERE Id = ?d', $this->curTpl['socketBonus']); $x .= ''.Lang::$item['socketBonus'].': '.Util::localizedString($sbonus, 'text').'
'; } // durability - if ($this->template['MaxDurability']) - $x .= Lang::$item['durability'].' '.$this->template['MaxDurability'].' / '.$this->template['MaxDurability'].'
'; + if ($this->curTpl['MaxDurability']) + $x .= Lang::$item['durability'].' '.$this->curTpl['MaxDurability'].' / '.$this->curTpl['MaxDurability'].'
'; // required classes - if ($classes = Lang::getClassString($this->template['AllowableClass'])) + if ($classes = Lang::getClassString($this->curTpl['AllowableClass'])) $x .= Lang::$game['classes'].': '.$classes.'
'; // required races - if ($races = Lang::getRaceString($this->template['AllowableRace'])) + if ($races = Lang::getRaceString($this->curTpl['AllowableRace'])) $x .= Lang::$game['races'].': '.$races['name'].'
'; // required honorRank (not used anymore) - if ($this->template['requiredhonorrank']) - $x .= Lang::$game['requires'].': '.Lang::$game['pvpRank'][$this->template['requiredhonorrank']].'
'; + if ($this->curTpl['requiredhonorrank']) + $x .= Lang::$game['requires'].': '.Lang::$game['pvpRank'][$this->curTpl['requiredhonorrank']].'
'; // required CityRank..? // what the f.. // required level - if (($this->template['Flags'] & ITEM_FLAG_ACCOUNTBOUND) && $this->template['Quality'] == ITEM_QUALITY_HEIRLOOM) + if (($this->curTpl['Flags'] & ITEM_FLAG_ACCOUNTBOUND) && $this->curTpl['Quality'] == ITEM_QUALITY_HEIRLOOM) $x .= sprintf(Lang::$game['reqLevelHlm'], ' 1'.Lang::$game['valueDelim'].MAX_LEVEL.' ('.($interactive ? printf(Util::$changeLevelString, MAX_LEVEL) : ''.MAX_LEVEL).')').'
'; - else if ($this->template['RequiredLevel'] > 1) - $x .= sprintf(Lang::$game['reqLevel'], $this->template['RequiredLevel']).'
'; + else if ($this->curTpl['RequiredLevel'] > 1) + $x .= sprintf(Lang::$game['reqLevel'], $this->curTpl['RequiredLevel']).'
'; // item level - $x .= Lang::$item['itemLevel'].' '.$this->template['ItemLevel']; + $x .= Lang::$item['itemLevel'].' '.$this->curTpl['ItemLevel']; // required skill - if ($this->template['RequiredSkill']) + if ($this->curTpl['RequiredSkill']) { - $skillText = DB::Aowow()->selectRow('SELECT * FROM ?_skill WHERE skillID = ?d', $this->template['RequiredSkill']); - $x .= '
'.Lang::$game['requires'].' '.Util::localizedString($skillText, 'name').''; - if ($this->template['RequiredSkillRank']) - $x .= ' ('.$this->template['RequiredSkillRank'].')'; + $skillText = DB::Aowow()->selectRow('SELECT * FROM ?_skill WHERE skillID = ?d', $this->curTpl['RequiredSkill']); + $x .= '
'.Lang::$game['requires'].' '.Util::localizedString($skillText, 'name').''; + if ($this->curTpl['RequiredSkillRank']) + $x .= ' ('.$this->curTpl['RequiredSkillRank'].')'; } // required spell - if ($this->template['requiredspell']) - $x .= '
'.Lang::$game['requires'].' '.Spell::getName($this->template['requiredspell']).''; + if ($this->curTpl['requiredspell']) + $x .= '
'.Lang::$game['requires'].' '.Spell::getName($this->curTpl['requiredspell']).''; // required reputation w/ faction - if ($this->template['RequiredReputationFaction']) - $x .= '
'.Lang::$game['requires'].' template['RequiredReputationFaction'].'">'.Faction::getName($this->template['RequiredReputationFaction']).' - '.Lang::$game['rep'][$this->template['RequiredReputationRank']]; + if ($this->curTpl['RequiredReputationFaction']) + $x .= '
'.Lang::$game['requires'].' curTpl['RequiredReputationFaction'].'">'.Faction::getName($this->curTpl['RequiredReputationFaction']).' - '.Lang::$game['rep'][$this->curTpl['RequiredReputationRank']]; // locked - if ($this->template['lockid']) + if ($this->curTpl['lockid']) { $lock = DB::Aowow()->selectRow(' SELECT @@ -513,14 +501,14 @@ class Item extends BaseType ?_lock WHERE lockID = ?d', - $this->template['lockid'] + $this->curTpl['lockid'] ); // only use first useful entry for ($j = 1; $j <= 5; $j++) { if ($lock['type'.$j] == 1) // opened by item { - $l = Lang::$game['requires'].' '.Item::getName($lock['lockproperties'.$j]).''; + $l = Lang::$game['requires'].' '.Util::getItemName($lock['lockproperties'.$j]).''; break; } else if ($lock['type'.$j] == 2) // opened by skill @@ -537,17 +525,20 @@ class Item extends BaseType $x .= '
'; // spells on item + $itemSpellsAndTrigger = []; for ($j = 1; $j <= 5; $j++) + if ($this->curTpl['spellid_'.$j] > 0) + $itemSpellsAndTrigger[$this->curTpl['spellid_'.$j]] = $this->curTpl['spelltrigger_'.$j]; + + if ($itemSpellsAndTrigger) { - // todo: complete Class SpellList and fetch from List - if ($this->template['spellid_'.$j] > 0) - { - $itemSpell = new Spell($this->template['spellid_'.$j]); - if ($parsed = $itemSpell->parseText('description', $this->template['RequiredLevel'])) - $green[] = Lang::$item['trigger'][$this->template['spelltrigger_'.$j]] . $parsed; - } + $itemSpells = new SpellList(array(['Id', array_keys($itemSpellsAndTrigger)])); + while ($itemSpells->iterate()) + if ($parsed = $itemSpells->parseText('description', $this->curTpl['RequiredLevel'])) + $green[] = Lang::$item['trigger'][$itemSpellsAndTrigger[$itemSpells->Id]].$parsed; } + // lower table (ratings, spells, ect) $x .= '
'; if (isset($green)) @@ -555,29 +546,6 @@ class Item extends BaseType if ($bonus) $x .= ''.$bonus.'
'; - // recipe handling (some stray Techniques have subclass == 0) - if ($this->template['class'] == ITEM_CLASS_RECIPE && ($this->template['subclass'] == 1 || $this->template['BagFamily'] = 16)) - { - // todo: aaaand another one for optimization - $craftSpell = new Spell($this->template['spellid_2']); - $craftItem = new Item($craftSpell->template["effect1CreateItemId"]); - $reagentItems = []; - - for ($i = 1; $i <= 8; $i++) - if ($craftSpell->template["reagent".$i]) - $reagentItems[$craftSpell->template["reagent".$i]] = $craftSpell->template["reagentCount".$i]; - - $reagents = new ItemList(array(['i.entry', array_keys($reagentItems)])); - $reqReag = []; - - foreach ($reagents->container as $r) - $reqReag[] = ''.$r->name.' ('.$reagentItems[$r->Id].')'; - - $x .= ''.Lang::$item['trigger'][0].' '.Util::localizedString($this->template, 'description').''; - if (isset($craftItem->Id)) - $x .= '

'.$craftItem->createTooltip(null, $interactive).'

'; - } - // Item Set $tmpX = ''; $pieces = []; @@ -600,8 +568,8 @@ class Item extends BaseType continue; $num++; - $equivalents = Item::getEquivalentSetPieces($itemset['item'.$i]); - $pieces[] = ''.Item::getName($itemset['item'.$i]).''; + $equivalents = ItemList::getEquivalentSetPieces($itemset['item'.$i]); + $pieces[] = ''.ItemList::getName($itemset['item'.$i]).''; } $tmpX .= implode('
', $pieces); @@ -610,9 +578,11 @@ class Item extends BaseType if ($itemset['skillID']) // bonus requires skill to activate { $name = DB::Aowow()->selectRow('SELECT * FROM ?_skill WHERE skillID=?d', $itemset['skillID']); - $x .= '
'.Lang::$game['requires'].' '.Util::localizedString($name, 'name').''; + $x .= '
'.Lang::$game['requires'].' '.Util::localizedString($name, 'name').''; + if ($itemset['skillLevel']) $x .= ' ('.$itemset['skillLevel'].')'; + $x .= '
'; } @@ -620,25 +590,30 @@ class Item extends BaseType $x .= '
'.$tmpX.'

'; // get bonuses - $num = 0; + $setSpellsAndIdx = []; for ($j = 1; $j <= 8; $j++) - { - if ($itemset['spell'.$j] <= 0) - continue; + if ($itemset['spell'.$j] > 0) + $setSpellsAndIdx[$itemset['spell'.$j]] = $j; - // todo: get from static prop? - $bonus = new Spell($itemset['spell'.$j]); - $itemset['spells'][$num]['tooltip'] = $bonus->parseText('description', $this->template['RequiredLevel']); - $itemset['spells'][$num]['entry'] = $itemset['spell'.$j]; - $itemset['spells'][$num]['bonus'] = $itemset['bonus'.$j]; - $num++; + // todo: get from static prop? + if ($setSpellsAndIdx) + { + $boni = new SpellList(array(['Id', array_keys($setSpellsAndIdx)])); + while ($boni->iterate()) + { + $itemset['spells'][] = array( + 'tooltip' => $boni->parseText('description', $this->curTpl['RequiredLevel']), + 'entry' => $itemset['spell'.$setSpellsAndIdx[$boni->Id]], + 'bonus' => $itemset['bonus'.$setSpellsAndIdx[$boni->Id]] + ); + } } // sort and list bonuses $x .= ''; - for ($i = 0; $i < $num; $i++) + for ($i = 0; $i < count($itemset['spells']); $i++) { - for ($j = $i; $j <= $num - 1; $j++) + for ($j = $i; $j < count($itemset['spells']); $j++) { if($itemset['spells'][$j]['bonus'] >= $itemset['spells'][$i]['bonus']) continue; @@ -648,105 +623,93 @@ class Item extends BaseType $itemset['spells'][$j] = $tmp; } $x .= '('.$itemset['spells'][$i]['bonus'].') '.Lang::$item['set'].': '.$itemset['spells'][$i]['tooltip'].''; - if ($i < $num - 1) + if ($i < count($itemset['spells']) - 1) $x .= '
'; } $x .= '
'; } - // funny, yellow text at the bottom - if ($this->template['description']) - $x .= '"'.Util::localizedString($this->template, 'description').'"'; + // recipe handling (some stray Techniques have subclass == 0), place at bottom of tooltipp + if ($this->curTpl['class'] == ITEM_CLASS_RECIPE && ($this->curTpl['subclass'] || $this->curTpl['BagFamily'] == 16)) + { + $craftSpell = new SpellList(array(['Id', (int)$this->curTpl['spellid_2']])); + $craftItem = new ItemList(array(['i.entry', (int)$craftSpell->curTpl["effect1CreateItemId"]])); + $reagentItems = []; + + for ($i = 1; $i <= 8; $i++) + if ($rId = $craftSpell->getField('reagent'.$i)) + $reagentItems[$rId] = $craftSpell->getField('reagentCount'.$i); + + $reagents = new ItemList(array(['i.entry', array_keys($reagentItems)])); + $reqReag = []; + + $x .= ''.Lang::$item['trigger'][0].' '.Util::localizedString($this->curTpl, 'description').''; + + $xCraft = '

'.$craftItem->renderTooltip(null, $interactive).'

'; + + while ($reagents->iterate()) + $reqReag[] = ''.$reagents->names[$reagents->Id].' ('.$reagentItems[$reagents->Id].')'; + + $xCraft .= ''.Lang::$game['requires']." ".implode(", ", $reqReag).''; + + } + + // misc (no idea, how to organize the
better) + $xMisc = []; + + // funny, yellow text at the bottom, omit if we have a recipe + if ($this->curTpl['description'] && !isset($xCraft)) + $xMisc[] = '"'.Util::localizedString($this->curTpl, 'description').'"'; // readable - if ($this->template['PageText']) - $x .= '
'.Lang::$item['readClick'].''; + if ($this->curTpl['PageText']) + $xMisc[] = ''.Lang::$item['readClick'].''; // charges (i guess checking first spell is enough (single charges not shown)) - if ($this->template['spellcharges_1'] > 1) - $x .= '
'.$this->template['spellcharges_1'].' '.Lang::$item['charges'].''; + if ($this->curTpl['spellcharges_1'] > 1) + $xMisc[] = ''.$this->curTpl['spellcharges_1'].' '.Lang::$item['charges'].''; + + if ($this->curTpl['SellPrice']) + $xMisc[] = ''.Lang::$item['sellPrice'].": ".Util::formatMoney($this->curTpl['SellPrice']).''; // list required reagents - if (!empty($reqReag)) - $x .= ''.Lang::$game['requires']." ".implode(", ", $reqReag).''; + if (isset($xCraft)) + $xMisc[] = $xCraft; + + if ($xMisc) + $x .= implode('
', $xMisc); + $x .= '
'; - if ($this->template['SellPrice']) - $x .= ''.Lang::$item['sellPrice'].": ".Util::formatMoney($this->template['SellPrice']).''; - // heirloom tooltip scaling - if ($this->ssd) + if (isset($this->ssd[$this->Id])) { $link = array( $this->Id, // itemId 1, // scaleMinLevel - $this->ssd['maxLevel'], // scaleMaxLevel - $this->ssd['maxLevel'], // scaleCurLevel - $this->template['ScalingStatDistribution'], // scaleDist - $this->template['ScalingStatValue'], // scaleFlags + $this->ssd[$this->Id]['maxLevel'], // scaleMaxLevel + $this->ssd[$this->Id]['maxLevel'], // scaleCurLevel + $this->curTpl['ScalingStatDistribution'], // scaleDist + $this->curTpl['ScalingStatValue'], // scaleFlags ); $x .= ''; } else $x .= ''; - $this->tooltip = $x; + $this->tooltip[$this->Id] = $x; - return $this->tooltip; - } - - private function parseRating($type, $value, $level, $interactive = false) - { - $level = min(max($level, 1), MAX_LEVEL); // clamp level range - - if (!Lang::$item['statType'][$type]) // unknown rating - return sprintf(Lang::$item['statType'][count(Lang::$item['statType']) - 1], $type, $value); - else if (in_array($type, Util::$lvlIndepRating)) // level independant Bonus - return Lang::$item['trigger'][1] . str_replace('%d', ''.$value, Lang::$item['statType'][$type]); - else // rating-Bonuses - { - // old - // $js = ' ('; - // $js .= Util::setRatingLevel($level, $type, $value); - // $js .= ')'; - if ($interactive) - $js = ' ('.printf(Util::$changeLevelString, Util::setRatingLevel($level, $type, $value)).'))'; - else - $js = " (".Util::setRatingLevel($level, $type, $value).")"; - - return Lang::$item['trigger'][1].str_replace('%d', ''.$value.$js, Lang::$item['statType'][$type]); - } - } - - private function getSSDMod($type) - { - $mask = $this->template['ScalingStatValue']; - - switch ($type) - { - case 'stats': $mask &= 0x04001F; break; - case 'armor': $mask &= 0xF001E0; break; - case 'dps' : $mask &= 0x007E00; break; - case 'spell': $mask &= 0x008000; break; - default: $mask &= 0x0; - } - - $field = null; - for ($i = 0; $i < count(Util::$ssdMaskFields); $i++) - if ($mask & (1 << $i)) - $field = Util::$ssdMaskFields[$i]; - - return $field ? DB::Aowow()->selectCell("SELECT ?# FROM ?_scalingstatvalues WHERE charLevel = ?", $field, $this->ssd['maxLevel']) : 0; + return $this->tooltip[$this->Id]; } // from Trinity public function generateEnchSuffixFactor() { - $rpp = DB::Aowow()->selectRow('SELECT * FROM ?_itemRandomPropPoints WHERE Id = ?', $this->template['ItemLevel']); + $rpp = DB::Aowow()->selectRow('SELECT * FROM ?_itemRandomPropPoints WHERE Id = ?', $this->curTpl['ItemLevel']); if (!$rpp) return 0; - switch ($this->template['InventoryType']) + switch ($this->curTpl['InventoryType']) { // Items of that type don`t have points case INVTYPE_NON_EQUIP: @@ -795,7 +758,7 @@ class Item extends BaseType } // Select rare/epic modifier - switch ($this->template['Quality']) + switch ($this->curTpl['Quality']) { case ITEM_QUALITY_UNCOMMON: return $rpp['uncommon'.$suffixFactor]; @@ -812,137 +775,289 @@ class Item extends BaseType return 0; } - public function getJsonStats($pieceAssoc = NULL) + public function extendJsonStats($pieceAssoc = NULL) { // convert ItemMods for ($h = 1; $h <= 10; $h++) { - if (!$this->template['stat_type'.$h]) + if (!$this->curTpl['stat_type'.$h]) continue; - @$this->itemMods[$this->template['stat_type'.$h]] += $this->template['stat_value'.$h]; + @$this->itemMods[$this->Id][$this->curTpl['stat_type'.$h]] += $this->curTpl['stat_value'.$h]; } // convert Spells + $equipSpells = []; for ($h = 1; $h <= 5; $h++) { // only onEquip - if ($this->template['spelltrigger_'.$h] != 1) + if ($this->curTpl['spelltrigger_'.$h] != 1) continue; - if ($this->template['spellid_'.$h] <= 0) + if ($this->curTpl['spellid_'.$h] <= 0) continue; - $spl = new Spell($this->template['spellid_'.$h]); - $stats = $spl->getStatGain(); + $equipSpells[] = $this->curTpl['spellid_'.$h]; + } + + if ($equipSpells) + { + $eqpSplList = new SpellList(array(['Id', $equipSpells])); + $stats = $eqpSplList->getStatGain(); foreach ($stats as $mId => $qty) - @$this->itemMods[$mId] += $qty; + @$this->itemMods[$this->Id][$mId] += $qty; } // fetch and add socketbonusstats - if ($this->json['socketbonus'] > 0) + if (@$this->json[$this->Id]['socketbonus'] > 0) { - $enh = DB::Aowow()->selectRow('SELECT * FROM ?_itemenchantment WHERE Id = ?;', $this->json['socketbonus']); - $this->json['socketbonusstat'] = []; + $enh = DB::Aowow()->selectRow('SELECT * FROM ?_itemenchantment WHERE Id = ?;', $this->json[$this->Id]['socketbonus']); + $this->json[$this->Id]['socketbonusstat'] = []; $socketbonusstat = Util::parseItemEnchantment($enh); foreach ($socketbonusstat as $k => $v) - $this->json['socketbonusstat'][] = '"'.$k.'":'.$v; + $this->json[$this->Id]['socketbonusstat'][] = '"'.$k.'":'.$v; - $this->json['socketbonusstat'] = "{".implode(',', $this->json['socketbonusstat'])."}"; + $this->json[$this->Id]['socketbonusstat'] = "{".implode(',', $this->json[$this->Id]['socketbonusstat'])."}"; } // readdress itemset .. is wrong for virtual sets if ($pieceAssoc) - $this->json['itemset'] = $pieceAssoc[$this->Id]; + $this->json[$this->Id]['itemset'] = $pieceAssoc[$this->Id]; // gather random Enchantments - if ($this->json['commondrop']) + // todo: !important! extremly high sql-load + if (@$this->json[$this->Id]['commondrop'] && isset($this->subItems[$this->Id])) { - $randId = $this->template['RandomProperty'] > 0 ? $this->template['RandomProperty'] : $this->template['RandomSuffix']; - $randomIds = DB::Aowow()->selectCol('SELECT ench FROM item_enchantment_template WHERE entry = ?d', $randId); - if (!$randomIds) - return null; - - if ($this->template['RandomSuffix'] > 0) - { - array_walk($randomIds, function($val, $key) use(&$randomIds) { - $randomIds[$key] = -$val; - }); - } - - $subItems = DB::Aowow()->select('SELECT *, Id AS ARRAY_KEY FROM ?_itemRandomEnchant WHERE Id IN (?a)', $randomIds); - - foreach ($subItems as $k => $sI) + foreach ($this->subItems[$this->Id] as $k => $sI) { $jsonEquip = []; $jsonText = []; + for ($i = 1; $i < 6; $i++) { if ($sI['enchantId'.$i] <= 0) continue; - $enchant = DB::Aowow()->selectRow('SELECT *, Id AS ARRAY_KEY FROM ?_itemenchantment WHERE Id = ?d', $sI['enchantId'.$i]); - if (!$enchant) + if (!$this->rndEnchIds[$sI['enchantId'.$i]]) continue; + $eData = $this->rndEnchIds[$sI['enchantId'.$i]]; + if ($sI['allocationPct'.$i] > 0) // RandomSuffix: scaling Enchantment; enchId < 0 { $amount = intVal($sI['allocationPct'.$i] * $this->generateEnchSuffixFactor() / 10000); - $jsonEquip = array_merge($jsonEquip, Util::parseItemEnchantment($enchant, $amount)); - $jsonText[] = str_replace('$i', $amount, Util::localizedString($enchant, 'text')); + $jsonEquip = array_merge($jsonEquip, Util::parseItemEnchantment($eData, $amount)); + $jsonText[] = str_replace('$i', $amount, Util::localizedString($eData, 'text')); } else // RandomProperty: static Enchantment; enchId > 0 { - $jsonText[] = Util::localizedString($enchant, 'text'); - $jsonEquip = array_merge($jsonEquip, Util::parseItemEnchantment($enchant)); + $jsonText[] = Util::localizedString($eData, 'text'); + $jsonEquip = array_merge($jsonEquip, Util::parseItemEnchantment($eData)); } } - $subItems[$k] = array( + $this->subItems[$this->Id][$k] = array( 'name' => Util::localizedString($sI, 'name'), 'enchantment' => implode(', ', $jsonText), 'jsonequip' => $jsonEquip ); } - $this->json['subitems'] = json_encode($subItems, JSON_FORCE_OBJECT); + $this->json[$this->Id]['subitems'] = json_encode($this->subItems[$this->Id], JSON_FORCE_OBJECT); } - foreach ($this->json as $key => $value) + foreach ($this->json[$this->Id] as $k => $v) { - if (!isset($value) || $value === "false") + if (!isset($v) || $v === "false") { - unset($this->json[$key]); + unset($this->json[$this->Id][$k]); continue; } - if (!in_array($key, array('class', 'subclass')) && $value === "0") + if (!in_array($k, ['classs', 'subclass', 'armor']) && $v === "0") { - unset($this->json[$key]); + unset($this->json[$this->Id][$k]); continue; } } } -} - - -class ItemList extends BaseTypeList -{ - protected $setupQuery = 'SELECT *, i.entry AS ARRAY_KEY FROM item_template i LEFT JOIN ?_item_template_addon iX ON i.entry = iX.id LEFT JOIN locales_item l ON i.entry = l.entry WHERE [filter] [cond] GROUP BY i.entry ORDER BY i.Quality DESC'; - - public function __construct($conditions) + private function parseRating($type, $value, $interactive = false) { - // may be called without filtering - if (class_exists('ItemFilter')) + // clamp level range + $ssdLvl = isset($this->ssd[$this->Id]) ? $this->ssd[$this->Id]['maxLevel'] : 1; + $level = min(max($this->curTpl['RequiredLevel'], $ssdLvl), MAX_LEVEL); + + if (!Lang::$item['statType'][$type]) // unknown rating + return sprintf(Lang::$item['statType'][count(Lang::$item['statType']) - 1], $type, $value); + else if (in_array($type, Util::$lvlIndepRating)) // level independant Bonus + return Lang::$item['trigger'][1] . str_replace('%d', ''.$value, Lang::$item['statType'][$type]); + else // rating-Bonuses { - $this->filter = new ItemFilter(); - if (($fiData = $this->filter->init()) === false) - return; + // old + // $js = ' ('; + // $js .= Util::setRatingLevel($level, $type, $value); + // $js .= ')'; + if ($interactive) + $js = ' ('.printf(Util::$changeLevelString, Util::setRatingLevel($level, $type, $value)).'))'; + else + $js = " (".Util::setRatingLevel($level, $type, $value).")"; + + return Lang::$item['trigger'][1].str_replace('%d', ''.$value.$js, Lang::$item['statType'][$type]); + } + } + + private function getSSDMod($type) + { + $mask = $this->curTpl['ScalingStatValue']; + + switch ($type) + { + case 'stats': $mask &= 0x04001F; break; + case 'armor': $mask &= 0xF001E0; break; + case 'dps' : $mask &= 0x007E00; break; + case 'spell': $mask &= 0x008000; break; + default: $mask &= 0x0; } - parent::__construct($conditions); + $field = null; + for ($i = 0; $i < count(Util::$ssdMaskFields); $i++) + if ($mask & (1 << $i)) + $field = Util::$ssdMaskFields[$i]; + + return $field ? DB::Aowow()->selectCell("SELECT ?# FROM ?_scalingstatvalues WHERE charLevel = ?", $field, $this->ssd[$this->Id]['maxLevel']) : 0; } + + private function initScalingStats() + { + $this->ssd[$this->Id] = DB::Aowow()->selectRow("SELECT * FROM ?_scalingstatdistribution WHERE id = ?", $this->curTpl['ScalingStatDistribution']); + + // stats and ratings + for ($i = 1; $i <= 10; $i++) + { + if ($this->ssd[$this->Id]['statMod'.$i] <= 0) + { + $this->templates[$this->Id]['stat_type'.$i] = 0; + $this->templates[$this->Id]['stat_value'.$i] = 0; + } + else + { + $this->templates[$this->Id]['stat_type'.$i] = $this->ssd[$this->Id]['statMod'.$i]; + $this->templates[$this->Id]['stat_value'.$i] = intVal(($this->getSSDMod('stats') * $this->ssd[$this->Id]['modifier'.$i]) / 10000); + } + } + + // armor: only replace if set + if ($ssvArmor = $this->getSSDMod('armor')) + $this->templates[$this->Id]['armor'] = $ssvArmor; + + // if set dpsMod in ScalingStatValue use it for min (70% from average), max (130% from average) damage + if ($extraDPS = $this->getSSDMod('dps')) // dmg_x2 not used for heirlooms + { + $average = $extraDPS * $this->curTpl['delay'] / 1000; + $this->templates[$this->Id]['dmg_min1'] = number_format(0.7 * $average); + $this->templates[$this->Id]['dmg_max1'] = number_format(1.3 * $average); + } + + // apply Spell Power from ScalingStatValue if set + if ($spellBonus = $this->getSSDMod('spell')) + { + $this->templates[$this->Id]['stat_type10'] = ITEM_MOD_SPELL_POWER; + $this->templates[$this->Id]['stat_value10'] = $spellBonus; + } + } + + private function initSubItems() + { + $randId = $this->curTpl['RandomProperty'] > 0 ? $this->curTpl['RandomProperty'] : $this->curTpl['RandomSuffix']; + if ($randomIds = DB::Aowow()->selectCol('SELECT ench FROM item_enchantment_template WHERE entry = ?d', $randId)) + { + if ($this->curTpl['RandomSuffix'] > 0) + array_walk($randomIds, function($val, $key) use(&$randomIds) { + $randomIds[$key] = -$val; + }); + + $this->subItems[$this->Id] = DB::Aowow()->select('SELECT *, Id AS ARRAY_KEY FROM ?_itemRandomEnchant WHERE Id IN (?a)', $randomIds); + + // subitems may share enchantmentIds + foreach ($this->subItems[$this->Id] as $sI) + for ($i = 1; $i < 6; $i++) + if (!isset($this->rndEnchIds[$sI['enchantId'.$i]]) && $sI['enchantId'.$i]) + if ($enchant = DB::Aowow()->selectRow('SELECT *, Id AS ARRAY_KEY FROM ?_itemenchantment WHERE Id = ?d', $sI['enchantId'.$i])) + $this->rndEnchIds[$enchant['Id']] = $enchant; + } + } + + private function initJsonStats() + { + $json = array( + 'id' => $this->Id, // note to self: lowercase for js-Ids.. ALWAYS!! + 'name' => (ITEM_QUALITY_HEIRLOOM - $this->curTpl['Quality']).$this->names[$this->Id], + 'icon' => $this->curTpl['icon'], + 'classs' => $this->curTpl['class'], + 'subclass' => $this->curTpl['subclass'], + // 'subsubclass' => $this->curTpl['subsubclass'], + 'slot' => $this->curTpl['InventoryType'], + 'slotbak' => $this->curTpl['InventoryType'], + 'level' => $this->curTpl['ItemLevel'], + 'reqlevel' => $this->curTpl['RequiredLevel'], + 'displayid' => $this->curTpl['displayid'], + 'commondrop' => ($this->curTpl['RandomProperty'] > 0 || $this->curTpl['RandomSuffix'] > 0) ? 'true' : null, // string required :( + 'holres' => $this->curTpl['holy_res'], + 'firres' => $this->curTpl['fire_res'], + 'natres' => $this->curTpl['nature_res'], + 'frores' => $this->curTpl['frost_res'], + 'shares' => $this->curTpl['shadow_res'], + 'arcres' => $this->curTpl['arcane_res'], + 'armorbonus' => $this->curTpl['ArmorDamageModifier'], + 'armor' => $this->curTpl['armor'], + 'dura' => $this->curTpl['MaxDurability'], + 'itemset' => $this->curTpl['itemset'], + 'socket1' => $this->curTpl['socketColor_1'], + 'socket2' => $this->curTpl['socketColor_2'], + 'socket3' => $this->curTpl['socketColor_3'], + 'nsockets' => ($this->curTpl['socketColor_1'] > 0 ? 1 : 0) + ($this->curTpl['socketColor_2'] > 0 ? 1 : 0) + ($this->curTpl['socketColor_3'] > 0 ? 1 : 0), + 'socketbonus' => $this->curTpl['socketBonus'], + 'scadist' => $this->curTpl['ScalingStatDistribution'], + 'scaflags' => $this->curTpl['ScalingStatValue'] + ); + + if ($this->curTpl['class'] == ITEM_CLASS_WEAPON || $this->curTpl['class'] == ITEM_CLASS_AMMUNITION) + { + $json['dmgtype1'] = $this->curTpl['dmg_type1']; + $json['dmgmin1'] = $this->curTpl['dmg_min1'] + $this->curTpl['dmg_min2']; + $json['dmgmax1'] = $this->curTpl['dmg_max1'] + $this->curTpl['dmg_max2']; + $json['dps'] = !$this->curTpl['delay'] ? 0 : number_format(($json['dmgmin1'] + $json['dmgmax1']) / (2 * $this->curTpl['delay'] / 1000), 1); + $json['speed'] = number_format($this->curTpl['delay'] / 1000, 2); + + if (in_array($json['subclass'], [2, 3, 18, 19])) + { + $json['rgddmgmin'] = $json['dmgmin1']; + $json['rgddmgmax'] = $json['dmgmax1']; + $json['rgdspeed'] = $json['speed']; + $json['rgddps'] = $json['dps']; + } + else if ($json['classs'] != ITEM_CLASS_AMMUNITION) + { + $json['mledmgmin'] = $json['dmgmin1']; + $json['mledmgmax'] = $json['dmgmax1']; + $json['mlespeed'] = $json['speed']; + $json['mledps'] = $json['dps']; + } + + if ($json['classs'] == ITEM_CLASS_WEAPON && in_array($json['subclass'], [5, 6, 10]) && $json['dps'] > 54.8) + $json['feratkpwr'] = max(0, round((($json['dmgmin1'] + $json['dmgmax1']) / (2 * $this->curTpl['delay'] / 1000) - 54.8) * 14, 0)); + } + + // clear zero-values afterwards + foreach ($json as $k => $v) + if (!isset($v) || $v === "false" || (!in_array($k, ['classs', 'subclass', 'armor']) && $v === "0")) + unset($json[$k]); + + $this->json[$json['id']] = $json; + } + + public function addRewardsToJScript(&$ref) { } } ?> diff --git a/includes/class.quest.php b/includes/class.quest.php index edd21d34..ceb8f334 100644 --- a/includes/class.quest.php +++ b/includes/class.quest.php @@ -3,29 +3,42 @@ if (!defined('AOWOW_REVISION')) die('illegal access'); -class Quest extends BaseType +class QuestList extends BaseType { public $cat1 = 0; public $cat2 = 0; - protected $setupQuery = 'SELECT * FROM quest_template a LEFT JOIN locales_quest b ON a.Id = b.entry WHERE a.Id = ?'; + protected $setupQuery = 'SELECT *, Id AS ARRAY_KEY FROM quest_template a LEFT JOIN locales_quest b ON a.Id = b.entry WHERE [filter] [cond] ORDER BY Id ASC'; + protected $matchQuery = 'SELECT COUNT(1) FROM quest_template a LEFT JOIN locales_quest b ON a.Id = b.entry WHERE [filter] [cond]'; - public function __construct($data) + // parent::__construct does the job + + public function iterate($qty = 1) { - parent::__construct($data); + $r = parent::iterate($qty); - // post process - $this->cat1 = $this->template['ZoneOrSort']; // should probably be in a method... - foreach (Util::$questClasses as $k => $arr) + if (!$this->Id) { - if (in_array($this->cat1, $arr)) + $this->cat1 = 0; + $this->cat2 = 0; + } + else + { + $this->cat1 = $this->curTpl['ZoneOrSort']; // should probably be in a method... + foreach (Util::$questClasses as $k => $arr) { - $this->cat2 = $k; - break; + if (in_array($this->cat1, $arr)) + { + $this->cat2 = $k; + break; + } } } + + return $r; } + // static use START public static function getName($id) { $n = DB::Aowow()->SelectRow(' @@ -54,160 +67,114 @@ class Quest extends BaseType else return 0; } + // static use END public function getSourceData() { - return array( - "n" => Util::localizedString($this->template, 'Title'), - "t" => TYPE_QUEST, - "ti" => $this->Id, - "c" => $this->cat1, - "c2" => $this->cat2 - ); - } + $data = []; - public function getListviewData() - { - $data = array( - 'category' => $this->cat1, - 'category2' => $this->cat2, - 'id' => $this->Id, - 'level' => $this->template['Level'], - 'reqlevel' => $this->template['MinLevel'], - 'name' => Util::localizedString($this->template, 'Title'), - 'side' => Util::sideByRaceMask($this->template['RequiredRaces']) - ); - - $rewards = []; - for ($i = 1; $i < 5; $i++) - if ($this->template['RewardItemId'.$i]) - $rewards[] = [$this->template['RewardItemId'.$i], $this->template['RewardItemCount'.$i]]; - - $choices = []; - for ($i = 1; $i < 7; $i++) - if ($this->template['RewardChoiceItemId'.$i]) - $choices[] = [$this->template['RewardChoiceItemId'.$i], $this->template['RewardChoiceItemCount'.$i]]; - - if (!empty($rewards)) - $data['itemrewards'] = $rewards; - - if (!empty($choices)) - $data['itemchoices'] = $choices; - - if ($this->template['RewardTitleId']) - $data['titlereward'] = $this->template['RewardTitleId']; - - // todo reprewards .. accesses QuestFactionReward.dbc + while ($this->iterate()) + { + $data[$this->Id] = array( + "n" => Util::localizedString($this->curTpl, 'Title'), + "t" => TYPE_QUEST, + "ti" => $this->Id, + "c" => $this->cat1, + "c2" => $this->cat2 + ); + } return $data; } - public function addRewardsToJscript(&$gItems, &$gSpells, &$gTitles) + public function getListviewData() { - // items - $items = []; - for ($i = 1; $i < 5; $i++) - if ($this->template['RewardItemId'.$i]) - $items[] = $this->template['RewardItemId'.$i]; + $data = []; - for ($i = 1; $i < 7; $i++) - if ($this->template['RewardChoiceItemId'.$i]) - $items[] = $this->template['RewardChoiceItemId'.$i]; - - if (!empty($items)) + while ($this->iterate()) { - $items = new ItemList(array(['entry', $items])); - $items->addSelfToJScipt($gItems); + $set = array( + 'category' => $this->cat1, + 'category2' => $this->cat2, + 'id' => $this->Id, + 'level' => $this->curTpl['Level'], + 'reqlevel' => $this->curTpl['MinLevel'], + 'name' => Util::localizedString($this->curTpl, 'Title'), + 'side' => Util::sideByRaceMask($this->curTpl['RequiredRaces']) + ); + + $rewards = []; + for ($i = 1; $i < 5; $i++) + if ($this->curTpl['RewardItemId'.$i]) + $rewards[] = [$this->curTpl['RewardItemId'.$i], $this->curTpl['RewardItemCount'.$i]]; + + $choices = []; + for ($i = 1; $i < 7; $i++) + if ($this->curTpl['RewardChoiceItemId'.$i]) + $choices[] = [$this->curTpl['RewardChoiceItemId'.$i], $this->curTpl['RewardChoiceItemCount'.$i]]; + + if ($rewards) + $set['itemrewards'] = $rewards; + + if ($choices) + $set['itemchoices'] = $choices; + + if ($this->curTpl['RewardTitleId']) + $set['titlereward'] = $this->curTpl['RewardTitleId']; + + // todo reprewards .. accesses QuestFactionReward.dbc } - // spells - $spells = []; - if ($this->template['RewardSpell']) - $spells[] = $this->template['RewardSpell']; - - if ($this->template['RewardSpellCast']) - $spells[] = $this->template['RewardSpellCast']; - - if (!empty($spells)) - { - $spells = new SpellList(array(['id', $spells])); - $spells->addSelfToJScipt($gSpells); - } - - // titles - if ($tId = $this->template['RewardTitleId']) - { - $title = new Title($tId); - $title->addGlobalsToJScript($gTitles); - } - } -} - - - -class QuestList extends BaseTypeList -{ - protected $setupQuery = 'SELECT *, Id AS ARRAY_KEY FROM quest_template a LEFT JOIN locales_quest b ON a.Id = b.entry WHERE [filter] [cond] ORDER BY Id ASC'; - - public function __construct($conditions) - { - // may be called without filtering - if (class_exists('QuestFilter')) - { - $this->filter = new QuestFilter(); - if (($fiData = $this->filter->init()) === false) - return; - } - - parent::__construct($conditions); + return $data; } - public function addRewardsToJscript(&$gItems, &$gSpells, &$gTitles) + public function addRewardsToJscript(&$refs) { $items = []; $spells = []; $titles = []; - foreach ($this->container as $quest) + while ($this->iterate()) { // items for ($i = 1; $i < 5; $i++) - if ($quest->template['RewardItemId'.$i]) - $items[] = $quest->template['RewardItemId'.$i]; + if ($this->curTpl['RewardItemId'.$i] > 0) + $items[] = $this->curTpl['RewardItemId'.$i]; for ($i = 1; $i < 7; $i++) - if ($quest->template['RewardChoiceItemId'.$i]) - $items[] = $quest->template['RewardChoiceItemId'.$i]; + if ($this->curTpl['RewardChoiceItemId'.$i] > 0) + $items[] = $this->curTpl['RewardChoiceItemId'.$i]; // spells - if ($quest->template['RewardSpell']) - $spells[] = $quest->template['RewardSpell']; + if ($this->curTpl['RewardSpell'] > 0) + $spells[] = $this->curTpl['RewardSpell']; - if ($quest->template['RewardSpellCast']) - $spells[] = $quest->template['RewardSpellCast']; + if ($this->curTpl['RewardSpellCast'] > 0) + $spells[] = $this->curTpl['RewardSpellCast']; // titles - if ($quest->template['RewardTitleId']) - $titles[] = $quest->template['RewardTitleId']; + if ($this->curTpl['RewardTitleId'] > 0) + $titles[] = $this->curTpl['RewardTitleId']; } - if (!empty($items)) - { - $items = new ItemList(array(['i.entry', $items])); - $items->addGlobalsToJScript($gItems); - } + if ($items) + (new ItemList(array(['i.entry', $items])))->addGlobalsToJscript($refs); - if (!empty($spells)) - { - $spells = new SpellList(array(['id', $spells])); - $spells->addGlobalsToJScript($gSpells); - } + if ($spells) + (new SpellList(array(['Id', $spells])))->addGlobalsToJscript($refs); - if (!empty($titles)) - { - $titles = new TitleList(array(['id', $titles])); - $titles->addGlobalsToJScript($gTitles); - } + if ($titles) + (new TitleList(array(['Id', $titles])))->addGlobalsToJscript($refs); + } + + public function renderTooltip() + { + // todo + } + + public function addGlobalsToJScript(&$refs) + { + // todo } } diff --git a/includes/class.spell.php b/includes/class.spell.php index 75fdc01a..27d70f50 100644 --- a/includes/class.spell.php +++ b/includes/class.spell.php @@ -3,15 +3,41 @@ if (!defined('AOWOW_REVISION')) die('illegal access'); -class Spell extends BaseType +class SpellList extends BaseType { - public $tooltip = ''; - public $buff = ''; + public $tooltips = []; + public $buffs = []; private $spellVars = []; private $refSpells = []; - protected $setupQuery = 'SELECT * FROM ?_spell WHERE Id = ?d'; + protected $setupQuery = 'SELECT *, Id AS ARRAY_KEY FROM ?_spell WHERE [filter] [cond] GROUP BY Id ORDER BY Id ASC'; + protected $matchQuery = 'SELECT COUNT(1) FROM ?_spell WHERE [filter] [cond]'; + + public function __construct($conditions) + { + parent::__construct($conditions); + + if ($this->error) + return; + + // post processing + $itemIcons = []; + + // if the spell creates an item use the itemIcon instead + while ($this->iterate()) + if ($this->curTpl['effect1CreateItemId']) + $itemIcons[(int)$this->curTpl['effect1CreateItemId']] = $this->Id; + + if ($itemIcons) + { + $itemList = new ItemList(array(['i.entry', array_keys($itemIcons)])); + while ($itemList->iterate()) + $this->templates[$itemIcons[$itemList->Id]]['createItemString'] = $itemList->getField('icon'); + } + + $this->reset(); // restore 'iterator' + } // use if you JUST need the name public static function getName($id) @@ -21,173 +47,177 @@ class Spell extends BaseType } // end static use - // required for item-sets-bonuses and socket-bonuses + // required for itemSet-bonuses and socket-bonuses public function getStatGain() { $stats = []; - for ($i = 1; $i <= 3; $i++) + + while ($this->iterate()) { - if (!in_array($this->template["effect".$i."AuraId"], [13, 22, 29, 34, 35, 83, 84, 85, 99, 124, 135, 143, 158, 161, 189, 230, 235, 240, 250])) - continue; - - $mv = $this->template["effect".$i."MiscValue"]; - $bp = $this->template["effect".$i."BasePoints"] + 1; - - switch ($this->template["effect".$i."AuraId"]) + for ($i = 1; $i <= 3; $i++) { - case 29: // ModStat MiscVal:type - { - if ($mv < 0) // all stats - { - for ($j = 0; $j < 5; $j++) - @$stats[ITEM_MOD_AGILITY + $j] += $bp; - } - else // one stat - @$stats[ITEM_MOD_AGILITY + $mv] += $bp; + if (!in_array($this->curTpl["effect".$i."AuraId"], [13, 22, 29, 34, 35, 83, 84, 85, 99, 124, 135, 143, 158, 161, 189, 230, 235, 240, 250])) + continue; - break; - } - case 34: // Increase Health - case 230: - case 250: + $mv = $this->curTpl["effect".$i."MiscValue"]; + $bp = $this->curTpl["effect".$i."BasePoints"] + 1; + + switch ($this->curTpl["effect".$i."AuraId"]) { - @$stats[ITEM_MOD_HEALTH] += $bp; - break; - } - case 13: // damage splpwr + physical (dmg & any) - { - if ($mv == 1) // + weapon damage + case 29: // ModStat MiscVal:type { - @$stats[ITEM_MOD_WEAPON_DMG] += $bp; + if ($mv < 0) // all stats + { + for ($j = 0; $j < 5; $j++) + @$stats[ITEM_MOD_AGILITY + $j] += $bp; + } + else // one stat + @$stats[ITEM_MOD_AGILITY + $mv] += $bp; + break; } + case 34: // Increase Health + case 230: + case 250: + { + @$stats[ITEM_MOD_HEALTH] += $bp; + break; + } + case 13: // damage splpwr + physical (dmg & any) + { + if ($mv == 1) // + weapon damage + { + @$stats[ITEM_MOD_WEAPON_DMG] += $bp; + break; + } - if ($mv == 0x7E) // full magic mask, also counts towards healing + if ($mv == 0x7E) // full magic mask, also counts towards healing + { + @$stats[ITEM_MOD_SPELL_POWER] += $bp; + @$stats[ITEM_MOD_SPELL_DAMAGE_DONE] += $bp; + } + else + { + if ($mv & (1 << 1)) // HolySpellpower (deprecated; still used in randomproperties) + @$stats[ITEM_MOD_HOLY_POWER] += $bp; + + if ($mv & (1 << 2)) // FireSpellpower (deprecated; still used in randomproperties) + @$stats[ITEM_MOD_FIRE_POWER] += $bp; + + if ($mv & (1 << 3)) // NatureSpellpower (deprecated; still used in randomproperties) + @$stats[ITEM_MOD_NATURE_POWER] += $bp; + + if ($mv & (1 << 4)) // FrostSpellpower (deprecated; still used in randomproperties) + @$stats[ITEM_MOD_FROST_POWER] += $bp; + + if ($mv & (1 << 5)) // ShadowSpellpower (deprecated; still used in randomproperties) + @$stats[ITEM_MOD_SHADOW_POWER] += $bp; + + if ($mv & (1 << 6)) // ArcaneSpellpower (deprecated; still used in randomproperties) + @$stats[ITEM_MOD_ARCANE_POWER] += $bp; + } + + break; + } + case 135: // healing splpwr (healing & any) .. not as a mask.. { @$stats[ITEM_MOD_SPELL_POWER] += $bp; - @$stats[ITEM_MOD_SPELL_DAMAGE_DONE] += $bp; - } - else - { - if ($mv & (1 << 1)) // HolySpellpower (deprecated; still used in randomproperties) - @$stats[ITEM_MOD_HOLY_POWER] += $bp; + @$stats[ITEM_MOD_SPELL_HEALING_DONE] += $bp; - if ($mv & (1 << 2)) // FireSpellpower (deprecated; still used in randomproperties) - @$stats[ITEM_MOD_FIRE_POWER] += $bp; - - if ($mv & (1 << 3)) // NatureSpellpower (deprecated; still used in randomproperties) - @$stats[ITEM_MOD_NATURE_POWER] += $bp; - - if ($mv & (1 << 4)) // FrostSpellpower (deprecated; still used in randomproperties) - @$stats[ITEM_MOD_FROST_POWER] += $bp; - - if ($mv & (1 << 5)) // ShadowSpellpower (deprecated; still used in randomproperties) - @$stats[ITEM_MOD_SHADOW_POWER] += $bp; - - if ($mv & (1 << 6)) // ArcaneSpellpower (deprecated; still used in randomproperties) - @$stats[ITEM_MOD_ARCANE_POWER] += $bp; - } - - break; - } - case 135: // healing splpwr (healing & any) .. not as a mask.. - { - @$stats[ITEM_MOD_SPELL_POWER] += $bp; - @$stats[ITEM_MOD_SPELL_HEALING_DONE] += $bp; - - break; - } - case 35: // ModPower - MiscVal:type see defined Powers only energy/mana in use - { - if ($mv == -2) - @$stats[ITEM_MOD_HEALTH] += $bp; - if ($mv == 3) - @$stats[ITEM_MOD_ENERGY] += $bp; - else if ($mv == 0) - @$stats[ITEM_MOD_MANA] += $bp; - else if ($mv == 6) - @$stats[ITEM_MOD_RUNIC_POWER] += $bp; - - break; - } - case 189: // CombatRating MiscVal:ratingMask - // special case: resilience - consists of 3 ratings strung together. MOD_CRIT_TAKEN_MELEE|RANGED|SPELL (14,15,16) - if (($mv & 0x1C000) == 0x1C000) - @$stats[ITEM_MOD_RESILIENCE_RATING] += $bp; - - for ($j = 0; $j < count(Util::$combatRatingToItemMod); $j++) - { - if (!Util::$combatRatingToItemMod[$j]) - continue; - - if (($mv & (1 << $j)) == 0) - continue; - - @$stats[Util::$combatRatingToItemMod[$j]] += $bp; - } - break; - case 143: // Resistance MiscVal:school - case 83: - case 22: - - if ($mv == 1) // Armor only if explixitly specified - { - @$stats[ITEM_MOD_ARMOR] += $bp; break; } - - if ($mv == 2) // holy-resistance ONLY if explicitly specified (shouldn't even exist...) + case 35: // ModPower - MiscVal:type see defined Powers only energy/mana in use { - @$stats[ITEM_MOD_HOLY_RESISTANCE] += $bp; + if ($mv == -2) + @$stats[ITEM_MOD_HEALTH] += $bp; + if ($mv == 3) + @$stats[ITEM_MOD_ENERGY] += $bp; + else if ($mv == 0) + @$stats[ITEM_MOD_MANA] += $bp; + else if ($mv == 6) + @$stats[ITEM_MOD_RUNIC_POWER] += $bp; + break; } + case 189: // CombatRating MiscVal:ratingMask + // special case: resilience - consists of 3 ratings strung together. MOD_CRIT_TAKEN_MELEE|RANGED|SPELL (14,15,16) + if (($mv & 0x1C000) == 0x1C000) + @$stats[ITEM_MOD_RESILIENCE_RATING] += $bp; - for ($j = 0; $j < 7; $j++) - { - if (($mv & (1 << $j)) == 0) - continue; - - switch ($j) + for ($j = 0; $j < count(Util::$combatRatingToItemMod); $j++) { - case 2: - @$stats[ITEM_MOD_FIRE_RESISTANCE] += $bp; - break; - case 3: - @$stats[ITEM_MOD_NATURE_RESISTANCE] += $bp; - break; - case 4: - @$stats[ITEM_MOD_FROST_RESISTANCE] += $bp; - break; - case 5: - @$stats[ITEM_MOD_SHADOW_RESISTANCE] += $bp; - break; - case 6: - @$stats[ITEM_MOD_ARCANE_RESISTANCE] += $bp; - break; + if (!Util::$combatRatingToItemMod[$j]) + continue; + + if (($mv & (1 << $j)) == 0) + continue; + + @$stats[Util::$combatRatingToItemMod[$j]] += $bp; } - } - break; - case 84: // hp5 - case 161: - @$stats[ITEM_MOD_HEALTH_REGEN] += $bp; - break; - case 85: // mp5 - @$stats[ITEM_MOD_MANA_REGENERATION] += $bp; - break; - case 99: // atkpwr - @$stats[ITEM_MOD_ATTACK_POWER] += $bp; - break; // ?carries over to rngatkpwr? - case 124: // rngatkpwr - @$stats[ITEM_MOD_RANGED_ATTACK_POWER] += $bp; - break; - case 158: // blockvalue - @$stats[ITEM_MOD_BLOCK_VALUE] += $bp; - break; - case 240: // ModExpertise - @$stats[ITEM_MOD_EXPERTISE_RATING] += $bp; - break; + break; + case 143: // Resistance MiscVal:school + case 83: + case 22: + if ($mv == 1) // Armor only if explixitly specified + { + @$stats[ITEM_MOD_ARMOR] += $bp; + break; + } + + if ($mv == 2) // holy-resistance ONLY if explicitly specified (shouldn't even exist...) + { + @$stats[ITEM_MOD_HOLY_RESISTANCE] += $bp; + break; + } + + for ($j = 0; $j < 7; $j++) + { + if (($mv & (1 << $j)) == 0) + continue; + + switch ($j) + { + case 2: + @$stats[ITEM_MOD_FIRE_RESISTANCE] += $bp; + break; + case 3: + @$stats[ITEM_MOD_NATURE_RESISTANCE] += $bp; + break; + case 4: + @$stats[ITEM_MOD_FROST_RESISTANCE] += $bp; + break; + case 5: + @$stats[ITEM_MOD_SHADOW_RESISTANCE] += $bp; + break; + case 6: + @$stats[ITEM_MOD_ARCANE_RESISTANCE] += $bp; + break; + } + } + break; + case 84: // hp5 + case 161: + @$stats[ITEM_MOD_HEALTH_REGEN] += $bp; + break; + case 85: // mp5 + @$stats[ITEM_MOD_MANA_REGENERATION] += $bp; + break; + case 99: // atkpwr + @$stats[ITEM_MOD_ATTACK_POWER] += $bp; + break; // ?carries over to rngatkpwr? + case 124: // rngatkpwr + @$stats[ITEM_MOD_RANGED_ATTACK_POWER] += $bp; + break; + case 158: // blockvalue + @$stats[ITEM_MOD_BLOCK_VALUE] += $bp; + break; + case 240: // ModExpertise + @$stats[ITEM_MOD_EXPERTISE_RATING] += $bp; + break; + } } } + return $stats; } @@ -236,16 +266,16 @@ class Spell extends BaseType // cache at least some lookups.. should be moved to single spellList :/ if ($lookup && !isset($this->refSpells[$lookup])) - $this->refSpells[$lookup] = new Spell($lookup); + $this->refSpells[$lookup] = new SpellList(array(['Id', $lookup])); switch ($var) { case 'a': // EffectRadiusMin case 'A': // EffectRadiusMax (ToDo) if ($lookup) - $base = $this->refSpells[$lookup]->template['effect'.$effIdx.'RadiusMax']; + $base = $this->refSpells[$lookup]->getField('effect'.$effIdx.'RadiusMax'); else - $base = $this->template['effect'.$effIdx.'RadiusMax']; + $base = $this->getField('effect'.$effIdx.'RadiusMax'); if (in_array($op, $signs) && is_numeric($oparg) && is_numeric($base)) eval("\$base = $base.$op.$oparg;"); @@ -254,9 +284,9 @@ class Spell extends BaseType case 'b': // PointsPerComboPoint case 'B': if ($lookup) - $base = $this->refSpells[$lookup]->template['effect'.$effIdx.'PointsPerComboPoint']; + $base = $this->refSpells[$lookup]->getField('effect'.$effIdx.'PointsPerComboPoint'); else - $base = $this->template['effect'.$effIdx.'PointsPerComboPoint']; + $base = $this->getField('effect'.$effIdx.'PointsPerComboPoint'); if (in_array($op, $signs) && is_numeric($oparg) && is_numeric($base)) eval("\$base = $base.$op.$oparg;"); @@ -267,7 +297,7 @@ class Spell extends BaseType if ($lookup > 0 && $exprData[0]) $spell = DB::Aowow()->selectRow('SELECT effect'.$exprData[0].'BasePoints, effect'.$exprData[0].'AuraId, effect'.$exprData[0].'MiscValue FROM ?_spell WHERE id=? LIMIT 1', $lookup); else - $spell = $this->template; + $spell = $this->curTpl; $base = $spell['effect'.$exprData[0].'BasePoints'] + 1; @@ -307,9 +337,9 @@ class Spell extends BaseType case 'd': // SpellDuration case 'D': // todo: min/max? if ($lookup) - $base = $this->refSpells[$lookup]->template['duration']; + $base = $this->refSpells[$lookup]->getField('duration'); else - $base = $this->template['duration']; + $base = $this->getField('duration'); if ($base < 0) return Lang::$spell['untilCanceled']; @@ -321,9 +351,9 @@ class Spell extends BaseType case 'e': // EffectValueMultiplier case 'E': if ($lookup) - $base = $this->refSpells[$lookup]->template['effect'.$effIdx.'ValueMultiplier']; + $base = $this->refSpells[$lookup]->getField('effect'.$effIdx.'ValueMultiplier'); else - $base = $this->template['effect'.$effIdx.'ValueMultiplier']; + $base = $this->getField('effect'.$effIdx.'ValueMultiplier'); if (in_array($op, $signs) && is_numeric($oparg) && is_numeric($base)) eval("\$base = $base.$op.$oparg;"); @@ -332,9 +362,9 @@ class Spell extends BaseType case 'f': // EffectDamageMultiplier case 'F': if ($lookup) - $base = $this->refSpells[$lookup]->template['effect'.$effIdx.'DamageMultiplier']; + $base = $this->refSpells[$lookup]->getField('effect'.$effIdx.'DamageMultiplier'); else - $base = $this->template['effect'.$effIdx.'DamageMultiplier']; + $base = $this->getField('effect'.$effIdx.'DamageMultiplier'); if (in_array($op, $signs) && is_numeric($oparg) && is_numeric($base)) eval("\$base = $base.$op.$oparg;"); @@ -346,9 +376,9 @@ class Spell extends BaseType case 'h': // ProcChance case 'H': if ($lookup) - $base = $this->refSpells[$lookup]->template['procChance']; + $base = $this->refSpells[$lookup]->getField('procChance'); else - $base = $this->template['procChance']; + $base = $this->getField('procChance'); if (in_array($op, $signs) && is_numeric($oparg) && is_numeric($base)) eval("\$base = $base.$op.$oparg;"); @@ -357,9 +387,9 @@ class Spell extends BaseType case 'i': // MaxAffectedTargets case 'I': if ($lookup) - $base = $this->refSpells[$lookup]->template['targets']; + $base = $this->refSpells[$lookup]->getField('targets'); else - $base = $this->template['targets']; + $base = $this->getField('targets'); if (in_array($op, $signs) && is_numeric($oparg) && is_numeric($base)) eval("\$base = $base.$op.$oparg;"); @@ -372,18 +402,18 @@ class Spell extends BaseType case 'M': // BasePoints (maxValue) if ($lookup) { - $base = $this->refSpells[$lookup]->template['effect'.$effIdx.'BasePoints']; - $add = $this->refSpells[$lookup]->template['effect'.$effIdx.'DieSides']; - $mv = $this->refSpells[$lookup]->template['effect'.$effIdx.'MiscValue']; - $aura = $this->refSpells[$lookup]->template['effect'.$effIdx.'AuraId']; + $base = $this->refSpells[$lookup]->getField('effect'.$effIdx.'BasePoints'); + $add = $this->refSpells[$lookup]->getField('effect'.$effIdx.'DieSides'); + $mv = $this->refSpells[$lookup]->getField('effect'.$effIdx.'MiscValue'); + $aura = $this->refSpells[$lookup]->getField('effect'.$effIdx.'AuraId'); } else { - $base = $this->template['effect'.$effIdx.'BasePoints']; - $add = $this->template['effect'.$effIdx.'DieSides']; - $mv = $this->template['effect'.$effIdx.'MiscValue']; - $aura = $this->template['effect'.$effIdx.'AuraId']; + $base = $this->getField('effect'.$effIdx.'BasePoints'); + $add = $this->getField('effect'.$effIdx.'DieSides'); + $mv = $this->getField('effect'.$effIdx.'MiscValue'); + $aura = $this->getField('effect'.$effIdx.'AuraId'); } if (ctype_lower($var)) @@ -419,9 +449,9 @@ class Spell extends BaseType case 'n': // ProcCharges case 'N': if ($lookup) - $base = $this->refSpells[$lookup]->template['procCharges']; + $base = $this->refSpells[$lookup]->getField('procCharges'); else - $base = $this->template['procCharges']; + $base = $this->getField('procCharges'); if (in_array($op, $signs) && is_numeric($oparg) && is_numeric($base)) eval("\$base = $base.$op.$oparg;"); @@ -431,17 +461,17 @@ class Spell extends BaseType case 'O': if ($lookup) { - $base = $this->refSpells[$lookup]->template['effect'.$effIdx.'BasePoints']; - $add = $this->refSpells[$lookup]->template['effect'.$effIdx.'DieSides']; - $periode = $this->refSpells[$lookup]->template['effect'.$effIdx.'Periode']; - $duration = $this->refSpells[$lookup]->template['duration']; + $base = $this->refSpells[$lookup]->getField('effect'.$effIdx.'BasePoints'); + $add = $this->refSpells[$lookup]->getField('effect'.$effIdx.'DieSides'); + $periode = $this->refSpells[$lookup]->getField('effect'.$effIdx.'Periode'); + $duration = $this->refSpells[$lookup]->getField('duration'); } else { - $base = $this->template['effect'.$effIdx.'BasePoints']; - $add = $this->template['effect'.$effIdx.'DieSides']; - $periode = $this->template['effect'.$effIdx.'Periode']; - $duration = $this->template['duration']; + $base = $this->getField('effect'.$effIdx.'BasePoints'); + $add = $this->getField('effect'.$effIdx.'DieSides'); + $periode = $this->getField('effect'.$effIdx.'Periode'); + $duration = $this->getField('duration'); } if (!$periode) @@ -453,9 +483,9 @@ class Spell extends BaseType case 'q': // EffectMiscValue case 'Q': if ($lookup) - $base = $this->refSpells[$lookup]->template['effect'.$effIdx.'MiscValue']; + $base = $this->refSpells[$lookup]->getField('effect'.$effIdx.'MiscValue'); else - $base = $this->template['effect'.$effIdx.'MiscValue']; + $base = $this->getField('effect'.$effIdx.'MiscValue'); if (in_array($op, $signs) && is_numeric($oparg) && is_numeric($base)) eval("\$base = $base.$op.$oparg;"); @@ -464,9 +494,9 @@ class Spell extends BaseType case 'r': // SpellRange case 'R': if ($lookup) - $base = $this->refSpells[$lookup]->template['rangeMaxHostile']; + $base = $this->refSpells[$lookup]->getField('rangeMaxHostile'); else - $base = $this->template['rangeMaxHostile']; + $base = $this->getField('rangeMaxHostile'); if (in_array($op, $signs) && is_numeric($oparg) && is_numeric($base)) eval("\$base = $base.$op.$oparg;"); @@ -476,17 +506,17 @@ class Spell extends BaseType case 'S': if ($lookup) { - $base = $this->refSpells[$lookup]->template['effect'.$effIdx.'BasePoints']; - $add = $this->refSpells[$lookup]->template['effect'.$effIdx.'DieSides']; - $mv = $this->refSpells[$lookup]->template['effect'.$effIdx.'MiscValue']; - $aura = $this->refSpells[$lookup]->template['effect'.$effIdx.'AuraId']; + $base = $this->refSpells[$lookup]->getField('effect'.$effIdx.'BasePoints'); + $add = $this->refSpells[$lookup]->getField('effect'.$effIdx.'DieSides'); + $mv = $this->refSpells[$lookup]->getField('effect'.$effIdx.'MiscValue'); + $aura = $this->refSpells[$lookup]->getField('effect'.$effIdx.'AuraId'); } else { - $base = $this->template['effect'.$effIdx.'BasePoints']; - $add = $this->template['effect'.$effIdx.'DieSides']; - $mv = $this->template['effect'.$effIdx.'MiscValue']; - $aura = $this->template['effect'.$effIdx.'AuraId']; + $base = $this->getField('effect'.$effIdx.'BasePoints'); + $add = $this->getField('effect'.$effIdx.'DieSides'); + $mv = $this->getField('effect'.$effIdx.'MiscValue'); + $aura = $this->getField('effect'.$effIdx.'AuraId'); } if (in_array($op, $signs) && is_numeric($oparg) && is_numeric($base)) @@ -517,9 +547,9 @@ class Spell extends BaseType case 't': // Periode case 'T': if ($lookup) - $base = $this->refSpells[$lookup]->template['effect'.$effIdx.'Periode'] / 1000; + $base = $this->refSpells[$lookup]->getField('effect'.$effIdx.'Periode') / 1000; else - $base = $this->template['effect'.$effIdx.'Periode'] / 1000; + $base = $this->getField('effect'.$effIdx.'Periode') / 1000; if (in_array($op, $signs) && is_numeric($oparg) && is_numeric($base)) eval("\$base = $base.$op.$oparg;"); @@ -528,9 +558,9 @@ class Spell extends BaseType case 'u': // StackCount case 'U': if ($lookup) - $base = $this->refSpells[$lookup]->template['stackAmount']; + $base = $this->refSpells[$lookup]->getField('stackAmount'); else - $base = $this->template['stackAmount']; + $base = $this->getField('stackAmount'); if (in_array($op, $signs) && is_numeric($oparg) && is_numeric($base)) eval("\$base = $base.$op.$oparg;"); @@ -539,9 +569,9 @@ class Spell extends BaseType case 'v': // MaxTargetLevel case 'V': if ($lookup) - $base = $this->refSpells[$lookup]->template['MaxTargetLevel']; + $base = $this->refSpells[$lookup]->getField('MaxTargetLevel'); else - $base = $this->template['MaxTargetLevel']; + $base = $this->getField('MaxTargetLevel'); if (in_array($op, $signs) && is_numeric($oparg) && is_numeric($base)) eval("\$base = $base.$op.$oparg;"); @@ -550,9 +580,9 @@ class Spell extends BaseType case 'x': // ChainTargetCount case 'X': if ($lookup) - $base = $this->refSpells[$lookup]->template['effect'.$effIdx.'ChainTarget']; + $base = $this->refSpells[$lookup]->getField('effect'.$effIdx.'ChainTarget'); else - $base = $this->template['effect'.$effIdx.'ChainTarget']; + $base = $this->getField('effect'.$effIdx.'ChainTarget'); if (in_array($op, $signs) && is_numeric($oparg) && is_numeric($base)) eval("\$base = $base.$op.$oparg;"); @@ -640,6 +670,10 @@ class Spell extends BaseType // although it seems to be pretty fast, even on those pesky test-spells with extra complex tooltips (Ron Test Spell X)) public function parseText($type = 'description', $level = MAX_LEVEL) { + // oooo..kaaayy.. parsing text in 6 or 7 easy steps + // we don't use the internal iterator here. This func has to be called for the individual template. + // otherwise it will get a bit messy, when we iterate, while we iterate *yo dawg!* + /* documentation .. sort of bracket use ${}.x - formulas; .x is optional; x:[0-9] .. max-precision of a floatpoint-result; default: 0 @@ -711,14 +745,14 @@ class Spell extends BaseType // step 0: get text - $data = Util::localizedString($this->template, $type); + $data = Util::localizedString($this->curTpl, $type); if (empty($data) || $data == "[]") // empty tooltip shouldn't be displayed anyway return null; // step 1: if the text is supplemented with text-variables, get and replace them - if (empty($this->spellVars[$this->Id]) && $this->template['spellDescriptionVariableId'] > 0) + if (empty($this->spellVars[$this->Id]) && $this->curTpl['spellDescriptionVariableId'] > 0) { - $spellVars = DB::Aowow()->SelectCell('SELECT vars FROM ?_spellVariables WHERE id = ?d', $this->template['spellDescriptionVariableId']); + $spellVars = DB::Aowow()->SelectCell('SELECT vars FROM ?_spellVariables WHERE id = ?d', $this->curTpl['spellDescriptionVariableId']); $spellVars = explode("\n", $spellVars); foreach ($spellVars as $sv) if (preg_match('/\$(\w*\d*)=(.*)/i', trim($sv), $matches)) @@ -906,270 +940,282 @@ class Spell extends BaseType return $str; } - public function getBuff() + public function renderBuff($Id = 0) { - // doesn't have a buff - if (!Util::localizedString($this->template, 'buff')) - return ''; - - $x = ''; - - // spellName - $x .= ''; - - // dispelType (if applicable) - if ($dispel = Lang::$game['di'][$this->template['dispelType']]) - $x .= ''; - - $x .= '
'.Util::localizedString($this->template, 'name').''.$dispel.'
'; - - $x .= '
'; - - // parse Buff-Text - $x .= $this->parseText('buff').'
'; - - // duration - if ($this->template['duration']) - $x .= ''.sprintf(Lang::$spell['remaining'], Util::formatTime($this->template['duration'])).''; - - $x .= '
'; - - $this->buff = $x; - - return $this->buff; - } - - public function getTooltip() - { - // get reagents - $reagents = []; - for ($j = 1; $j <= 8; $j++) + while ($this->iterate()) { - if($this->template['reagent'.$j] <= 0) + if ($Id && $this->Id != $Id) continue; - $reagents[] = array( - 'id' => $this->template['reagent'.$j], - 'name' => Item::getName($this->template['reagent'.$j]), - 'count' => $this->template['reagentCount'.$j] // if < 0 : require, but don't use - ); - } - $reagents = array_reverse($reagents); + // doesn't have a buff + if (!Util::localizedString($this->curTpl, 'buff')) + return ''; - // get tools - $tools = []; - for ($i = 1; $i <= 2; $i++) - { - // Tools - if ($this->template['tool'.$i]) - $tools[$i-1] = array('itemId' => $this->template['tool'.$i], 'name' => Item::getName($this->template['tool'.$i])); + $x = ''; - // TotemCategory - if ($this->template['toolCategory'.$i]) - { - $tc = DB::Aowow()->selectRow('SELECT * FROM aowow_totemcategory WHERE id = ?d', $this->template['toolCategory'.$i]); - $tools[$i+1] = array('categoryMask' => $tc['categoryMask'], 'name' => Util::localizedString($tc, 'name')); - } - } - $tools = array_reverse($tools); + // spellName + $x .= ''; - // get description - $desc = $this->parseText('description'); + // dispelType (if applicable) + if ($dispel = Lang::$game['di'][$this->curTpl['dispelType']]) + $x .= ''; - $reqWrapper = $this->template['rangeMaxHostile'] && ($this->template['powerCost'] > 0 || $this->template['powerCostPercent'] > 0); - $reqWrapper2 = $reagents ||$tools || $desc; + $x .= '
'.Util::localizedString($this->curTpl, 'name').''.$dispel.'
'; - $x = ''; - $x .= '
'; + $x .= '
'; - $rankText = Util::localizedString($this->template, 'rank'); + // parse Buff-Text + $x .= $this->parseText('buff').'
'; - if (!empty($rankText)) - $x .= '
'; + // duration + if ($this->curTpl['duration'] > 0) + $x .= ''.sprintf(Lang::$spell['remaining'], Util::formatTime($this->curTpl['duration'])).''; - // name - $x .= ''.Util::localizedString($this->template, 'name').''; + $x .= '
'; - // rank - if (!empty($rankText)) - $x .= '
'.$rankText.'
'; - - - if ($reqWrapper) - $x .= '
'; - - // check for custom PowerDisplay - $pt = $this->template['powerDisplayString'] ? $this->template['powerDisplayString'] : $this->template['powerType']; - - // power cost: pct over static - if ($this->template['powerCostPercent'] > 0) - $x .= $this->template['powerCostPercent']."% ".sprintf(Lang::$spell['pctCostOf'], strtolower(Lang::$spell['powerTypes'][$pt])); - else if ($this->template['powerCost'] > 0 || $this->template['powerPerSecond'] > 0 || $this->template['powerCostPerLevel'] > 0) - $x .= ($pt == 1 ? $this->template['powerCost'] / 10 : $this->template['powerCost']).' '.ucFirst(Lang::$spell['powerTypes'][$pt]); - - // append periodic cost - if ($this->template['powerPerSecond'] > 0) - $x .= sprintf(Lang::$spell['costPerSec'], $this->template['powerPerSecond']); - - // append level cost - if ($this->template['powerCostPerLevel'] > 0) - $x .= sprintf(Lang::$spell['costPerLevel'], $this->template['powerCostPerLevel']); - - $x .= '
'; - - if ($reqWrapper) - $x .= '
'; - - // ranges - if ($this->template['rangeMaxHostile']) - { - // minRange exists; show as range - if ($this->template['rangeMinHostile']) - $x .= sprintf(Lang::$spell['range'], $this->template['rangeMinHostile'].' - '.$this->template['rangeMaxHostile']).'
'; - // friend and hostile differ; do color - else if ($this->template['rangeMaxHostile'] != $this->template['rangeMaxFriend']) - $x .= sprintf(Lang::$spell['range'], ''.$this->template['rangeMaxHostile'].' - '.$this->template['rangeMaxHostile']. '').'
'; - // hardcode: "melee range" - else if ($this->template['rangeMaxHostile'] == 5) - $x .= Lang::$spell['meleeRange'].'
'; - // regular case - else - $x .= sprintf(Lang::$spell['range'], $this->template['rangeMaxHostile']).'
'; + $this->buffs[$this->Id] = $x; } - if ($reqWrapper) - $x .= '
'; - - $x .= ''; - - // cooldown or categorycooldown - if ($this->template['recoveryTime']) - $x.= ''; - else if ($this->template['recoveryCategory']) - $x.= ''; - - $x .= ''; - - if ($this->template['stanceMask']) - $x.= ''; - - $x .= '
'; - - // cast times - if ($this->template['interruptFlagsChannel']) - $x .= Lang::$spell['channeled']; - else if ($this->template['castTime']) - $x .= sprintf(Lang::$spell['castIn'], $this->template['castTime'] / 1000); - else if ($this->template['attributes0'] & 0x10) // SPELL_ATTR0_ABILITY instant ability.. yeah, wording thing only - $x .= Lang::$spell['instantPhys']; - else // instant cast - $x .= Lang::$spell['instantMagic']; - - $x .= ''.sprintf(Lang::$game['cooldown'], Util::formatTime($this->template['recoveryTime'], true)).''.sprintf(Lang::$game['cooldown'], Util::formatTime($this->template['recoveryCategory'], true)).'
'.Lang::$game['requires'].' '.Lang::getStances($this->template['stanceMask']).'
'; - $x .= '
'; - - if ($reqWrapper2) - $x .= ''; - - if ($tools) - { - $x .= ''; - } - - if ($reagents) - { - $x .= ''; - } - - if($desc && $desc <> '_empty_') - $x .= ''; - - if ($reqWrapper2) - $x .= "
'; - $x .= Lang::$spell['tools'].':
'; - while ($tool = array_pop($tools)) - { - if (isset($tool['itemId'])) - $x .= ''.$tool['name'].''; - else if (isset($tool['totemCategory'])) - $x .= ''.$tool['name'].''; - else - $x .= $tool['name']; - - if (!empty($tools)) - $x .= ', '; - else - $x .= '
'; - } - $x .= '
'; - $x .= Lang::$spell['reagents'].':
'; - while ($reagent = array_pop($reagents)) - { - $x .= ''.$reagent['name'].''; - if ($reagent['count'] > 1) - $x .= ' ('.$reagent['count'].')'; - - if(!empty($reagents)) - $x .= ', '; - else - $x .= '
'; - } - $x .= '
'.$desc.'
"; - - $this->tooltip = $x; - - return $this->tooltip; + return $Id ? $this->buffs[$Id] : true; } - public function getTalentHead() + public function renderTooltip($Id = 0) + { + while ($this->iterate()) + { + if ($Id && $this->Id != $Id) + continue; + + // get reagents + $reagents = []; + for ($j = 1; $j <= 8; $j++) + { + if($this->curTpl['reagent'.$j] <= 0) + continue; + + $reagents[] = array( + 'id' => $this->curTpl['reagent'.$j], + 'name' => Util::getItemName($this->curTpl['reagent'.$j]), + 'count' => $this->curTpl['reagentCount'.$j] // if < 0 : require, but don't use + ); + } + $reagents = array_reverse($reagents); + + // get tools + $tools = []; + for ($i = 1; $i <= 2; $i++) + { + // Tools + if ($this->curTpl['tool'.$i]) + $tools[$i-1] = array('itemId' => $this->curTpl['tool'.$i], 'name' => Util::getItemName($this->curTpl['tool'.$i])); + + // TotemCategory + if ($this->curTpl['toolCategory'.$i]) + { + $tc = DB::Aowow()->selectRow('SELECT * FROM aowow_totemcategory WHERE id = ?d', $this->curTpl['toolCategory'.$i]); + $tools[$i+1] = array('categoryMask' => $tc['categoryMask'], 'name' => Util::localizedString($tc, 'name')); + } + } + $tools = array_reverse($tools); + + // get description + $desc = $this->parseText('description'); + + $reqWrapper = $this->curTpl['rangeMaxHostile'] && ($this->curTpl['powerCost'] > 0 || $this->curTpl['powerCostPercent'] > 0); + $reqWrapper2 = $reagents ||$tools || $desc; + + $x = ''; + $x .= '
'; + + $rankText = Util::localizedString($this->curTpl, 'rank'); + + if (!empty($rankText)) + $x .= '
'; + + // name + $x .= ''.$this->names[$this->Id].''; + + // rank + if (!empty($rankText)) + $x .= '
'.$rankText.'
'; + + + if ($reqWrapper) + $x .= '
'; + + // check for custom PowerDisplay + $pt = $this->curTpl['powerDisplayString'] ? $this->curTpl['powerDisplayString'] : $this->curTpl['powerType']; + + // power cost: pct over static + if ($this->curTpl['powerCostPercent'] > 0) + $x .= $this->curTpl['powerCostPercent']."% ".sprintf(Lang::$spell['pctCostOf'], strtolower(Lang::$spell['powerTypes'][$pt])); + else if ($this->curTpl['powerCost'] > 0 || $this->curTpl['powerPerSecond'] > 0 || $this->curTpl['powerCostPerLevel'] > 0) + $x .= ($pt == 1 ? $this->curTpl['powerCost'] / 10 : $this->curTpl['powerCost']).' '.ucFirst(Lang::$spell['powerTypes'][$pt]); + + // append periodic cost + if ($this->curTpl['powerPerSecond'] > 0) + $x .= sprintf(Lang::$spell['costPerSec'], $this->curTpl['powerPerSecond']); + + // append level cost + if ($this->curTpl['powerCostPerLevel'] > 0) + $x .= sprintf(Lang::$spell['costPerLevel'], $this->curTpl['powerCostPerLevel']); + + $x .= '
'; + + if ($reqWrapper) + $x .= '
'; + + // ranges + if ($this->curTpl['rangeMaxHostile']) + { + // minRange exists; show as range + if ($this->curTpl['rangeMinHostile']) + $x .= sprintf(Lang::$spell['range'], $this->curTpl['rangeMinHostile'].' - '.$this->curTpl['rangeMaxHostile']).'
'; + // friend and hostile differ; do color + else if ($this->curTpl['rangeMaxHostile'] != $this->curTpl['rangeMaxFriend']) + $x .= sprintf(Lang::$spell['range'], ''.$this->curTpl['rangeMaxHostile'].' - '.$this->curTpl['rangeMaxHostile']. '').'
'; + // hardcode: "melee range" + else if ($this->curTpl['rangeMaxHostile'] == 5) + $x .= Lang::$spell['meleeRange'].'
'; + // regular case + else + $x .= sprintf(Lang::$spell['range'], $this->curTpl['rangeMaxHostile']).'
'; + } + + if ($reqWrapper) + $x .= '
'; + + $x .= ''; + + // cooldown or categorycooldown + if ($this->curTpl['recoveryTime']) + $x.= ''; + else if ($this->curTpl['recoveryCategory']) + $x.= ''; + + $x .= ''; + + if ($this->curTpl['stanceMask']) + $x.= ''; + + $x .= '
'; + + // cast times + if ($this->curTpl['interruptFlagsChannel']) + $x .= Lang::$spell['channeled']; + else if ($this->curTpl['castTime']) + $x .= sprintf(Lang::$spell['castIn'], $this->curTpl['castTime'] / 1000); + else if ($this->curTpl['attributes0'] & 0x10) // SPELL_ATTR0_ABILITY instant ability.. yeah, wording thing only + $x .= Lang::$spell['instantPhys']; + else // instant cast + $x .= Lang::$spell['instantMagic']; + + $x .= ''.sprintf(Lang::$game['cooldown'], Util::formatTime($this->curTpl['recoveryTime'], true)).''.sprintf(Lang::$game['cooldown'], Util::formatTime($this->curTpl['recoveryCategory'], true)).'
'.Lang::$game['requires'].' '.Lang::getStances($this->curTpl['stanceMask']).'
'; + $x .= '
'; + + if ($reqWrapper2) + $x .= ''; + + if ($tools) + { + $x .= ''; + } + + if ($reagents) + { + $x .= ''; + } + + if($desc && $desc <> '_empty_') + $x .= ''; + + if ($reqWrapper2) + $x .= "
'; + $x .= Lang::$spell['tools'].':
'; + while ($tool = array_pop($tools)) + { + if (isset($tool['itemId'])) + $x .= ''.$tool['name'].''; + else if (isset($tool['totemCategory'])) + $x .= ''.$tool['name'].''; + else + $x .= $tool['name']; + + if (!empty($tools)) + $x .= ', '; + else + $x .= '
'; + } + $x .= '
'; + $x .= Lang::$spell['reagents'].':
'; + while ($reagent = array_pop($reagents)) + { + $x .= ''.$reagent['name'].''; + if ($reagent['count'] > 1) + $x .= ' ('.$reagent['count'].')'; + + if(!empty($reagents)) + $x .= ', '; + else + $x .= '
'; + } + $x .= '
'.$desc.'
"; + + $this->tooltips[$this->Id] = $x; + } + + return $Id ? $this->tooltips[$Id] : true; + } + + public function getTalentHeadForCurrent() { // upper: cost :: range - // lower: time :: cool + // lower: time :: cooldown $x = ''; // power cost: pct over static $cost = ''; - if ($this->template['powerCostPercent'] > 0) - $cost .= $this->template['powerCostPercent']."% ".sprintf(Lang::$spell['pctCostOf'], strtolower(Lang::$spell['powerTypes'][$this->template['powerType']])); - else if ($this->template['powerCost'] > 0 || $this->template['powerPerSecond'] > 0 || $this->template['powerCostPerLevel'] > 0) - $cost .= ($this->template['powerType'] == 1 ? $this->template['powerCost'] / 10 : $this->template['powerCost']).' '.ucFirst(Lang::$spell['powerTypes'][$this->template['powerType']]); + if ($this->curTpl['powerCostPercent'] > 0) + $cost .= $this->curTpl['powerCostPercent']."% ".sprintf(Lang::$spell['pctCostOf'], strtolower(Lang::$spell['powerTypes'][$this->curTpl['powerType']])); + else if ($this->curTpl['powerCost'] > 0 || $this->curTpl['powerPerSecond'] > 0 || $this->curTpl['powerCostPerLevel'] > 0) + $cost .= ($this->curTpl['powerType'] == 1 ? $this->curTpl['powerCost'] / 10 : $this->curTpl['powerCost']).' '.ucFirst(Lang::$spell['powerTypes'][$this->curTpl['powerType']]); // append periodic cost - if ($this->template['powerPerSecond'] > 0) - $cost .= sprintf(Lang::$spell['costPerSec'], $this->template['powerPerSecond']); + if ($this->curTpl['powerPerSecond'] > 0) + $cost .= sprintf(Lang::$spell['costPerSec'], $this->curTpl['powerPerSecond']); // append level cost - if ($this->template['powerCostPerLevel'] > 0) - $cost .= sprintf(Lang::$spell['costPerLevel'], $this->template['powerCostPerLevel']); + if ($this->curTpl['powerCostPerLevel'] > 0) + $cost .= sprintf(Lang::$spell['costPerLevel'], $this->curTpl['powerCostPerLevel']); // ranges $range = ''; - if ($this->template['rangeMaxHostile']) + if ($this->curTpl['rangeMaxHostile']) { // minRange exists; show as range - if ($this->template['rangeMinHostile']) - $range .= sprintf(Lang::$spell['range'], $this->template['rangeMinHostile'].' - '.$this->template['rangeMaxHostile']); + if ($this->curTpl['rangeMinHostile']) + $range .= sprintf(Lang::$spell['range'], $this->curTpl['rangeMinHostile'].' - '.$this->curTpl['rangeMaxHostile']); // friend and hostile differ; do color - else if ($this->template['rangeMaxHostile'] != $this->template['rangeMaxFriend']) - $range .= sprintf(Lang::$spell['range'], ''.$this->template['rangeMaxHostile'].' - '.$this->template['rangeMaxHostile']. ''); + else if ($this->curTpl['rangeMaxHostile'] != $this->curTpl['rangeMaxFriend']) + $range .= sprintf(Lang::$spell['range'], ''.$this->curTpl['rangeMaxHostile'].' - '.$this->curTpl['rangeMaxHostile']. ''); // hardcode: "melee range" - else if ($this->template['rangeMaxHostile'] == 5) + else if ($this->curTpl['rangeMaxHostile'] == 5) $range .= Lang::$spell['meleeRange']; // regular case else - $range .= sprintf(Lang::$spell['range'], $this->template['rangeMaxHostile']); + $range .= sprintf(Lang::$spell['range'], $this->curTpl['rangeMaxHostile']); } // cast times $time = ''; - if ($this->template['interruptFlagsChannel']) + if ($this->curTpl['interruptFlagsChannel']) $time .= Lang::$spell['channeled']; - else if ($this->template['castTime']) - $time .= sprintf(Lang::$spell['castIn'], $this->template['castTime'] / 1000); - else if ($this->template['attributes0'] & 0x10) // SPELL_ATTR0_ABILITY instant ability.. yeah, wording thing only + else if ($this->curTpl['castTime']) + $time .= sprintf(Lang::$spell['castIn'], $this->curTpl['castTime'] / 1000); + else if ($this->curTpl['attributes0'] & 0x10) // SPELL_ATTR0_ABILITY instant ability.. yeah, wording thing only $time .= Lang::$spell['instantPhys']; else // instant cast $time .= Lang::$spell['instantMagic']; @@ -1177,10 +1223,10 @@ class Spell extends BaseType // cooldown or categorycooldown $cool = ''; - if ($this->template['recoveryTime']) - $cool.= sprintf(Lang::$game['cooldown'], Util::formatTime($this->template['recoveryTime'], true)).''; - else if ($this->template['recoveryCategory']) - $cool.= sprintf(Lang::$game['cooldown'], Util::formatTime($this->template['recoveryCategory'], true)).''; + if ($this->curTpl['recoveryTime']) + $cool.= sprintf(Lang::$game['cooldown'], Util::formatTime($this->curTpl['recoveryTime'], true)).''; + else if ($this->curTpl['recoveryCategory']) + $cool.= sprintf(Lang::$game['cooldown'], Util::formatTime($this->curTpl['recoveryCategory'], true)).''; // assemble parts @@ -1209,48 +1255,39 @@ class Spell extends BaseType public function getListviewData() { - return array( - 'id' => $this->Id, - 'name' => Util::localizedString($this->template, 'name'), - ); - } + // this is going to be .. ""fun"" - public function addGlobalsToJScript(&$gSpells) - { - // if the spell creates an item use the itemIcon instead - if ($this->template['effect1CreateItemId']) + $data = []; + + while ($this->iterate()) { - $item = new Item($this->template['effect1CreateItemId']); - $iconString = $item->template['icon']; - } - else - $iconString = $this->template['iconString']; - - $gSpells[$this->Id] = array( - 'icon' => $iconString, - 'name' => Util::localizedString($this->template, 'name'), - ); - } -} - - - -class SpellList extends BaseTypeList -{ - protected $setupQuery = 'SELECT *, Id AS ARRAY_KEY FROM ?_spell WHERE [filter] [cond] GROUP BY id'; - - public function __construct($conditions) - { - // may be called without filtering - if (class_exists('SpellFilter')) - { - $this->filter = new SpellFilter(); - if (($fiData = $this->filter->init()) === false) - return; + $data[$this->Id] = array( + 'name' => $this->names[$this->Id], + 'icon' => $this->curTpl['iconString'], + 'level' => $this->curTpl['baseLevel'], + ); } - parent::__construct($conditions); + return $data; } + + public function addGlobalsToJscript(&$refs) + { + if (!isset($refs['gSpells'])) + $refs['gSpells'] = []; + + while ($this->iterate()) + { + $iconString = isset($this->curTpl['createItemString']) ? 'createItemString' : 'iconString'; + + $refs['gSpells'][$this->Id] = array( + 'icon' => $this->curTpl[$iconString], + 'name' => $this->names[$this->Id], + ); + } + } + + public function addRewardsToJScript(&$refs) { } } ?> diff --git a/includes/class.title.php b/includes/class.title.php index 044fc489..9b227876 100644 --- a/includes/class.title.php +++ b/includes/class.title.php @@ -3,45 +3,57 @@ if (!defined('AOWOW_REVISION')) die('illegal access'); -class Title extends BaseType +class TitleList extends BaseType { - public $name = []; - public $source = []; + private $sources = []; - protected $setupQuery = "SELECT * FROM ?_titles WHERE `Id` = ?"; + protected $setupQuery = 'SELECT *, Id AS ARRAY_KEY FROM ?_titles WHERE [cond] ORDER BY Id ASC'; + protected $matchQuery = 'SELECT COUNT(1) FROM ?_titles WHERE [cond]'; public function __construct($data) { parent::__construct($data); // post processing - $this->name[GENDER_MALE] = Util::localizedString($this->template, 'male'); - if ($this->template['female_loc0'] || $this->template['female_loc'.User::$localeId]) - $this->name[GENDER_FEMALE] = Util::localizedString($this->template, 'female'); - - // preparse sources - if (!empty($this->template['source'])) + while ($this->iterate()) { - $sources = explode(' ', $this->template['source']); - foreach ($sources as $src) + // overwrite names with gender-speciffics + $this->names[$this->Id][GENDER_MALE] = Util::localizedString($this->curTpl, 'male'); + if ($this->curTpl['female_loc0'] || $this->curTpl['female_loc'.User::$localeId]) + $this->names[$this->Id][GENDER_FEMALE] = Util::localizedString($this->curTpl, 'female'); + + // preparse sources + if (!empty($this->curTpl['source'])) { - $src = explode(':', $src); - $this->source[$src[0]][] = $src[1]; + $sources = explode(' ', $this->curTpl['source']); + foreach ($sources as $src) + { + $src = explode(':', $src); + $this->sources[$this->Id][$src[0]][] = $src[1]; + } } } } public function getListviewData() { - $data = array( - 'id' => $this->Id, - 'name' => $this->name[GENDER_MALE], - 'side' => $this->template['side'], - 'gender' => $this->template['gender'], - 'expansion' => $this->template['expansion'], - 'category' => $this->template['category'], - 'source' => $this->source - ); + $data = []; + $this->createSource(); + + while ($this->iterate()) + { + $data[$this->Id] = array( + 'Id' => $this->Id, + 'name' => $this->names[$this->Id][GENDER_MALE], + 'side' => $this->curTpl['side'], + 'gender' => $this->curTpl['gender'], + 'expansion' => $this->curTpl['expansion'], + 'category' => $this->curTpl['category'] + ); + + if (!empty($this->curTpl['source'])) + $data[$this->Id]['source'] = $this->curTpl['source']; + } if (isset($this->name[GENDER_FEMALE])) $data['namefemale'] = $this->name[GENDER_FEMALE]; @@ -49,27 +61,77 @@ class Title extends BaseType return $data; } - public function addGlobalsToJScript(&$gTitles) + public function addGlobalsToJscript(&$refs) { - $gTitles[$this->Id] = ['name' => Util::jsEscape($this->name[GENDER_MALE])]; + if (!isset($refs['gTitles'])) + $refs['gTitles'] = []; - if (isset($this->name[GENDER_FEMALE])) - $gTitles[$this->Id]['namefemale'] = Util::jsEscape($this->name[GENDER_FEMALE]); + while ($this->iterate()) + { + $refs['gTitles'][$this->Id]['name'] = Util::jsEscape($this->names[$this->Id][GENDER_MALE]); - return true; + if (isset($this->names[$this->Id][GENDER_FEMALE])) + $refs['gTitles'][$this->Id]['namefemale'] = Util::jsEscape($this->names[$this->Id][GENDER_FEMALE]); + } + } + + private function createSource() + { + $sources = array( + 4 => [], // Quest + 12 => [], // Achievements + 13 => [] // simple text + ); + + while ($this->iterate()) + { + if (empty($this->sources[$this->Id])) + continue; + + foreach (array_keys($sources) as $srcKey) + if (isset($this->sources[$this->Id][$srcKey])) + $sources[$srcKey] = array_merge($sources[$srcKey], $this->sources[$this->Id][$srcKey]); + } + + // fill in the details + if (!empty($sources[4])) + $sources[4] = (new QuestList(array(['Id', $sources[4]])))->getSourceData(); + + if (!empty($sources[12])) + $sources[12] = (new AchievementList(array(['Id', $sources[12]])))->getSourceData(); + + if (!empty($sources[13])) + $sources[13] = DB::Aowow()->SELECT('SELECT *, Id AS ARRAY_KEY FROM ?_sourceStrings WHERE Id IN (?a)', $sources[13]); + + foreach ($this->sources as $Id => $src) + { + $tmp = []; + + // Quest-source + if (isset($src[4])) + foreach ($src[4] as $s) + $tmp[4][] = $sources[4][$s]; + + // Achievement-source + if (isset($src[12])) + foreach ($src[12] as $s) + $tmp[12][] = $sources[12][$s]; + + // other source (only one item possible, so no iteration needed) + if (isset($src[13])) + $tmp[13] = [Util::localizedString($sources[13][$this->sources[$Id][13][0]], 'source')]; + + $this->templates[$Id]['source'] = json_encode($tmp); + } } public function getHtmlizedName($gender = GENDER_MALE) { - return str_replace('%s', '<Name>', $this->name[$gender]); + return str_replace('%s', '<'.Lang::$main['name'].'>', $this->name[$gender]); } -} - - -class TitleList extends BaseTypeList -{ - protected $setupQuery = 'SELECT *, Id AS ARRAY_KEY FROM ?_titles WHERE [cond] ORDER BY Id ASC'; + public function addRewardsToJScript(&$ref) { } + public function renderTooltip() { } } ?> diff --git a/includes/class.worldevent.php b/includes/class.worldevent.php index d9741073..6c9b088a 100644 --- a/includes/class.worldevent.php +++ b/includes/class.worldevent.php @@ -3,7 +3,7 @@ if (!defined('AOWOW_REVISION')) die('illegal access'); -class WorldEvent +class WorldEvent extends BaseType { public static function getName($id) diff --git a/includes/defines.php b/includes/defines.php index 19b1bb86..0563e0da 100644 --- a/includes/defines.php +++ b/includes/defines.php @@ -19,7 +19,7 @@ define('TYPE_FACTION', 8); define('TYPE_PET', 9); define('TYPE_ACHIEVEMENT', 10); define('TYPE_TITLE', 11); -define('TYPE_EVENT', 12); +define('TYPE_WORLDEVENT', 12); define('TYPE_CLASS', 13); define('TYPE_RACE', 14); define('TYPE_SKILL', 15); @@ -33,8 +33,8 @@ define('CACHETYPE_SEARCH', 3); define('SEARCH_TYPE_REGULAR', 0x10000000); define('SEARCH_TYPE_OPEN', 0x20000000); define('SEARCH_TYPE_JSON', 0x40000000); -define('SEARCH_MASK_OPEN', 0x03FFFFFF); -define('SEARCH_MASK_ALL', 0x03FFFFFF); +define('SEARCH_MASK_OPEN', 0x017F807F); // open search +define('SEARCH_MASK_ALL', 0x07FFFFFF); // normal search // Databases define('DB_AOWOW', 0); @@ -94,6 +94,12 @@ define('LOCALE_DE', 3); define('LOCALE_ES', 6); define('LOCALE_RU', 8); +// Additional info in item-listviews +define('ITEMINFO_JSON', 0x1); +define('ITEMINFO_SUBITEMS', 0x2); +define('ITEMINFO_VENDOR', 0x4); +define('ITEMINFO_LOOT', 0x8); + /* * Game */ @@ -185,6 +191,7 @@ define('SPELL_SCHOOL_NATURE', 3); define('SPELL_SCHOOL_FROST', 4); define('SPELL_SCHOOL_SHADOW', 5); define('SPELL_SCHOOL_ARCANE', 6); +define('SPELL_ALL_SCHOOLS', 0x7F); // CharacterSlot define('SLOT_HEAD', 0); diff --git a/includes/kernel.php b/includes/kernel.php index ddd94e2a..92c6cfa6 100644 --- a/includes/kernel.php +++ b/includes/kernel.php @@ -20,7 +20,7 @@ require 'includes/class.database.php'; // autoload any List-Classes spl_autoload_register(function ($class) { - if (!strpos($class, 'Mysql') && !strpos($class, 'Filter')) + if (strpos($class, 'List')) require 'includes/class.'.strtr($class, ['List' => '']).'.php'; }); @@ -93,7 +93,7 @@ class Smarty_AoWoW extends Smarty if (!$cache) return false; - $cache = explode("\n", $cache, 2); + $cache = explode("\n", $cache); @list($time, $rev) = explode(' ', $cache[0]); $expireTime = $time + $this->config['page']['cacheTimer']; diff --git a/includes/utilities.php b/includes/utilities.php index 663fbc1c..f6f2d981 100644 --- a/includes/utilities.php +++ b/includes/utilities.php @@ -3,48 +3,19 @@ if (!defined('AOWOW_REVISION')) die('invalid access'); -class BaseType +abstract class BaseType { - public $template = null; - public $Id = 0; - - protected $setupQuery = ''; - - public function __construct($data) - { - if (!$this->setupQuery) - return false; - - if (is_array($data)) - $this->template = $data; - else - $this->template = DB::Aowow()->SelectRow($this->setupQuery, intVal($data)); - - if (empty($this->template)) - { - $this->template = null; - return false; - } - - $this->Id = isset($this->template['Id']) ? (int)$this->template['Id'] : (int)$this->template['entry']; - } - - // should return data required to display a listview of any kind - public function getListviewData() { } - - // should return data to extend global js variables for a certain type (e.g. g_items) - public function addGlobalsToJScript(&$ref) { } - - // should return data to extend global js variables for the rewards provided by this type (e.g. g_titles) - public function addRewardsToJscript(&$ref1, &$ref2 = null, &$ref3 = null) { } -} - -class BaseTypeList -{ - public $container = []; - public $filter = null; + public $names = []; + public $Id = 0; + public $matches = 0; // total matches unaffected by sqlLimit in config + public $error = true; + + protected $templates = []; + protected $curTpl = []; // lets iterate! + protected $filter = null; protected $setupQuery = ''; + protected $matchQuery = ''; /* * condition as array [field, value, operator] @@ -56,19 +27,34 @@ class BaseTypeList * ! - negated default value (NOT LIKE; <>; NOT IN) * condition as str * defines linking (AND || OR) + * condition as int + * defines LIMIT * * example: - * array(['id', 45], ['name', 'test', '!'], 'OR') + * array(['id', 45], ['name', 'test', '!'], 'OR', 5) * results in - * WHERE id = 45 OR name NOT LIKE %test%; + * WHERE id = 45 OR name NOT LIKE %test% LIMIT 5; */ - public function __construct($conditions) + public function __construct($conditions = []) { - if (!$this->setupQuery) - return false; + global $AoWoWconf; // yes i hate myself.. - $sql = []; - $linking = ' AND '; + $sql = []; + $linking = ' AND '; + $limit = ' LIMIT '.$AoWoWconf['sqlLimit']; + $className = strtr(get_class($this), ['List' => '']); + + if (!$this->setupQuery || !$this->matchQuery) + return; + + // may be called without filtering + if (class_exists($className.'Filter')) + { + $fiName = $className.'Filter'; + $this->filter = new $fiName(); + if ($this->filter->init() === false) + return; + } foreach ($conditions as $c) { @@ -90,6 +76,9 @@ class BaseTypeList else continue; + if (isset($c[2]) && $c[2] != '!') + $op = $c[2]; + if (is_array($c[1])) { $op = (isset($c[2]) && $c[2] == '!') ? 'NOT IN' : 'IN'; @@ -109,52 +98,84 @@ class BaseTypeList else continue; - if (isset($c[2]) && $c[2] != '!') - $op = $c[2]; - $sql[] = $field.' '.$op.' '.$val; } else if (is_string($c)) - $linking = $c == 'OR' ? ' OR ' : ' AND '; - else + $linking = $c == 'AND' ? ' AND ' : ' OR '; + else if (is_int($c)) + $limit = $c > 0 ? ' LIMIT '.$c : ''; continue; // ignore other possibilities } // todo: add strings propperly without them being escaped by simpleDB..? - $this->setupQuery = str_replace('[filter]', $this->filter && $this->filter->buildFilterQuery() ? $this->filter->query.' AND ' : NULL, $this->setupQuery); - $this->setupQuery = str_replace('[cond]', empty($sql) ? '1' : '('.implode($linking, $sql).')', $this->setupQuery); + $this->setupQuery = str_replace('[filter]', $this->filter && $this->filter->buildFilterQuery() ? $this->filter->query.' AND ' : NULL, $this->setupQuery); + $this->setupQuery = str_replace('[cond]', empty($sql) ? '1' : '('.implode($linking, $sql).')', $this->setupQuery); + $this->setupQuery .= $limit; - $rows = DB::Aowow()->Select($this->setupQuery); - $className = str_replace('List', '', get_class($this)); + $this->matchQuery = str_replace('[filter]', $this->filter && $this->filter->buildFilterQuery() ? $this->filter->query.' AND ' : NULL, $this->matchQuery); + $this->matchQuery = str_replace('[cond]', empty($sql) ? '1' : '('.implode($linking, $sql).')', $this->matchQuery); - foreach ($rows as $k => $row) - $this->container[$k] = new $className($row); // free dirty mindfuck galore here... + $rows = DB::Aowow()->Select($this->setupQuery); + if (!$rows) + return; + + $this->matches = DB::Aowow()->SelectCell($this->matchQuery); + + foreach ($rows as $k => $tpl) + { + $this->names[$k] = Util::localizedString($tpl, Util::getNameFieldName($tpl)); + $this->templates[$k] = $tpl; + } + + $this->reset(); + + $this->error = false; } - public function getListviewData() + public function iterate($qty = 1) { - $data = []; - // no extra queries required, just call recursively - foreach ($this->container as $type) - $data[] = $type->getListviewData(); + if (!$this->curTpl) // exceeded end of line .. array .. in last iteration + reset($this->templates); - return $data; + $this->curTpl = current($this->templates); + $field = $this->curTpl ? Util::getIdFieldName($this->curTpl) : null; + $this->Id = $this->curTpl ? $this->curTpl[$field] : 0; + + while ($qty--) + next($this->templates); + + return $this->Id; } - public function addGlobalsToJScript(&$ref) + public function reset() { - // no extra queries required, just call recursively - foreach ($this->container as $type) - $type->addGlobalsToJScript($ref); + $this->curTpl = reset($this->templates); + $this->Id = $this->curTpl[Util::getIdFieldName($this->curTpl)]; } - public function addRewardsToJScript(&$ref1, &$ref2 = null, &$ref3 = null) + // read-access to templates + public function getField($field) { - // no extra queries required, just call recursively - foreach ($this->container as $type) - $type->addRewardsToJScript($ref1, $ref2, $ref3); + if (!$this->curTpl || !isset($this->curTpl[$field])) + return null; + + return $this->curTpl[$field]; } + + // should return data required to display a listview of any kind + // this is a rudimentary example, that will not suffice for most Types + abstract public function getListviewData(); + + // should return data to extend global js variables for a certain type (e.g. g_items) + abstract public function addGlobalsToJScript(&$ref); + + // should return data to extend global js variables for the rewards provided by this type (e.g. g_titles) + // rewards will not always be required and only by Achievement and Quest .. but yeah.. maybe it should be merged with addGlobalsToJScript + abstract public function addRewardsToJScript(&$ref); + + // NPC, GO, Item, Quest, Spell, Achievement, Profile would require this + abstract public function renderTooltip(); } class Lang @@ -234,7 +255,7 @@ class Lang public static function getMagicSchools($schoolMask) { - $schoolMask &= 0x7F; // clamp to available schools.. + $schoolMask &= SPELL_ALL_SCHOOLS; // clamp to available schools.. $tmp = []; $i = 1; @@ -335,7 +356,7 @@ class Util 'enus', null, 'frfr', 'dede', null, null, 'eses', null, 'ruru' ); - private static $typeStrings = array( // zero-indexed + public static $typeStrings = array( // zero-indexed null, 'npc', 'object', 'item', 'itemset', 'quest', 'spell', 'zone', 'faction', 'pet', 'achievement', 'title', 'event', 'class', 'race', 'skill', null, 'currency' ); @@ -1055,10 +1076,10 @@ class Util return strtr(trim($string), array( '\\' => '\\\\', "'" => "\\'", - '"' => '\\"', + // '"' => '\\"', "\r" => '\\r', "\n" => '\\n', - ' '<\/', + // ' '<\/', )); } @@ -1070,7 +1091,7 @@ class Util if (!empty($data[$field.'_loc'.User::$localeId])) return $data[$field.'_loc'.User::$localeId]; - // locale not enUS; aowow-type localization available + // locale not enUS; aowow-type localization available; add brackets else if (User::$localeId != LOCALE_EN && isset($data[$field.'_loc0']) && !empty($data[$field.'_loc0'])) return '['.$data[$field.'_loc0'].']'; @@ -1124,7 +1145,7 @@ class Util return sprintf(Lang::$item['ratingString'], '' . $result, '' . $level); } - public static function powerUseLocale($domain) + public static function powerUseLocale($domain = 'www') { foreach (Util::$localeStrings as $k => $v) { @@ -1138,7 +1159,6 @@ class Util if ($domain == 'www') { - /* todo: dont .. should use locale given by inclusion of aowowPower .. should be fixed in aowowPower.js */ User::useLocale(LOCALE_EN); Lang::load(User::$localeString); } @@ -1172,8 +1192,9 @@ class Util break; case 3: case 7: - $spl = new Spell($enchant['object'.$h]); + $spl = new SpellList(array(['Id', (int)$enchant['object'.$h]])); $gain = $spl->getStatGain(); + foreach ($gain as $k => $v) // array_merge screws up somehow... @$jsonStats[$k] += $v; break; @@ -1219,6 +1240,35 @@ class Util return $return; } + + + // BaseType::_construct craaap! + // todo: unify names + public static function getNameFieldName($tpl) + { + if (isset($tpl['name']) || isset($tpl['name_loc0'])) + return 'name'; + else if (isset($tpl['title']) || isset($tpl['title_loc0'])) + return 'title'; + else if (isset($tpl['male']) || isset($tpl['male_loc'])) + return 'male'; + else + return null; + } + + // BaseType::iterate craaaaaaaaap!!! + // todo: unify indizes + public static function getIdFieldName($tpl) + { + if (isset($tpl['entry'])) + return 'entry'; + else if (isset($tpl['Id'])) + return 'Id'; + else if (isset($tpl['ID'])) + return 'ID'; + else + return null; + } } ?> diff --git a/opensearch.php b/opensearch.php index 4007ae37..a6b9fd65 100644 --- a/opensearch.php +++ b/opensearch.php @@ -96,12 +96,12 @@ if ($_type & 0x18) { // 3 | 4 $iList = new ItemList($conditions); $items = []; - foreach ($iList->container as $id => $item) + while ($iList->iterate()) { - $item->getJsonStats($pieceAssoc); + $iList->extendJsonStats($pieceAssoc); $stats = []; - foreach ($item->json as $k => $v) + foreach ($iList->json[$iList->Id] as $k => $v) { if (!$v && $k != 'classs' && $k != 'subclass') continue; @@ -109,10 +109,10 @@ if ($_type & 0x18) { // 3 | 4 $stats[] = is_numeric($v) || $v[0] == "{" ? '"'.$k.'":'.$v.'' : '"'.$k.'":"'.$v.'"'; } - foreach ($item->itemMods as $k => $v) + foreach ($iList->itemMods[$iList->Id] as $k => $v) $stats[] = '"'.Util::$itemMods[$k].'":'.$v.''; - $items[$id] = "\t{".implode(',', $stats)."}"; + $items[$iList->Id] = "\t{".implode(',', $stats)."}"; } echo implode(",\n", $items)."\n],[\n"; diff --git a/pages/account.php b/pages/account.php index 0935458b..2793cf61 100644 --- a/pages/account.php +++ b/pages/account.php @@ -1,21 +1,21 @@ 'activate_usernamelength', - 'ACCT_PASSWORD_LENGTH' => 'activate_passwordlength', - 'ACCT_USERNAME_SYMBOLS' => 'activate_invalidusername', - 'ACCT_PASSWORD_SYMBOLS' => 'activate_invalidpassword', - 'ACCT_EMAIL_SYMBOLS' => 'signup_emailinvalid', + 'ACCT_USERNAME_LENGTH' => 'activate_usernamelength', + 'ACCT_PASSWORD_LENGTH' => 'activate_passwordlength', + 'ACCT_USERNAME_SYMBOLS' => 'activate_invalidusername', + 'ACCT_PASSWORD_SYMBOLS' => 'activate_invalidpassword', + 'ACCT_EMAIL_SYMBOLS' => 'signup_emailinvalid', - 'ACCT_PASSWORDS_NOT_EQUAL' => 'signup_passwordsnotequal', - 'ACCT_USERNAME_EXISTS' => 'activate_usernameinuse', - 'ACCT_NO_SUCH_ACCT' => 'signin_un_or_pass_fail', + 'ACCT_PASSWORDS_NOT_EQUAL' => 'signup_passwordsnotequal', + 'ACCT_USERNAME_EXISTS' => 'activate_usernameinuse', + 'ACCT_NO_SUCH_ACCT' => 'signin_un_or_pass_fail', 'ACCT_IP_LOCKED' => 'signin_ip_locked', - 'ACCT_SIGNUP_BLOCKED' => 'signup_blocked', - 'ACCT_SIGNIN_BLOCKED' => 'signin_blocked', + 'ACCT_SIGNUP_BLOCKED' => 'signup_blocked', + 'ACCT_SIGNIN_BLOCKED' => 'signin_blocked', - 'ACCT_INTERNAL_ERROR' => 'internal_error', + 'ACCT_INTERNAL_ERROR' => 'internal_error', )); enum(array( // UserPropsLimits @@ -97,7 +97,8 @@ function signin() function signup() { -/* $username = Get(GET_STRING, 'username', 'POST'); +/* + $username = Get(GET_STRING, 'username', 'POST'); $password = Get(GET_STRING, 'password', 'POST'); $pwd2 = Get(GET_STRING, 'password2', 'POST'); $email = Get(GET_STRING, 'email', 'POST'); diff --git a/pages/compare.php b/pages/compare.php index ffd05b07..10500ab0 100644 --- a/pages/compare.php +++ b/pages/compare.php @@ -4,10 +4,10 @@ if (!defined('AOWOW_REVISION')) die('invalid access'); $pageData = array( - 'summary' => '[]', - 'items' => [] + 'items' => null, + 'summary' => '[]' ); -$compareString = ''; +$compareString = ''; // prefer $_GET over $_COOKIE if (!empty($_GET['compare'])) @@ -48,22 +48,23 @@ if ($compareString) $pageData['summary'] = "[".implode(',', $outSet)."]"; $iList = new ItemList(array(['i.entry', $items])); - foreach ($iList->container as $item) + while ($iList->iterate()) { - $item->getJsonStats(); + $iList->extendJsonStats(); $stats = []; - foreach ($item->json as $k => $v) + + foreach ($iList->json[$iList->Id] as $k => $v) $stats[] = is_numeric($v) || $v[0] == "{" ? '"'.$k.'":'.$v.'' : '"'.$k.'":"'.$v.'"'; - foreach ($item->itemMods as $k => $v) + foreach ($iList->itemMods[$iList->Id] as $k => $v) if ($v) $stats[] = '"'.Util::$itemMods[$k].'":'.$v; $pageData['items'][] = [ - $item->Id, - Util::jsEscape(Util::localizedString($item->template, 'name')), - $item->template['Quality'], - $item->template['icon'], + $iList->Id, + Util::jsEscape($iList->names[$iList->Id]), + $iList->getField('Quality'), + $iList->getField('icon'), "{".implode(",", $stats)."}" ]; } diff --git a/pages/item.php b/pages/item.php index f53e6cce..953dc72b 100644 --- a/pages/item.php +++ b/pages/item.php @@ -11,20 +11,18 @@ if (!defined('AOWOW_REVISION')) // require 'includes/class.community.php'; // wo dont need those .. yet $id = intVal($pageParam); -$item = new Item($id); +$item = new ItemList(array(['i.entry', $id])); $cacheKeyPage = implode('_', [CACHETYPE_PAGE, TYPE_ITEM, $id, -1, User::$localeId]); if (isset($_GET['xml'])) -{ - // output item info as xml - // why should i implement this..? -} -else if (isset($_GET['power'])) + die('unsupported, as i do not see the point'); + +if (isset($_GET['power'])) { header('Content-type: application/x-javascript; charsetUTF-8'); - Util::powerUseLocale($_GET['domain']); + Util::powerUseLocale(@$_GET['domain']); $enh = []; $itemString = $id; @@ -50,21 +48,20 @@ else if (isset($_GET['power'])) $itemString .= 's'; } - // : are not accepted in filenames $cacheKeyTooltip = implode('_', [CACHETYPE_TOOLTIP, TYPE_ITEM, str_replace(':', ',', $itemString), -1, User::$localeId]); // output json for tooltips if (!$smarty->loadCache($cacheKeyTooltip, $x)) { - if (!$item->template) + if ($item->error) die('$WowheadPower.registerItem(\''.$itemString.'\', '.User::$localeId.', {})'); - $item->createTooltip($enh); + $item->renderTooltip($enh); $x .= '$WowheadPower.registerItem(\''.$itemString.'\', '.User::$localeId.", {\n"; - $x .= "\tname_".User::$localeString.": '".Util::jsEscape($item->name)."',\n"; - $x .= "\tquality: ".$item->template['Quality'].",\n"; - $x .= "\ticon: '".Util::jsEscape($item->template['icon'])."',\n"; - $x .= "\ttooltip_".User::$localeString.": '".Util::jsEscape($item->tooltip)."'\n"; + $x .= "\tname_".User::$localeString.": '".Util::jsEscape($item->names[$item->Id])."',\n"; + $x .= "\tquality: ".$item->getField('Quality').",\n"; + $x .= "\ticon: '".Util::jsEscape($item->getField('icon'))."',\n"; + $x .= "\ttooltip_".User::$localeString.": '".Util::jsEscape($item->tooltip[$item->Id])."'\n"; $x .= "});"; $smarty->saveCache($cacheKeyTooltip, $x); diff --git a/pages/spell.php b/pages/spell.php index 26ed6c84..7e681b93 100644 --- a/pages/spell.php +++ b/pages/spell.php @@ -8,33 +8,33 @@ if (!defined('AOWOW_REVISION')) // require 'includes/allquests.php'; // require 'includes/class.community.php'; // not needed .. yet -$id = intVal($pageParam); -$spell = new Spell($id); +$Id = intVal($pageParam); -$cacheKeyPage = implode('_', [CACHETYPE_PAGE, TYPE_SPELL, $id, -1, User::$localeId]); -$cacheKeyTooltip = implode('_', [CACHETYPE_TOOLTIP, TYPE_SPELL, $id, -1, User::$localeId]); +$cacheKeyPage = implode('_', [CACHETYPE_PAGE, TYPE_SPELL, $Id, -1, User::$localeId]); +$cacheKeyTooltip = implode('_', [CACHETYPE_TOOLTIP, TYPE_SPELL, $Id, -1, User::$localeId]); if (isset($_GET['power'])) { header('Content-type: application/x-javascript; charsetUTF-8'); - Util::powerUseLocale($_GET['domain']); + Util::powerUseLocale(@$_GET['domain']); if (!$smarty->loadCache($cacheKeyTooltip, $x)) { - $spell = new Spell($id); - if (!$spell->template) - die('$WowheadPower.registerSpell(\''.$id.'\', '.User::$localeId.', {})'); + $spell = new SpellList(array(['Id', $Id])); - $x = '$WowheadPower.registerSpell('.$id.', '.User::$localeId.",{\n"; - if ($n = Util::localizedString($spell->template, 'spellname')) + if ($spell->error) + die('$WowheadPower.registerSpell('.$Id.', '.User::$localeId.', {});'); + + $x = '$WowheadPower.registerSpell('.$Id.', '.User::$localeId.", {\n"; + if ($n = $spell->names[$Id]) $x .= "\tname_".User::$localeString.": '".Util::jsEscape($n)."',\n"; - if ($i = $spell->template['iconString']) + if ($i = $spell->getField('iconString')) $x .= "\ticon: '".Util::jsEscape($i)."',\n"; - if ($spell->getTooltip()) - $x .= "\ttooltip_".User::$localeString.": '".Util::jsEscape($spell->tooltip)."'"; - if ($spell->getBuff()) - $x .= ",\n\tbuff_".User::$localeString.": '".Util::jsEscape($spell->buff)."'\n"; + if ($t = $spell->renderTooltip($Id)) + $x .= "\ttooltip_".User::$localeString.": '".Util::jsEscape($t)."'"; + if ($b = $spell->renderBuff($Id)) + $x .= ",\n\tbuff_".User::$localeString.": '".Util::jsEscape($b)."'\n"; $x .= '});'; $smarty->saveCache($cacheKeyTooltip, $x); @@ -42,16 +42,14 @@ if (isset($_GET['power'])) die($x); } +if (!$smarty->loadCache($cacheKeyPage, $pageData)) +{ + $spell = new SpellList(array(['Id', $Id])); // v there be dragons v - -if (!$smarty->loadCache($cacheKeyPage, $pageData)) -{ - unset($spell); - // Spelldata - if ($spellObj = new Spell($id)) + if ($spellObj = new SpellList(array(['Id', $Id]))) { $row = $spellObj->template; // equivalent to 5 layers of panzertape @@ -142,7 +140,7 @@ if (!$smarty->loadCache($cacheKeyPage, $pageData)) $spell['stances'] = Lang::getStances($row['stanceMask']); // Btt - Buff TollTip - if ($buff = $spellObj->getBuff()) + if ($buff = $spellObj->renderBuff()) $spell['btt'] = $buff; // Iterate through all effects: @@ -566,7 +564,7 @@ if (!$smarty->loadCache($cacheKeyPage, $pageData)) FROM ?_spellicons s, ?_achievementcriteria c, ?_achievement a LEFT JOIN (?_zones z) ON a.map != -1 AND a.map = z.mapID WHERE - a.iconId = s.id + a.icon = s.id AND a.id = c.refAchievement AND c.type IN (?a) AND c.value1 = ?d diff --git a/pages/title.php b/pages/title.php index 875ef7b0..ffd3a96d 100644 --- a/pages/title.php +++ b/pages/title.php @@ -12,43 +12,54 @@ $cacheKeyPage = implode('_', [CACHETYPE_PAGE, TYPE_TITLE, $Id, -1, User::$locale if (!$smarty->loadCache($cacheKeyPage, $pageData)) { - $title = new Title($Id); - if ($title->template) + $title = new TitleList(array(['Id', $Id])); + if ($title->error) { - $title->addGlobalsToJScript($pageData['gTitles']); + $smarty->updatePageVars(array( + 'subject' => ucfirst(Lang::$game['title']), + 'id' => $Id, + 'notFound' => sprintf(Lang::$main['pageNotFound'], Lang::$game['title']), + )); + $smarty->assign('lang', Lang::$main); + $smarty->display('404.tpl'); + exit(); + } + else + { + $title->addGlobalsToJscript($pageData); $infobox = []; $colon = User::$localeId == LOCALE_FR ? ' : ' : ': '; // Je suis un prick! <_< - if ($title->template['side'] == 1) + if ($title->getField('side') == 1) $infobox[] = Lang::$main['side'].$colon.'[span class=alliance-icon]'.Lang::$game['alliance'].'[/span]'; - else if ($title->template['side'] == 2) + else if ($title->getField('side') == 2) $infobox[] = Lang::$main['side'].$colon.'[span class=horde-icon]'.Lang::$game['horde'].'[/span]'; else $infobox[] = Lang::$main['side'].$colon.Lang::$main['both']; - if ($title->template['gender']) - $infobox[] = Lang::$main['gender'].$colon.'[span class='.($title->template['gender'] == 2 ? 'female' : 'male').'-icon]'.Lang::$main['sex'][$title->template['gender']].'[/span]'; + if ($g = $title->getField('gender')) + $infobox[] = Lang::$main['gender'].$colon.'[span class='.($g == 2 ? 'female' : 'male').'-icon]'.Lang::$main['sex'][$g].'[/span]'; - if ($title->template['eventId']) - $infobox[] = Lang::$game['eventShort'].$colon.'[url=?event='.$title->template['eventId'].']'.WorldEvent::getName($title->template['eventId']).'[/url]'; + if ($e = $title->getField('eventId')) + $infobox[] = Lang::$game['eventShort'].$colon.'[url=?event='.$e.']'.WorldEvent::getName($e).'[/url]'; $pageData = array( 'page' => array( 'name' => $title->getHtmlizedName(), - 'id' => $title->Id, - 'expansion' => Util::$expansionString[$title->template['expansion']] + 'id' => $Id, + 'expansion' => Util::$expansionString[$title->getField('expansion')] ), 'infobox' => '[li][ul]'.implode('[/ul][ul]', $infobox).'[/ul][/li]', ); - foreach ($title->source as $type => $entries) + foreach ($title->sources[$Id] as $type => $entries) { // todo: hidden-/visibleCols by actual use switch ($type) { case 4: - $quests = new QuestList(array(['id', $entries])); - $quests->addRewardsToJscript($pageData['gItems'], $pageData['gSpells'], $pageData['gTitles']); + $quests = new QuestList(array(['Id', $entries])); + $quests->addRewardsToJscript($pageData); $pageData['page']['questReward'] = $quests->getListviewData(); $pageData['page']['questParams'] = array( @@ -59,9 +70,9 @@ if (!$smarty->loadCache($cacheKeyPage, $pageData)) ); break; case 12: - $acvs = new AchievementList(array(['id', $entries])); - $acvs->addGlobalsToJScript($pageData['gAchievements']); - $acvs->addRewardsToJscript($pageData['gItems'], $pageData['gTitles']); + $acvs = new AchievementList(array(['Id', $entries])); + $acvs->addGlobalsToJscript($pageData); + $acvs->addRewardsToJscript($pageData); $pageData['page']['acvReward'] = $acvs->getListviewData(); $pageData['page']['acvParams'] = array( @@ -76,30 +87,21 @@ if (!$smarty->loadCache($cacheKeyPage, $pageData)) } } $pageData['title'] = ucFirst(trim(str_replace('%s', '', str_replace(',', '', $title->name[0])))); + $pageData['path'] = '[0, 10, '.$title->getField('category').']'; $smarty->saveCache($cacheKeyPage, $pageData); } - else - { - $smarty->updatePageVars(array( - 'subject' => ucfirst(Lang::$game['title']), - 'id' => $Id, - 'notFound' => sprintf(Lang::$main['pageNotFound'], Lang::$game['title']), - )); - $smarty->assign('lang', Lang::$main); - $smarty->display('404.tpl'); - exit(); - } } $smarty->updatePageVars(array( 'title' => $pageData['title']." - ".ucfirst(Lang::$game['title']), - 'path' => "[0, 10, ".$title->template['category']."]", + 'path' => $pageData['path'], 'tab' => 0, // for g_initHeader($tab) 'type' => TYPE_TITLE, // 11:Titles 'typeId' => $Id )); + // Announcements $announcements = DB::Aowow()->Select('SELECT * FROM ?_announcements WHERE flags & 0x10 AND (page = "title" OR page = "*")'); foreach ($announcements as $k => $v) diff --git a/pages/titles.php b/pages/titles.php index e9d5f1cb..6463d679 100644 --- a/pages/titles.php +++ b/pages/titles.php @@ -19,65 +19,14 @@ if (!$smarty->loadCache($cacheKey, $pageData)) $titles = new TitleList(isset($cat) ? array(['category', (int)$cat]) : []); $listview = $titles->getListviewData(); - $sources = array( - 4 => [], // Quest - 12 => [], // Achievement - 13 => [] // DB-Text + $pageData = array( + 'page' => $listview, + 'params' => array( + 'parent' => false, + 'tabs' => false + ) ); - // parse sources - foreach ($listview as $lvTitle) - { - if(!isset($lvTitle['source'])) - continue; - - foreach (array_keys($sources) as $srcKey) - if (isset($lvTitle['source'][$srcKey])) - $sources[$srcKey] = array_merge($sources[$srcKey], $lvTitle['source'][$srcKey]); - } - - // replace with suitable objects - if (!empty($sources[4])) - $sources[4] = new QuestList(array(['Id', $sources[4]])); - - if (!empty($sources[12])) - $sources[12] = new AchievementList(array(['Id', $sources[12]])); - - if (!empty($sources[13])) - $sources[13] = DB::Aowow()->SELECT('SELECT *, Id AS ARRAY_KEY FROM ?_sourceStrings WHERE Id IN (?a)', $sources[13]); - - foreach ($listview as $k => $lvTitle) - { - if(!isset($lvTitle['source'])) - continue; - - // Quest-source - if (isset($lvTitle['source'][4])) - { - $ids = $lvTitle['source'][4]; - $listview[$k]['source'][4] = []; - foreach ($ids as $id) - $listview[$k]['source'][4][] = $sources[4]->container[$id]->getSourceData(); - } - - // Achievement-source - if (isset($lvTitle['source'][12])) - { - $ids = $lvTitle['source'][12]; - $listview[$k]['source'][12] = []; - foreach ($ids as $id) - $listview[$k]['source'][12][] = $sources[12]->container[$id]->getSourceData(); - } - - // other source (only one item possible, so no iteration needed) - if (isset($lvTitle['source'][13])) - $listview[$k]['source'][13] = [$sources[13][$lvTitle['source'][13][0]]]; - - $listview[$k]['source'] = json_encode($listview[$k]['source']); - } - - $pageData['page'] = $listview; - $smarty->saveCache($cacheKey, $pageData); } diff --git a/setup/tools/dataset-assembler/enchants.php b/setup/tools/dataset-assembler/enchants.php index 5f497365..90fd45e3 100644 --- a/setup/tools/dataset-assembler/enchants.php +++ b/setup/tools/dataset-assembler/enchants.php @@ -55,7 +55,7 @@ if (!defined('AOWOW_REVISION')) // from g_item_slots: 13:"One-Hand", 26:"Ranged", 17:"Two-Hand", $slotPointer = [13, 17, 26, 26, 13, 17, 17, 13, 17, null, 17, null, null, 13, null, 13, null, null, null, null, 17]; $locales = [LOCALE_EN, LOCALE_FR, LOCALE_DE, LOCALE_ES, LOCALE_RU]; - $enchantSpells = new SpellList([['effect1Id', '=', '53'], ['name_loc0', 'NOT LIKE', 'QA%']]); // enchantItemPermanent && !qualityAssurance + $enchantSpells = new SpellList([['effect1Id', 53], ['name_loc0', 'QA%', '!']]); // enchantItemPermanent && !qualityAssurance $castItems = []; $jsonEnchants = []; @@ -72,29 +72,29 @@ if (!defined('AOWOW_REVISION')) $enchantsOut = []; - foreach ($enchantSpells->spellList as $spl) + while ($enchantSpells->iterate()) { - $enchant = DB::Aowow()->SelectRow('SELECT * FROM ?_itemEnchantment WHERE Id = ?d', $spl->template['effect1MiscValue']); + $enchant = DB::Aowow()->SelectRow('SELECT * FROM ?_itemEnchantment WHERE Id = ?d', $enchantSpells->getField('effect1MiscValue')); if (!$enchant) // 'shouldn't' happen continue; // slots have to be recalculated $slot = 0; - if ($spl->template['equippedItemClass'] == 4) // armor + if ($enchantSpells->getField('equippedItemClass') == 4) // armor { - if ($invType = $spl->template['equippedItemInventoryTypeMask']) - $slot = $spl->template['equippedItemInventoryTypeMask'] >> 1; + if ($invType = $enchantSpells->getField('equippedItemInventoryTypeMask')) + $slot = $enchantSpells->getField('equippedItemInventoryTypeMask') >> 1; else /* if (equippedItemSubClassMask == 64) */ // shields have it their own way <_< $slot = (1 << (14 - 1)); } - else if ($spl->template['equippedItemClass'] == 2) // weapon + else if ($enchantSpells->getField('equippedItemClass') == 2) // weapon { foreach ($slotPointer as $i => $sp) { if (!$sp) continue; - if ((1 << $i) & $spl->template['equippedItemSubClassMask']) + if ((1 << $i) & $enchantSpells->getField('equippedItemSubClassMask')) { if ($sp == 13) // also mainHand & offHand *siiigh* $slot |= ((1 << (21 - 1)) | (1 << (22 - 1))); @@ -112,7 +112,7 @@ if (!defined('AOWOW_REVISION')) $ench = array( 'name' => [], // set by skill or item 'quality' => -1, // modified if item - 'icon' => strToLower($spl->template['iconString']), // item over spell + 'icon' => strToLower($enchantSpells->getField('iconString')), // item over spell 'source' => [], // <0: item; >0:spell 'skill' => -1, // modified if skill 'slots' => [], // determied per spell but set per item @@ -132,37 +132,38 @@ if (!defined('AOWOW_REVISION')) $ench['jsonequip']['reqlevel'] = $enchant['requiredLevel']; // check if the spell has an entry in skill_line_ability -> Source:Profession - if ($skill = DB::Aowow()->SelectCell('SELECT skillId FROM ?_skill_line_ability WHERE spellId = ?d', $spl->Id)) + if ($skill = DB::Aowow()->SelectCell('SELECT skillId FROM ?_skill_line_ability WHERE spellId = ?d', $enchantSpells->Id)) { - $ench['name'][] = Util::jsEscape(Util::localizedString($spl->template, 'name')); - $ench['source'][] = $spl->Id; + $ench['name'][] = Util::jsEscape($enchantSpells->names[$enchantSpells->Id])); + $ench['source'][] = $enchantSpells->Id; $ench['skill'] = $skill; $ench['slots'][] = $slot; } // check if this item can be cast via item -> Source:Item - if (!isset($castItems[$spl->Id])) - $castItems[$spl->Id] = new ItemList([['spellid_1', '=', $spl->Id], ['name', 'NOT LIKE', 'Scroll of Enchant%']]); // do not reuse enchantment scrolls + if (!isset($castItems[$enchantSpells->Id])) + $castItems[$enchantSpells->Id] = new ItemList([['spellid_1', $enchantSpells->Id], ['name', 'Scroll of Enchant%', '!']]); // do not reuse enchantment scrolls - foreach ($castItems[$spl->Id]->container as $item) + $cI &= $castItems[$enchantSpells->Id]; // this construct is a bit .. unwieldy + while ($cI->iterate()) { - $ench['name'][] = Util::jsEscape(Util::localizedString($item->template, 'name')); - $ench['source'][] = -$item->Id; - $ench['icon'] = strTolower($item->template['icon']); + $ench['name'][] = Util::jsEscape($cI->names[$cI->Id]); + $ench['source'][] = -$cI->Id; + $ench['icon'] = strTolower($cI->getField('icon')); $ench['slots'][] = $slot; - if ($item->template['Quality'] > $ench['quality']) - $ench['quality'] = $item->template['Quality']; + if ($cI->getField('Quality') > $ench['quality']) + $ench['quality'] = $cI->getField('Quality'); - if ($item->template['AllowableClass'] > 0) + if ($cI->getField('AllowableClass') > 0) { - $ench['classes'] = $item->template['AllowableClass']; - $ench['jsonequip']['classes'] = $item->template['AllowableClass']; + $ench['classes'] = $cI->getField('AllowableClass'); + $ench['jsonequip']['classes'] = $cI->getField('AllowableClass'); } if (!isset($ench['jsonequip']['reqlevel'])) - if ($item->template['RequiredLevel'] > 0) - $ench['jsonequip']['reqlevel'] = $item->template['RequiredLevel']; + if ($cI->getField('RequiredLevel') > 0) + $ench['jsonequip']['reqlevel'] = $cI->getField('RequiredLevel'); } // enchant spell not in use diff --git a/setup/tools/dataset-assembler/glyphs.php b/setup/tools/dataset-assembler/glyphs.php index f0e2c980..0303c484 100644 --- a/setup/tools/dataset-assembler/glyphs.php +++ b/setup/tools/dataset-assembler/glyphs.php @@ -127,6 +127,13 @@ if (!defined('AOWOW_REVISION')) echo "script set up in ".Util::execTime()."
\n"; + $glyphSpells = []; + foreach ($glyphList as $pop) + if ($pop['glyphEffect']) + $glyphSpells[] = $pop['glyphEffect']; + + $glyphSpells = new SpellList(array(['Id', $glyphSpells])); + foreach ($locales as $lId) { User::useLocale($lId); @@ -138,16 +145,17 @@ if (!defined('AOWOW_REVISION')) if (!$pop['glyphEffect']) continue; - $spl = new Spell($pop['glyphEffect']); + while ($glyphSpells->Id != $pop['glyphEffect']) + $glyphSpells->iterate(); - if ($spl->template['effect1Id'] != 6 && $spl->template['effect2Id'] != 6 && $spl->template['effect3Id'] != 6) + if ($glyphSpells->getField('effect1Id') != 6 && $glyphSpells->getField('effect2Id') != 6 && $glyphSpells->getField('effect3Id') != 6) continue; if ($pop['itemId'] == 42958) // Crippling Poison has no skillLine.. oO => hardcode { $glyphsOut[$pop['itemId']] = array( 'name' => Util::jsEscape(Util::localizedString($pop, 'name')), - 'description' => Util::jsEscape($spl->parseText()), + 'description' => Util::jsEscape($glyphSpells->parseText()), 'icon' => 'ability_poisonsting', 'type' => 0, 'classs' => $pop['classs'], @@ -158,7 +166,7 @@ if (!defined('AOWOW_REVISION')) continue; } - $description = $spl->parseText(); + $description = $glyphSpells->parseText(); $spellFamily = $class2Family[$pop['classs']]; $classId = $pop['classs'] - 1; $skill = 0; @@ -181,11 +189,11 @@ if (!defined('AOWOW_REVISION')) while (empty($icons) && $i < 3) { $i++; - $m1 = $spl->template['effect1SpellClassMask'.$l[$i]]; - $m2 = $spl->template['effect2SpellClassMask'.$l[$i]]; - $m3 = $spl->template['effect3SpellClassMask'.$l[$i]]; + $m1 = $glyphSpells->getField('effect1SpellClassMask'.$l[$i]); + $m2 = $glyphSpells->getField('effect2SpellClassMask'.$l[$i]); + $m3 = $glyphSpells->getField('effect3SpellClassMask'.$l[$i]); - if ($spl->template['effect'.$i.'Id'] != 6 || (!$m1 && !$m2 && !$m3)) + if ($glyphSpells->getField('effect'.$i.'Id') != 6 || (!$m1 && !$m2 && !$m3)) continue; $where = "SpellFamilyId = ?d AND ((SpellFamilyFlags3 & 0xFFFFFFFF) & ?d OR (SpellFamilyFlags2 & 0xFFFFFFFF) & ?d OR (SpellFamilyFlags1 & 0xFFFFFFFF) & ?d)"; diff --git a/setup/tools/dataset-assembler/itemsets.php b/setup/tools/dataset-assembler/itemsets.php index 777b12dd..08db7379 100644 --- a/setup/tools/dataset-assembler/itemsets.php +++ b/setup/tools/dataset-assembler/itemsets.php @@ -113,7 +113,7 @@ if (!defined('AOWOW_REVISION')) // costy and locale-independant -> cache if (!isset($jsonBonus[$set['spell'.$i]])) { - $bSpell = new Spell($set['spell'.$i]); + $bSpell = new SpellList(array(['Id', $set['spell'.$i]])); $jsonBonus[$set['spell'.$i]] = $bSpell->getStatGain(); } diff --git a/setup/tools/dataset-assembler/talents.php b/setup/tools/dataset-assembler/talents.php index 53cac8f3..7d151fd3 100644 --- a/setup/tools/dataset-assembler/talents.php +++ b/setup/tools/dataset-assembler/talents.php @@ -114,12 +114,12 @@ if (!defined('AOWOW_REVISION')) for ($k = 0; $k <= ($m - 1); $k++) { - $tSpell = new Spell($talents[$j]['rank'.($k + 1)]); + $tSpell = new SpellList(array(['Id', $talents[$j]['rank'.($k + 1)]])); $d[] = $tSpell->parseText(); $s[] = $talents[$j]['rank'.($k + 1)]; if ($talents[$j]['isSpell']) - $t[] = $tSpell->getTalentHead(); + $t[] = $tSpell->getTalentHeadForCurrent(); } if ($talents[$j]['dependsOn']) diff --git a/template/titles.tpl b/template/titles.tpl index 1dbf4bf2..46563720 100644 --- a/template/titles.tpl +++ b/template/titles.tpl @@ -14,7 +14,7 @@