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 @@