From d2e109d81834b0d4591e26ea670582dd1d5001c8 Mon Sep 17 00:00:00 2001 From: Sarjuuk Date: Thu, 15 Aug 2024 03:49:04 +0200 Subject: [PATCH] SpellDetailPage * attempted cleanup in effect generation and template * display summon properties * display unit of effect value * fix spell effect layout, typos, missing tools, ... --- includes/kernel.php | 2 +- includes/types/spell.class.php | 62 +- localization/lang.class.php | 7 +- localization/locale_dede.php | 13 +- localization/locale_enus.php | 11 +- localization/locale_eses.php | 11 +- localization/locale_frfr.php | 11 +- localization/locale_ruru.php | 11 +- localization/locale_zhcn.php | 11 +- pages/genericPage.class.php | 42 +- pages/spell.php | 1094 ++++++++++---------- setup/db_structure.sql | 2 +- setup/tools/clisetup/setup.us.php | 2 +- setup/tools/dbc/12340.ini | 8 + setup/tools/sqlgen/summonproperties.ss.php | 18 + setup/updates/1724095916_01.sql | 1 + template/pages/spell.tpl.php | 132 +-- 17 files changed, 767 insertions(+), 671 deletions(-) create mode 100644 setup/tools/sqlgen/summonproperties.ss.php create mode 100644 setup/updates/1724095916_01.sql diff --git a/includes/kernel.php b/includes/kernel.php index 4a79a6cc..ad463e3f 100644 --- a/includes/kernel.php +++ b/includes/kernel.php @@ -3,7 +3,7 @@ mb_internal_encoding('UTF-8'); mysqli_report(MYSQLI_REPORT_ERROR); -define('AOWOW_REVISION', 38); +define('AOWOW_REVISION', 39); define('OS_WIN', substr(PHP_OS, 0, 3) == 'WIN'); // OS_WIN as per compile info of php define('CLI', PHP_SAPI === 'cli'); define('CLI_HAS_E', CLI && // WIN10 and later usually support ANSI escape sequences diff --git a/includes/types/spell.class.php b/includes/types/spell.class.php index a95ef44c..53892951 100644 --- a/includes/types/spell.class.php +++ b/includes/types/spell.class.php @@ -187,8 +187,10 @@ class SpellList extends BaseType // use if you JUST need the name public static function getName($id) { - $n = DB::Aowow()->SelectRow('SELECT name_loc0, name_loc2, name_loc3, name_loc4, name_loc6, name_loc8 FROM ?_spell WHERE id = ?d', $id ); - return Util::localizedString($n, 'name'); + if ($n = DB::Aowow()->SelectRow('SELECT name_loc0, name_loc2, name_loc3, name_loc4, name_loc6, name_loc8 FROM ?_spell WHERE id = ?d', $id)) + return Util::localizedString($n, 'name'); + + return ''; } // end static use @@ -484,9 +486,10 @@ class SpellList extends BaseType return $this->tools; } - public function getModelInfo($spellId = 0, $effIdx = 0) + public function getModelInfo(int $spellId = 0, int $effIdx = 0) : array { - $displays = [0 => []]; + $displays = $results = []; + foreach ($this->iterate() as $id => $__) { if ($spellId && $spellId != $id) @@ -494,6 +497,9 @@ class SpellList extends BaseType for ($i = 1; $i < 4; $i++) { + if ($spellId && $effIdx && $effIdx != $i) + continue; + $effMV = $this->curTpl['effect'.$i.'MiscValue']; if (!$effMV) continue; @@ -524,16 +530,16 @@ class SpellList extends BaseType 2289 => [2289, 29415, 29418, 29419, 29420, 29421] // Bear - Tauren ); - if ($st = DB::Aowow()->selectRow('SELECT *, displayIdA as model1, displayIdH as model2 FROM ?_shapeshiftforms WHERE id = ?d', $effMV)) + if ($st = DB::Aowow()->selectRow('SELECT *, `displayIdA` AS `model1`, `displayIdH` AS `model2` FROM ?_shapeshiftforms WHERE `id` = ?d', $effMV)) { foreach ([1, 2] as $j) if (isset($subForms[$st['model'.$j]])) $st['model'.$j] = $subForms[$st['model'.$j]][array_rand($subForms[$st['model'.$j]])]; - $displays[0][$id][$i] = array( - 'typeId' => 0, - 'displayId' => $st['model2'] ? $st['model'.rand(1, 2)] : $st['model1'], + $results[$id][$i] = array( + 'type' => Type::NPC, 'creatureType' => $st['creatureType'], + 'displayId' => $st['model2'] ? $st['model'.rand(1, 2)] : $st['model1'], 'displayName' => Lang::game('st', $effMV) ); } @@ -541,8 +547,6 @@ class SpellList extends BaseType } } - $results = $displays[0]; - if (!empty($displays[Type::NPC])) { $nModels = new CreatureList(array(['id', array_column($displays[Type::NPC], 1)])); @@ -555,6 +559,7 @@ class SpellList extends BaseType foreach ($indizes as $idx) { $res = array( + 'type' => Type::NPC, 'typeId' => $nId, 'displayId' => $nModels->getRandomModelId(), 'displayName' => $nModels->getField('name', true) @@ -582,6 +587,7 @@ class SpellList extends BaseType foreach ($indizes as $idx) { $results[$srcId][$idx] = array( + 'type' => Type::OBJECT, 'typeId' => $oId, 'displayId' => $oModels->getField('displayId'), 'displayName' => $oModels->getField('name', true) @@ -593,12 +599,15 @@ class SpellList extends BaseType } if ($spellId && $effIdx) - return !empty($results[$spellId][$effIdx]) ? $results[$spellId][$effIdx] : 0; + return $results[$spellId][$effIdx] ?? []; + + if ($spellId) + return $results[$spellId] ?? []; return $results; } - private function createRangesForCurrent() + private function createRangesForCurrent() : string { if (!$this->curTpl['rangeMaxHostile']) return ''; @@ -620,7 +629,7 @@ class SpellList extends BaseType return sprintf(Lang::spell('range'), $this->curTpl['rangeMaxHostile']); } - public function createPowerCostForCurrent() + public function createPowerCostForCurrent() : string { $str = ''; @@ -664,7 +673,7 @@ class SpellList extends BaseType return $str; } - public function createCastTimeForCurrent($short = true, $noInstant = true) + public function createCastTimeForCurrent(bool $short = true, bool $noInstant = true) : string { if (!$this->curTpl['castTime'] && $this->isChanneledSpell()) return Lang::spell('channeled'); @@ -678,7 +687,7 @@ class SpellList extends BaseType return $short ? Lang::formatTime($this->curTpl['castTime'] * 1000, 'spell', 'castTime') : Util::formatTime($this->curTpl['castTime'] * 1000); } - private function createCooldownForCurrent() + private function createCooldownForCurrent() : string { if ($this->curTpl['recoveryTime']) return Lang::formatTime($this->curTpl['recoveryTime'], 'spell', 'cooldown'); @@ -689,16 +698,15 @@ class SpellList extends BaseType } // formulae base from TC - private function calculateAmountForCurrent(int $effIdx, ?SpellList $altTpl = null, int $nTicks = 1) : array + private function calculateAmountForCurrent(int $effIdx, int $nTicks = 1) : array { - $ref = $altTpl ?: $this; $level = $this->charLevel; $maxBase = 0; - $rppl = $ref->getField('effect'.$effIdx.'RealPointsPerLevel'); - $base = $ref->getField('effect'.$effIdx.'BasePoints'); - $add = $ref->getField('effect'.$effIdx.'DieSides'); - $maxLvl = $ref->getField('maxLevel'); - $baseLvl = $ref->getField('baseLevel'); + $rppl = $this->getField('effect'.$effIdx.'RealPointsPerLevel'); + $base = $this->getField('effect'.$effIdx.'BasePoints'); + $add = $this->getField('effect'.$effIdx.'DieSides'); + $maxLvl = $this->getField('maxLevel'); + $baseLvl = $this->getField('baseLevel'); if ($rppl) { @@ -707,8 +715,8 @@ class SpellList extends BaseType else if ($level < $baseLvl) $level = $baseLvl; - if (!$ref->getField('atributes0') & SPELL_ATTR0_PASSIVE) - $level -= $ref->getField('spellLevel'); + if (!$this->getField('atributes0') & SPELL_ATTR0_PASSIVE) + $level -= $this->getField('spellLevel'); $maxBase += (int)(($level - $baseLvl) * $rppl); $maxBase *= $nTicks; @@ -1060,7 +1068,7 @@ class SpellList extends BaseType break; case 'm': // BasePoints (minValue) case 'M': // BasePoints (maxValue) - [$min, $max, $modStrMin, $modStrMax] = $this->calculateAmountForCurrent($effIdx, $srcSpell); + [$min, $max, $modStrMin, $modStrMax] = $srcSpell->calculateAmountForCurrent($effIdx); $mv = $srcSpell->getField('effect'.$effIdx.'MiscValue'); $aura = $srcSpell->getField('effect'.$effIdx.'AuraId'); @@ -1116,7 +1124,7 @@ class SpellList extends BaseType $periode = 3000; } - [$min, $max, $modStrMin, $modStrMax] = $this->calculateAmountForCurrent($effIdx, $srcSpell, intVal($duration / $periode)); + [$min, $max, $modStrMin, $modStrMax] = $srcSpell->calculateAmountForCurrent($effIdx, intVal($duration / $periode)); if (in_array($op, $signs) && is_numeric($oparg)) { @@ -1155,7 +1163,7 @@ class SpellList extends BaseType break; case 's': // BasePoints (with variance) case 'S': - [$min, $max, $modStrMin, $modStrMax] = $this->calculateAmountForCurrent($effIdx, $srcSpell); + [$min, $max, $modStrMin, $modStrMax] = $srcSpell->calculateAmountForCurrent($effIdx); $mv = $srcSpell->getField('effect'.$effIdx.'MiscValue'); $aura = $srcSpell->getField('effect'.$effIdx.'AuraId'); diff --git a/localization/lang.class.php b/localization/lang.class.php index 8fa9cd50..12d8c820 100644 --- a/localization/lang.class.php +++ b/localization/lang.class.php @@ -399,12 +399,17 @@ class Lang return implode(', ', $tmp); } - public static function getMagicSchools(int $schoolMask) : string + public static function getMagicSchools(int $schoolMask, bool $short = false) : string { $schoolMask &= SPELL_ALL_SCHOOLS; // clamp to available schools.. $tmp = []; $i = 0; + if ($short && $schoolMask == SPELL_ALL_SCHOOLS) + return self::main('all'); + if ($short && $schoolMask == SPELL_MAGIC_SCHOOLS) + return self::main('all').' ('.self::game('dt', 1).')'; + while ($schoolMask) { if ($schoolMask & (1 << $i)) diff --git a/localization/locale_dede.php b/localization/locale_dede.php index b423c368..ae1251b5 100644 --- a/localization/locale_dede.php +++ b/localization/locale_dede.php @@ -57,6 +57,8 @@ $lang = array( 'status' => "Status", 'yes' => "Ja", 'no' => "Nein", + 'any' => "Beliebig", + 'all' => "Alle", // filter 'extSearch' => "Erweiterte Suche", @@ -1577,7 +1579,7 @@ $lang = array( ), 'spellModOp' => array( "Schaden", "Dauer", "Bedrohung", "Effekt 1", "Aufladungen", - "Reichweite", "Radius", "kritische Trefferchance", "Alle Effekte", "Zauberzeitverlust", + "Reichweite", "Radius", "Kritische Trefferchance", "Alle Effekte", "Zauberzeitverlust", "Zauberzeit", "Abklingzeit", "Effekt 2", "Ignoriere Rüstung", "Kosten", "Kritischer Bonusschaden", "Trefferchance", "Sprung-Ziele", "Chance auf Auslösung", "Intervall", "Multiplikator (Schaden)", "Globale Abklingzeit", "Schaden über Zeit", "Effekt 3", "Multiplikator (Bonus)", @@ -1591,6 +1593,9 @@ $lang = array( "erhaltene kritische Fernkampftreffer", "erhaltene kritische Zaubertreffer", "Nahkampftempo", "Fernkampftempo", "Zaubertempo", "Waffenfertigkeit Haupthand", "Waffenfertigkeit Nebenhand", "Waffenfertigkeit Fernkampf", "Waffenkunde", "Rüstungsdurchschlag" ), + 'combatRatingMask' => array( + 0xE0 => "Trefferchance", 0x700 => "Kritische Trefferchance", 0x1C000 => "Abhärtung" + ), 'lockType' => array( null, "Schlossknacken", "Kräuterkunde", "Bergbau", "Falle entschärfen", "Öffnen", "Schatz (DND)", "Verkalkte Elfenedelsteine (DND)", "Schließen", "Falle scharf machen", @@ -1659,6 +1664,8 @@ $lang = array( 89 => "Verwendbar, während Ihr verängstigt seid", 65 => "Braucht alle Ressourcen auf" ), + 'summonControl' => ["Ungesteuert", "Wächter", "Begleiter", "Bezaubert", "Gesteuertes Fahrzeug", "Ungesteuertes Fahrzeug"], + 'summonSlot' => ["Begleiter", "Feuertotem", "Erdtotem", "Wassertotem", "Lufttotem", "Haustier", "Quest"], 'unkEffect' => 'Unknown Effect (%1$d)', 'effects' => array( /*0-5 */ 'None', 'Instakill', 'School Damage', 'Dummy', 'Portal Teleport', 'Teleport Units', @@ -1683,11 +1690,11 @@ $lang = array( /*114+ */ 'Taunt', 'Durability Damage - %', 'Skin Player Corpse (PvP)', 'AoE Resurrect with % Health','Learn Skill', 'Apply Area Aura - Pet', /*120+ */ 'Teleport to Graveyard', 'Normalized Weapon Damage', null, 'Take Flight Path', 'Pull Towards', 'Modify Threat - %', /*126+ */ 'Spell Steal ', 'Prospect', 'Apply Area Aura - Friend', 'Apply Area Aura - Enemy', 'Redirect Done Threat %', 'Play Sound', -/*132+ */ 'Play Music', 'Unlearn Specialization', 'Kill Credit2', 'Call Pet', 'Heal for % of Total Health','Give % of Total Power', +/*132+ */ 'Play Music', 'Unlearn Specialization', 'Kill Credit 2', 'Call Pet', 'Heal for % of Total Health','Give % of Total Power', /*138+ */ 'Leap Back', 'Abandon Quest', 'Force Cast', 'Force Spell Cast with Value','Trigger Spell with Value','Apply Area Aura - Pet Owner', /*144+ */ 'Knockback to Dest.', 'Pull Towards Dest.', 'Activate Rune', 'Fail Quest', null, 'Charge to Dest', /*150+ */ 'Start Quest', 'Trigger Spell 2', 'Summon - Refer-A-Friend', 'Create Tamed Pet', 'Discover Flight Path', 'Dual Wield 2H Weapons', -/*156+ */ 'Add Socket to Item', 'Create Tradeskill Item', 'Milling', 'Rename Pet', null, 'Change Talent Spec. Count', +/*156+ */ 'Add Socket to Item', 'Create Tradeskill Item', 'Milling', 'Rename Pet', 'Force Cast 2', 'Change Talent Spec. Count', /*162-167*/ 'Activate Talent Spec.', null, 'Remove Aura', null, null, 'Update Player Phase' ), 'unkAura' => 'Unknown Aura (%1$d)', diff --git a/localization/locale_enus.php b/localization/locale_enus.php index 3d65fd29..41824f6b 100644 --- a/localization/locale_enus.php +++ b/localization/locale_enus.php @@ -58,6 +58,8 @@ $lang = array( 'status' => "Status", 'yes' => "Yes", 'no' => "No", + 'any' => "Any", + 'all' => "All", // filter 'extSearch' => "Extended search", @@ -1592,6 +1594,9 @@ $lang = array( "Taken Critical Ranged Hit Chance", "Taken Critical Spell Hit Chance", "Melee Haste", "Ranged Haste", "Spell Haste", "Mainhand Weapon Skill", "Offhand Weapon Skill", "Ranged Weapon Skill", "Expertise", "Armor Penetration" ), + 'combatRatingMask' => array( + 0xE0 => "Hit Chance", 0x700 => "Critical Hit Chance", 0x1C000 => "Resilience" + ), 'lockType' => array( // lockType.dbc null, "Lockpicking", "Herbalism", "Mining", "Disarm Trap", "Open", "Treasure (DND)", "Calcified Elven Gems (DND)", "Close", "Arm Trap", @@ -1660,6 +1665,8 @@ $lang = array( 89 => "Usable while feared", 65 => "Uses all power" ), + 'summonControl' => ["Uncontrolled", "Guardian", "Pet", "Possessed", "Possessed Vehicle", "Uncontrolled Vehicle"], + 'summonSlot' => ["Pet", "Fire Totem", "Earth Totem", "Water Totem", "Air Totem", "Non-combat Pet", "Quest"], 'unkEffect' => 'Unknown Effect (%1$d)', 'effects' => array( /*0-5 */ 'None', 'Instakill', 'School Damage', 'Dummy', 'Portal Teleport', 'Teleport Units', @@ -1684,11 +1691,11 @@ $lang = array( /*114+ */ 'Taunt', 'Durability Damage - %', 'Skin Player Corpse (PvP)', 'AoE Resurrect with % Health','Learn Skill', 'Apply Area Aura - Pet', /*120+ */ 'Teleport to Graveyard', 'Normalized Weapon Damage', null, 'Take Flight Path', 'Pull Towards', 'Modify Threat - %', /*126+ */ 'Spell Steal ', 'Prospect', 'Apply Area Aura - Friend', 'Apply Area Aura - Enemy', 'Redirect Done Threat %', 'Play Sound', -/*132+ */ 'Play Music', 'Unlearn Specialization', 'Kill Credit2', 'Call Pet', 'Heal for % of Total Health','Give % of Total Power', +/*132+ */ 'Play Music', 'Unlearn Specialization', 'Kill Credit 2', 'Call Pet', 'Heal for % of Total Health','Give % of Total Power', /*138+ */ 'Leap Back', 'Abandon Quest', 'Force Cast', 'Force Spell Cast with Value','Trigger Spell with Value','Apply Area Aura - Pet Owner', /*144+ */ 'Knockback to Dest.', 'Pull Towards Dest.', 'Activate Rune', 'Fail Quest', null, 'Charge to Dest', /*150+ */ 'Start Quest', 'Trigger Spell 2', 'Summon - Refer-A-Friend', 'Create Tamed Pet', 'Discover Flight Path', 'Dual Wield 2H Weapons', -/*156+ */ 'Add Socket to Item', 'Create Tradeskill Item', 'Milling', 'Rename Pet', null, 'Change Talent Spec. Count', +/*156+ */ 'Add Socket to Item', 'Create Tradeskill Item', 'Milling', 'Rename Pet', 'Force Cast 2', 'Change Talent Spec. Count', /*162-167*/ 'Activate Talent Spec.', null, 'Remove Aura', null, null, 'Update Player Phase' ), 'unkAura' => 'Unknown Aura (%1$d)', diff --git a/localization/locale_eses.php b/localization/locale_eses.php index f62be1db..a34e44e2 100644 --- a/localization/locale_eses.php +++ b/localization/locale_eses.php @@ -57,6 +57,8 @@ $lang = array( 'status' => "Estado", 'yes' => "Sí", 'no' => "No", + 'any' => "Cualquiera", + 'all' => "Todo", // filter 'extSearch' => "Extender búsqueda", @@ -1591,6 +1593,9 @@ $lang = array( "CRIT_TAKEN_RANGED", "CRIT_TAKEN_SPELL", "HASTE_MELEE", "HASTE_RANGED", "HASTE_SPELL", "WEAPON_SKILL_MAINHAND", "WEAPON_SKILL_OFFHAND", "WEAPON_SKILL_RANGED", "EXPERTISE", "ARMOR_PENETRATION" ), + 'combatRatingMask' => array( + 0xE0 => "[Hit Chance]", 0x700 => "[Critical Hit Chance]", 0x1C000 => "Temple" + ), 'lockType' => array( null, "Forzar cerradura", "Herboristería", "Minería", "Desactivar trampa", "Abrir", "Tesoro (DND)", "Gemas cálcicas elfas (DND)", "Cerrar", "Activar trampa", @@ -1659,6 +1664,8 @@ $lang = array( 89 => "Utilizable mientras se esta aterrorizado", 65 => "Utiliza todo el poder" ), + 'summonControl' => ["[Uncontrolled]", "Guardián", "Mascota", "Embelesado", "[Possessed Vehicle]", "[Uncontrolled Vehicle]"], + 'summonSlot' => ["Mascota", "Tótem de Fuego", "Tótem de Tierra", "Tótem de Agua", "Tótem de Aire", "Mascota mansa", "Misión"], 'unkEffect' => 'Unknown Effect (%1$d)', 'effects' => array( /*0-5 */ 'None', 'Instakill', 'School Damage', 'Dummy', 'Portal Teleport', 'Teleport Units', @@ -1683,11 +1690,11 @@ $lang = array( /*114+ */ 'Taunt', 'Durability Damage - %', 'Skin Player Corpse (PvP)', 'AoE Resurrect with % Health','Learn Skill', 'Apply Area Aura - Pet', /*120+ */ 'Teleport to Graveyard', 'Normalized Weapon Damage', null, 'Take Flight Path', 'Pull Towards', 'Modify Threat - %', /*126+ */ 'Spell Steal ', 'Prospect', 'Apply Area Aura - Friend', 'Apply Area Aura - Enemy', 'Redirect Done Threat %', 'Play Sound', -/*132+ */ 'Play Music', 'Unlearn Specialization', 'Kill Credit2', 'Call Pet', 'Heal for % of Total Health','Give % of Total Power', +/*132+ */ 'Play Music', 'Unlearn Specialization', 'Kill Credit 2', 'Call Pet', 'Heal for % of Total Health','Give % of Total Power', /*138+ */ 'Leap Back', 'Abandon Quest', 'Force Cast', 'Force Spell Cast with Value','Trigger Spell with Value','Apply Area Aura - Pet Owner', /*144+ */ 'Knockback to Dest.', 'Pull Towards Dest.', 'Activate Rune', 'Fail Quest', null, 'Charge to Dest', /*150+ */ 'Start Quest', 'Trigger Spell 2', 'Summon - Refer-A-Friend', 'Create Tamed Pet', 'Discover Flight Path', 'Dual Wield 2H Weapons', -/*156+ */ 'Add Socket to Item', 'Create Tradeskill Item', 'Milling', 'Rename Pet', null, 'Change Talent Spec. Count', +/*156+ */ 'Add Socket to Item', 'Create Tradeskill Item', 'Milling', 'Rename Pet', 'Force Cast 2', 'Change Talent Spec. Count', /*162-167*/ 'Activate Talent Spec.', null, 'Remove Aura', null, null, 'Update Player Phase' ), 'unkAura' => 'Unknown Aura (%1$d)', diff --git a/localization/locale_frfr.php b/localization/locale_frfr.php index 2be2a31f..9f52e1e6 100644 --- a/localization/locale_frfr.php +++ b/localization/locale_frfr.php @@ -57,6 +57,8 @@ $lang = array( 'status' => "Statut", 'yes' => "Oui", 'no' => "Non", + 'any' => "N'importe quelle", + 'all' => "Tous", // filter 'extSearch' => "Recherche avancée", @@ -1591,6 +1593,9 @@ $lang = array( "CRIT_TAKEN_RANGED", "CRIT_TAKEN_SPELL", "HASTE_MELEE", "HASTE_RANGED", "HASTE_SPELL", "WEAPON_SKILL_MAINHAND", "WEAPON_SKILL_OFFHAND", "WEAPON_SKILL_RANGED", "EXPERTISE", "ARMOR_PENETRATION" ), + 'combatRatingMask' => array( + 0xE0 => "[Hit Chance]", 0x700 => "[Critical Hit Chance]", 0x1C000 => "Résilience JcJ" + ), 'lockType' => array( null, "Crochetage", "Herboristerie", "Minage", "Désarmement de piège", "Ouverture", "Trésor (DND)", "Gemmes elfiques calcifiées (DND)", "Fermeture", "Pose de piège", @@ -1659,6 +1664,8 @@ $lang = array( 89 => "Utilisable sous l'effet de peur", 65 => "Utilise toute la puissance" ), + 'summonControl' => ["[Uncontrolled]", "Gardiens", "Familier", "Charmé", "[Possessed Vehicle]", "[Uncontrolled Vehicle]"], + 'summonSlot' => ["Familier", "Totem de Feu", "Totem de Terre", "Totem d'Eau", "Totem d'Air", "Familier pacifique", "Quête"], 'unkEffect' => 'Unknown Effect (%1$d)', 'effects' => array( /*0-5 */ 'None', 'Instakill', 'School Damage', 'Dummy', 'Portal Teleport', 'Teleport Units', @@ -1683,11 +1690,11 @@ $lang = array( /*114+ */ 'Taunt', 'Durability Damage - %', 'Skin Player Corpse (PvP)', 'AoE Resurrect with % Health','Learn Skill', 'Apply Area Aura - Pet', /*120+ */ 'Teleport to Graveyard', 'Normalized Weapon Damage', null, 'Take Flight Path', 'Pull Towards', 'Modify Threat - %', /*126+ */ 'Spell Steal ', 'Prospect', 'Apply Area Aura - Friend', 'Apply Area Aura - Enemy', 'Redirect Done Threat %', 'Play Sound', -/*132+ */ 'Play Music', 'Unlearn Specialization', 'Kill Credit2', 'Call Pet', 'Heal for % of Total Health','Give % of Total Power', +/*132+ */ 'Play Music', 'Unlearn Specialization', 'Kill Credit 2', 'Call Pet', 'Heal for % of Total Health','Give % of Total Power', /*138+ */ 'Leap Back', 'Abandon Quest', 'Force Cast', 'Force Spell Cast with Value','Trigger Spell with Value','Apply Area Aura - Pet Owner', /*144+ */ 'Knockback to Dest.', 'Pull Towards Dest.', 'Activate Rune', 'Fail Quest', null, 'Charge to Dest', /*150+ */ 'Start Quest', 'Trigger Spell 2', 'Summon - Refer-A-Friend', 'Create Tamed Pet', 'Discover Flight Path', 'Dual Wield 2H Weapons', -/*156+ */ 'Add Socket to Item', 'Create Tradeskill Item', 'Milling', 'Rename Pet', null, 'Change Talent Spec. Count', +/*156+ */ 'Add Socket to Item', 'Create Tradeskill Item', 'Milling', 'Rename Pet', 'Force Cast 2', 'Change Talent Spec. Count', /*162-167*/ 'Activate Talent Spec.', null, 'Remove Aura', null, null, 'Update Player Phase' ), 'unkAura' => 'Unknown Aura (%1$d)', diff --git a/localization/locale_ruru.php b/localization/locale_ruru.php index 677b43ef..ad989cc3 100644 --- a/localization/locale_ruru.php +++ b/localization/locale_ruru.php @@ -57,6 +57,8 @@ $lang = array( 'status' => "Статус", 'yes' => "Да", 'no' => "Нет", + 'any' => "Любой", // Any[one] of X => "Любой из" + 'all' => "Все", // filter 'extSearch' => "Расширенный поиск", @@ -1591,6 +1593,9 @@ $lang = array( "CRIT_TAKEN_RANGED", "CRIT_TAKEN_SPELL", "HASTE_MELEE", "HASTE_RANGED", "HASTE_SPELL", "WEAPON_SKILL_MAINHAND", "WEAPON_SKILL_OFFHAND", "WEAPON_SKILL_RANGED", "EXPERTISE", "ARMOR_PENETRATION" ), + 'combatRatingMask' => array( + 0xE0 => "[Hit Chance]", 0x700 => "[Critical Hit Chance]", 0x1C000 => "Устойчивость" + ), 'lockType' => array( null, "Взлом замков", "Травничество", "Горное дело", "Обезвреживание ловушки", "Открытие", "Клад (DND)", "Эльфийские самоцветы (DND)", "Закрытие", "Установка", @@ -1659,6 +1664,8 @@ $lang = array( 89 => "usablefearedМожет быть использовано, пока наложен Страх", 65 => "Использует ресурс полностью" ), + 'summonControl' => ['[Uncontrolled]', "Стражи", "Питомец", "Подчинённый", '[Possessed Vehicle]', '[Uncontrolled Vehicle]'], + 'summonSlot' => ["Питомец", "Тотем огня", "Тотем земли", "Тотем воды", "Тотем воздуха", "Спутник", "Задание"], 'unkEffect' => 'Unknown Effect (%1$d)', 'effects' => array( /*0-5 */ 'None', 'Instakill', 'School Damage', 'Dummy', 'Portal Teleport', 'Teleport Units', @@ -1683,11 +1690,11 @@ $lang = array( /*114+ */ 'Taunt', 'Durability Damage - %', 'Skin Player Corpse (PvP)', 'AoE Resurrect with % Health','Learn Skill', 'Apply Area Aura - Pet', /*120+ */ 'Teleport to Graveyard', 'Normalized Weapon Damage', null, 'Take Flight Path', 'Pull Towards', 'Modify Threat - %', /*126+ */ 'Spell Steal ', 'Prospect', 'Apply Area Aura - Friend', 'Apply Area Aura - Enemy', 'Redirect Done Threat %', 'Play Sound', -/*132+ */ 'Play Music', 'Unlearn Specialization', 'Kill Credit2', 'Call Pet', 'Heal for % of Total Health','Give % of Total Power', +/*132+ */ 'Play Music', 'Unlearn Specialization', 'Kill Credit 2', 'Call Pet', 'Heal for % of Total Health','Give % of Total Power', /*138+ */ 'Leap Back', 'Abandon Quest', 'Force Cast', 'Force Spell Cast with Value','Trigger Spell with Value','Apply Area Aura - Pet Owner', /*144+ */ 'Knockback to Dest.', 'Pull Towards Dest.', 'Activate Rune', 'Fail Quest', null, 'Charge to Dest', /*150+ */ 'Start Quest', 'Trigger Spell 2', 'Summon - Refer-A-Friend', 'Create Tamed Pet', 'Discover Flight Path', 'Dual Wield 2H Weapons', -/*156+ */ 'Add Socket to Item', 'Create Tradeskill Item', 'Milling', 'Rename Pet', null, 'Change Talent Spec. Count', +/*156+ */ 'Add Socket to Item', 'Create Tradeskill Item', 'Milling', 'Rename Pet', 'Force Cast 2', 'Change Talent Spec. Count', /*162-167*/ 'Activate Talent Spec.', null, 'Remove Aura', null, null, 'Update Player Phase' ), 'unkAura' => 'Unknown Aura (%1$d)', diff --git a/localization/locale_zhcn.php b/localization/locale_zhcn.php index e2090627..fdbc95bb 100644 --- a/localization/locale_zhcn.php +++ b/localization/locale_zhcn.php @@ -58,6 +58,8 @@ $lang = array( 'status' => "状态", 'yes' => "是", 'no' => "无", + 'any' => "任意", + 'all' => "全部", // filter 'extSearch' => "扩展搜索", @@ -1591,6 +1593,9 @@ $lang = array( "受到远程暴击几率", "受到法术暴击几率", "急速(近战)", "急速(远程)", "急速(法术)", "主手武器技能", "副手武器技能", "远程武器技能", "精准", "护甲穿透" ), + 'combatRatingMask' => array( + 0xE0 => "[Hit Chance]", 0x700 => "[Critical Hit Chance]", 0x1C000 => "韧性" + ), 'lockType' => array( null, "锁上的物品", "药草", "矿点", "陷阱", "未锁上的物品", "宝物", "钙化精灵宝石", "未锁上的物品", "陷阱", @@ -1659,6 +1664,8 @@ $lang = array( 89 => "恐惧时可用", 65 => "消耗所有力量" ), + 'summonControl' => ['[Uncontrolled]', "守护者", "宠物", "被魅惑", '[Possessed Vehicle]', '[Uncontrolled Vehicle]'], + 'summonSlot' => ["宠物", "火焰图腾", "大地图腾", "水图腾", "空气图腾", "非战斗宠物", "任务"], 'unkEffect' => '未知效果 (%1$d)', 'effects' => array( /*0-5 */ '无', '杀死', '类型伤害', 'Dummy', '传送门', '传送单位', @@ -1683,11 +1690,11 @@ $lang = array( /*114+ */ 'Taunt', 'Durability Damage - %', 'Skin Player Corpse (PvP)', 'AoE Resurrect with % Health','Learn Skill', 'Apply Area Aura - Pet', /*120+ */ 'Teleport to Graveyard', 'Normalized Weapon Damage', null, 'Take Flight Path', 'Pull Towards', 'Modify Threat - %', /*126+ */ 'Spell Steal ', 'Prospect', 'Apply Area Aura - Friend', 'Apply Area Aura - Enemy', 'Redirect Done Threat %', 'Play Sound', -/*132+ */ 'Play Music', 'Unlearn Specialization', 'Kill Credit2', 'Call Pet', 'Heal for % of Total Health','Give % of Total Power', +/*132+ */ 'Play Music', 'Unlearn Specialization', 'Kill Credit 2', 'Call Pet', 'Heal for % of Total Health','Give % of Total Power', /*138+ */ 'Leap Back', 'Abandon Quest', 'Force Cast', 'Force Spell Cast with Value','Trigger Spell with Value','Apply Area Aura - Pet Owner', /*144+ */ 'Knockback to Dest.', 'Pull Towards Dest.', 'Activate Rune', 'Fail Quest', null, 'Charge to Dest', /*150+ */ 'Start Quest', 'Trigger Spell 2', 'Summon - Refer-A-Friend', 'Create Tamed Pet', 'Discover Flight Path', 'Dual Wield 2H Weapons', -/*156+ */ 'Add Socket to Item', 'Create Tradeskill Item', 'Milling', 'Rename Pet', null, 'Change Talent Spec. Count', +/*156+ */ 'Add Socket to Item', 'Create Tradeskill Item', 'Milling', 'Rename Pet', 'Force Cast 2', 'Change Talent Spec. Count', /*162-167*/ 'Activate Talent Spec.', null, 'Remove Aura', null, null, 'Update Player Phase' ), 'unkAura' => '未知光环 (%1$d)', diff --git a/pages/genericPage.class.php b/pages/genericPage.class.php index a2ab88ac..0efd8d6d 100644 --- a/pages/genericPage.class.php +++ b/pages/genericPage.class.php @@ -861,8 +861,44 @@ class GenericPage return $buff; } + protected function fmtCreateIcon(int $iconIdx, int $type, int $typeId, int $pad = 0, string $element = 'icontab-icon', int $size = 1, int $num = 0, int $qty = 0) : string + { + // $element, $iconTabIdx, [typeId, size, num, qty] + $createIconString = "\$WH.ge('%s%d').appendChild(%s.createIcon(%s));\n"; + + if ($size < 0 || $size > 3) + { + trigger_error('GenericPage::fmtCreateIcon - invalid icon size '.$size.'. Normalied to 1 [small]', E_USER_WARNING); + $size = 1; + } + + $jsg = Type::getJSGlobalString($type); + if (!$jsg) + { + trigger_error('GenericPage::fmtCreateIcon - invalid type '.$type.'. Assumed '.Type::SPELL.' [spell]', E_USER_WARNING); + $jsg = Type::getJSGlobalString(Type::SPELL); + } + + $params = [$typeId, $size]; + if ($num || $qty) + $params[] = is_numeric($num) ? $num : "'".$num."'"; + if ($qty) + $params[] = is_numeric($qty) ? $qty : "'".$qty."'"; + + // $WH.ge('icontab-icon1').appendChild(g_spells.createIcon(40120, 1, '1-4', 0)); + return str_repeat(' ', $pad) . sprintf($createIconString, $element, $iconIdx, $jsg, implode(', ', $params)); + } + + protected function fmtStaffTip(string $text, string $tip) : string + { + if (User::isInGroup(U_GROUP_EMPLOYEE)) + return sprintf(Util::$dfnString, $tip, $text); + else + return $text; + } + // load brick - public function brick(string $file, array $localVars = []) : void + protected function brick(string $file, array $localVars = []) : void { foreach ($localVars as $n => $v) $$n = $v; @@ -874,7 +910,7 @@ class GenericPage } // load listview addIns - public function lvBrick(string $file) : void + protected function lvBrick(string $file) : void { if (!$this->isSaneInclude('template/listviews/', $file)) trigger_error('Nonexistant Listview addin requested: template/listviews/'.$file.'.tpl.php', E_USER_ERROR); @@ -883,7 +919,7 @@ class GenericPage } // load brick with more text then vars - public function localizedBrick(string $file, int $loc = LOCALE_EN) : void + protected function localizedBrick(string $file, int $loc = LOCALE_EN) : void { if (!$this->isSaneInclude('template/localized/', $file.'_'.$loc)) { diff --git a/pages/spell.php b/pages/spell.php index d27e4597..264ff62b 100644 --- a/pages/spell.php +++ b/pages/spell.php @@ -16,19 +16,19 @@ class SpellPage extends GenericPage protected $tools = []; protected $effects = []; protected $attributes = []; - protected $powerCost = []; + protected $powerCost = ''; protected $castTime = []; protected $level = []; - protected $rangeName = []; - protected $range = []; - protected $gcd = []; - protected $gcdCat = null; // todo (low): nyi; find out how this works [n/a; normal; ..] - protected $school = []; - protected $dispel = []; - protected $mechanic = []; - protected $stances = []; - protected $cooldown = []; - protected $duration = []; + protected $rangeName = ''; + protected $range = ''; + protected $gcd = ''; + protected $gcdCat = ''; // todo (low): nyi; find out how this works [n/a; normal; ..] + protected $school = ''; + protected $dispel = ''; + protected $mechanic = ''; + protected $stances = ''; + protected $cooldown = ''; + protected $duration = ''; protected $type = Type::SPELL; protected $typeId = 0; @@ -160,6 +160,8 @@ class SpellPage extends GenericPage $_cat = $this->subject->getField('typeCat'); + $modelInfo = $this->subject->getModelInfo($this->typeId); + $redButtons = array( BUTTON_VIEW3D => false, BUTTON_WOWHEAD => true, @@ -172,6 +174,21 @@ class SpellPage extends GenericPage ) ); + // could have multiple models set, one per effect + foreach ($modelInfo as $mI) + { + $redButtons[BUTTON_VIEW3D] = ['type' => $mI['type'], 'displayId' => $mI['displayId']]; + + if (isset($mI['humanoid'])) + { + $redButtons[BUTTON_VIEW3D]['typeId'] = $mI['typeId']; + $redButtons[BUTTON_VIEW3D]['humanoid'] = 1; + } + + break; + } + + /***********/ /* Infobox */ /***********/ @@ -238,7 +255,7 @@ class SpellPage extends GenericPage if (!$rSpell->error) { $this->extendGlobalData($rSpell->getJSGlobals()); - $infobox[] = Lang::game('requires2').' [spell='.$rSpell->id.'][/li]'; + $infobox[] = Lang::game('requires2').' [spell='.$rSpell->id.']'; } } @@ -255,7 +272,7 @@ class SpellPage extends GenericPage // training cost if ($cost = $this->subject->getField('trainingCost')) - $infobox[] = Lang::spell('trainingCost').Lang::main('colon').'[money='.$cost.'][/li]'; + $infobox[] = Lang::spell('trainingCost').Lang::main('colon').'[money='.$cost.']'; // icon if ($_ = $this->subject->getField('iconId')) @@ -269,7 +286,17 @@ class SpellPage extends GenericPage if ($id == $this->typeId) // "Mode" seems to be multilingual acceptable $infobox[] = 'Mode'.Lang::main('colon').Lang::game('modes', $n); - $effects = $this->createEffects($infobox, $redButtons); + // Creature Type from Aura: Shapeshift + foreach ($modelInfo as $mI) + { + if (!isset($mI['creatureType'])) + continue; + + if ($mI['creatureType'] > 0) + $infobox[] = Lang::game('type').Lang::main('colon').Lang::game('ct', $mI['creatureType']); + + break; + } // spell script if (User::isInGroup(U_GROUP_STAFF)) @@ -281,7 +308,7 @@ class SpellPage extends GenericPage // append glyph symbol if available $glyphId = 0; for ($i = 1; $i < 4; $i++) - if ($this->subject->getField('effect'.$i.'Id') == 74) + if ($this->subject->getField('effect'.$i.'Id') == SPELL_EFFECT_APPLY_GLYPH) $glyphId = $this->subject->getField('effect'.$i.'MiscValue'); if ($_ = DB::Aowow()->selectCell('SELECT ic.name FROM ?_glyphproperties gp JOIN ?_icons ic ON gp.iconId = ic.id WHERE gp.spellId = ?d { OR gp.id = ?d }', $this->typeId, $glyphId ?: DBSIMPLE_SKIP)) @@ -297,7 +324,7 @@ class SpellPage extends GenericPage $this->scaling = $this->createScalingData(); $this->items = $this->createRequiredItems(); $this->tools = $this->createTools(); - $this->effects = &$effects; + $this->effects = $this->createEffects(); $this->attributes = $this->createAttributesList(); $this->powerCost = $this->subject->createPowerCostForCurrent(); $this->castTime = $this->subject->createCastTimeForCurrent(false, false); @@ -305,7 +332,7 @@ class SpellPage extends GenericPage $this->rangeName = $this->subject->getField('rangeText', true); $this->range = $this->subject->getField('rangeMaxHostile'); $this->gcd = Util::formatTime($this->subject->getField('startRecoveryTime')); - $this->school = [Util::asHex($this->subject->getField('schoolMask')), Lang::getMagicSchools($this->subject->getField('schoolMask'))]; + $this->school = $this->fmtStaffTip(Lang::getMagicSchools($this->subject->getField('schoolMask')), Util::asHex($this->subject->getField('schoolMask'))); $this->dispel = $this->subject->getField('dispelType') ? Lang::game('dt', $this->subject->getField('dispelType')) : null; $this->mechanic = $this->subject->getField('mechanic') ? Lang::game('me', $this->subject->getField('mechanic')) : null; $this->name = $this->subject->getField('name', true); @@ -1399,7 +1426,7 @@ class SpellPage extends GenericPage return $didAppendSomething; } - private function createReagentList() + private function createReagentList() : array { $reagentResult = []; $enhanced = false; @@ -1419,8 +1446,8 @@ class SpellPage extends GenericPage 'name' => $this->subject->relItems->getField('name', true), 'icon' => $this->subject->relItems->getField('iconString'), 'qty' => $reagents[$iId][1], - 'path' => Type::ITEM.'-'.$iId, // id of the html-element - 'level' => 0 // depths in array, used for indentation + 'path' => Type::ITEM.'-'.$iId, // id of the html-element + 'level' => 0 // depths in array, used for indentation ); $idx = count($reagentResult); @@ -1441,7 +1468,7 @@ class SpellPage extends GenericPage return [$enhanced, $reagentResult]; } - private function createScalingData() // calculation mostly like seen in TC + private function createScalingData() : array // calculation mostly like seen in TC { $scaling = array_merge( array( @@ -1450,7 +1477,7 @@ class SpellPage extends GenericPage 'directAP' => 0, 'dotAP' => 0 ), - (array)DB::World()->selectRow('SELECT direct_bonus AS directSP, dot_bonus AS dotSP, ap_bonus AS directAP, ap_dot_bonus AS dotAP FROM spell_bonus_data WHERE entry = ?d', $this->firstRank) + (array)DB::World()->selectRow('SELECT `direct_bonus` AS `directSP`, `dot_bonus` AS `dotSP`, `ap_bonus` AS `directAP`, `ap_dot_bonus` AS `dotAP` FROM spell_bonus_data WHERE `entry` = ?d', $this->firstRank) ); if (!$this->subject->isDamagingSpell() && !$this->subject->isHealingSpell()) @@ -1462,7 +1489,6 @@ class SpellPage extends GenericPage if ($v != -1 || !in_array($this->subject->getField('typeCat'), [-2, -3, -7, 7])) continue; - // no known calculation for physical abilities if ($k == 'directAP' || $k == 'dotAP') continue; @@ -1541,7 +1567,7 @@ class SpellPage extends GenericPage return $scaling; } - private function createRequiredItems() + private function createRequiredItems() : string { // parse itemClass & itemSubClassMask $class = $this->subject->getField('equippedItemClass'); @@ -1549,10 +1575,10 @@ class SpellPage extends GenericPage $invType = $this->subject->getField('equippedItemInventoryTypeMask'); if ($class <= 0) - return; + return ''; - $title = ['Class: '.$class, 'SubClass: '.Util::asHex($subClass)]; - $text = Lang::getRequiredItems($class, $subClass, false); + $tip = 'Class: '.$class.'
SubClass: '.Util::asHex($subClass); + $text = Lang::getRequiredItems($class, $subClass, false); if ($invType) { @@ -1575,33 +1601,25 @@ class SpellPage extends GenericPage if ($invType & 1 << $k && $str) $_[] = $str; - $title[] = Lang::item('slot').Lang::main('colon').Util::asHex($invType); - $text .= ' '.Lang::spell('_inSlot').Lang::main('colon').implode(', ', $_); + $tip .= '
'.Lang::item('slot').Lang::main('colon').Util::asHex($invType); + $text .= ' '.Lang::spell('_inSlot').Lang::main('colon').implode(', ', $_); } - return [$title, $text]; + return $this->fmtStaffTip($text, $tip); } - private function createTools() + private function createTools() : array { $tools = $this->subject->getToolsForCurrent(); // prepare Tools foreach ($tools as &$tool) - { - if (isset($tool['itemId'])) // Tool - $tool['url'] = '?item='.$tool['itemId']; - else // ToolCat - { - $tool['quality'] = ITEM_QUALITY_HEIRLOOM - ITEM_QUALITY_NORMAL; - $tool['url'] = '?items&filter=cr=91;crs='.$tool['id'].';crv=0'; - } - } + $tool['url'] = isset($tool['itemId']) ? '?item='.$tool['itemId'] : '?items&filter=cr=91;crs='.$tool['id'].';crv=0'; return $tools; } - private function createEffects(&$infobox, &$redButtons) + private function createEffects() : array { // proc data .. maybe use more information..? $procData = array( @@ -1609,23 +1627,16 @@ class SpellPage extends GenericPage 'cooldown' => 0 ); - if ($procCustom = DB::World()->selectRow('SELECT IF(ProcsPerMinute > 0, -ProcsPerMinute, Chance) AS chance, Cooldown AS cooldown FROM spell_proc WHERE ABS(SpellId) = ?d', $this->firstRank)) - foreach ($procCustom as $k => $v) - if ($v) - $procData[$k] = $v; + if ($sp = DB::World()->selectRow('SELECT IF(`ProcsPerMinute` > 0, -`ProcsPerMinute`, `Chance`) AS `chance`, `Cooldown` AS `cooldown` FROM `spell_proc` WHERE ABS(`SpellId`) = ?d', $this->firstRank)) + { + $procData['chance'] = $sp['chance'] ?: $procData['chance']; + $procData['cooldown'] = $sp['cooldown'] ?: $procData['cooldown']; + } $effects = []; $spellIdx = array_unique(array_merge($this->subject->canTriggerSpell(), $this->subject->canTeachSpell())); $itemIdx = $this->subject->canCreateItem(); - $perfItem = DB::World()->selectRow('SELECT * FROM skill_perfect_item_template WHERE spellId = ?d', $this->typeId); - - $fmtStaffTT = function($text, $tip) - { - if (User::isInGroup(U_GROUP_EMPLOYEE)) - return sprintf(Util::$dfnString, $tip, $text); - else - return $text; - }; + $perfItem = DB::World()->selectRow('SELECT `perfectItemType` AS `itemId`, `requiredSpecialization` AS `reqSpellId`, `perfectCreateChance` AS `chance` FROM skill_perfect_item_template WHERE `spellId` = ?d', $this->typeId); // Iterate through all effects: for ($i = 1; $i < 4; $i++) @@ -1633,61 +1644,73 @@ class SpellPage extends GenericPage if ($this->subject->getField('effect'.$i.'Id') <= 0) continue; - $effId = (int)$this->subject->getField('effect'.$i.'Id'); - $effMV = (int)$this->subject->getField('effect'.$i.'MiscValue'); - $effMVB = (int)$this->subject->getField('effect'.$i.'MiscValueB'); - $effBP = (int)$this->subject->getField('effect'.$i.'BasePoints'); - $effDS = (int)$this->subject->getField('effect'.$i.'DieSides'); - $effRPPL = $this->subject->getField('effect'.$i.'RealPointsPerLevel'); - $effAura = (int)$this->subject->getField('effect'.$i.'AuraId'); - $foo = &$effects[$i]; + $effId = $this->subject->getField('effect'.$i.'Id'); + $effMV = $this->subject->getField('effect'.$i.'MiscValue'); + $effMVB = $this->subject->getField('effect'.$i.'MiscValueB'); + $effBP = $this->subject->getField('effect'.$i.'BasePoints'); + $effDS = $this->subject->getField('effect'.$i.'DieSides'); + $effRPPL = $this->subject->getField('effect'.$i.'RealPointsPerLevel'); + $effAura = $this->subject->getField('effect'.$i.'AuraId'); + + /* Effect Format + * + * EffectName<: AuraName>< (effMV)>< [effMVB]> + * Value: A<, plus y per level> + * Radius: Byd + * Interval: Cms + * Mechanic: D + * Proc Chance: E% || (E procs per minute) + * Cooldown: Fs + * < formated markup > + * < iconlist > + * < icon > + */ + + $_nameEffect = $_nameAura = $_nameMV = $_nameMVB = $_markup = ''; + $_icon = $_perfItem = $_footer = []; + + $_footer['value'] = [0, 0]; + $valueFmt = '%s'; // Icons: // .. from item if (in_array($i, $itemIdx)) { - $_ = $this->subject->getField('effect'.$i.'CreateItemId'); - foreach ($this->subject->relItems->iterate() as $itemId => $__) + if ($itemId = $this->subject->getField('effect'.$i.'CreateItemId')) { - if ($itemId != $_) - continue; + $itemEntry = $this->subject->relItems->getEntry($itemId); - $foo['icon'] = array( - 'id' => $this->subject->relItems->id, - 'name' => $this->subject->relItems->getField('name', true), - 'quality' => $this->subject->relItems->getField('quality'), - 'count' => $effDS + $effBP, - 'icon' => $this->subject->relItems->getField('iconString') + $_icon = array( + 'type' => Type::ITEM, + 'typeId' => $itemId, + 'name' => $itemEntry ? $this->subject->relItems->getField('name', true) : '', + 'quality' => $itemEntry ? $this->subject->relItems->getField('quality') : '', + 'count' => ($effBP + 1) . ($effDS > 1 ? '-' . ($effBP + $effDS) : '') ); - - break; } // perfect Items - if ($perfItem && $this->subject->relItems->getEntry($perfItem['perfectItemType'])) + if ($perfItem && $this->subject->relItems->getEntry($perfItem['itemId'])) { - $cndSpell = new SpellList(array(['id', $perfItem['requiredSpecialization']])); + $cndSpell = new SpellList(array(['id', $perfItem['reqSpellId']])); if (!$cndSpell->error) { - $foo['perfItem'] = array( - 'icon' => $cndSpell->getField('iconString'), - 'quality' => $this->subject->relItems->getField('quality'), - 'cndSpellId' => $perfItem['requiredSpecialization'], - 'cndSpellName' => $cndSpell->getField('name', true), - 'chance' => $perfItem['perfectCreateChance'], - 'itemId' => $perfItem['perfectItemType'], - 'itemName' => $this->subject->relItems->getField('name', true) + $_perfItem = array( + 'spellId' => $perfItem['reqSpellId'], + 'spellName' => $cndSpell->getField('name', true), + 'itemId' => $perfItem['itemId'], + 'itemName' => $this->subject->relItems->getField('name', true), + 'quality' => $this->subject->relItems->getField('quality'), + 'icon' => $cndSpell->getField('iconString'), + 'chance' => $perfItem['chance'] ); } } - - if ($effDS > 1) - $foo['icon']['count'] = "'".($effBP + 1).'-'.$foo['icon']['count']."'"; } // .. from spell - else if (in_array($i, $spellIdx) || in_array($effId, [133, 140, 141])) + else if (in_array($i, $spellIdx) || $effId == SPELL_EFFECT_UNLEARN_SPECIALIZATION) { - if ($effId == 155) + if ($effId == SPELL_EFFECT_TITAN_GRIP) $triggeredSpell = $effMV; else $triggeredSpell = $this->subject->getField('effect'.$i.'TriggerSpell'); @@ -1696,122 +1719,112 @@ class SpellPage extends GenericPage { $trig = new SpellList(array(['s.id', (int)$triggeredSpell])); - $foo['icon'] = array( - 'id' => $triggeredSpell, - 'name' => $trig->error ? Util::ucFirst(Lang::game('spell')).' #'.$triggeredSpell : $trig->getField('name', true), - 'count' => 0 + $_icon = array( + 'type' => Type::SPELL, + 'typeId' => $triggeredSpell, + 'name' => $trig->error ? '' : $trig->getField('name', true), + 'quality' => 0, + 'count' => 0 ); $this->extendGlobalData($trig->getJSGlobals(GLOBALINFO_SELF | GLOBALINFO_RELATED)); } } - // Effect Name - if ($_ = Lang::spell('effects', $effId)) - $foo['name'] = $fmtStaffTT($_, 'Effect'.Lang::main('colon').$effId).Lang::main('colon'); - else - $foo['name'] = Lang::spell('unkEffect', [$effId]); + // small text under effect name and resolved links .. order of adding to _footer determines order of output. + + // cases where we dont want 'Value' to be displayed [min, max, staffTT] + if (!in_array($i, $itemIdx) && !in_array($effAura, [SPELL_AURA_MOD_TAUNT, SPELL_AURA_MOD_STUN, SPELL_AURA_MOD_SHAPESHIFT, SPELL_AURA_MECHANIC_IMMUNITY]) && !in_array($effId, [SPELL_EFFECT_PLAY_MUSIC]) && ($effBP + $effDS) != 0) + $_footer['value'] = [$effBP + ($effDS ? 1 : 0), $effBP + $effDS]; if ($this->subject->getField('effect'.$i.'RadiusMax') > 0) - $foo['radius'] = $this->subject->getField('effect'.$i.'RadiusMax'); + $_footer['radius'] = Lang::spell('_radius').Lang::main('colon').$this->subject->getField('effect'.$i.'RadiusMax').' '.Lang::spell('_distUnit');; - if (!in_array($i, $itemIdx)) - $foo['value'] = ($effDS && $effDS != 1 ? ($effBP + 1).Lang::game('valueDelim') : null).($effBP + $effDS); - - if ($effRPPL != 0) - $foo['value'] = (isset($foo['value']) ? $foo['value'] : '0').sprintf(Lang::spell('costPerLevel'), $effRPPL); if ($this->subject->getField('effect'.$i.'Periode') > 0) - $foo['interval'] = Util::formatTime($this->subject->getField('effect'.$i.'Periode')); + $_footer['interval'] = Lang::spell('_interval').Lang::main('colon').Util::formatTime($this->subject->getField('effect'.$i.'Periode')); if ($_ = $this->subject->getField('effect'.$i.'Mechanic')) - $foo['mechanic'] = Lang::game('me', $_); + $_footer['mechanic'] = Lang::game('mechanic').Lang::main('colon').Lang::game('me', $_); - if (in_array($i, $this->subject->canTriggerSpell()) && $procData['chance']) - $foo['procData'] = array( - $procData['chance'], - $procData['cooldown'] ? Util::formatTime($procData['cooldown'], true) : null - ); + if (in_array($i, $this->subject->canTriggerSpell()) && $procData['chance'] && $procData['chance'] < 100) + { + $_footer['proc'] = $procData['chance'] < 0 ? Lang::spell('ppm', [Lang::nf(-$procData['chance'], 1)]) : Lang::spell('procChance') . Lang::main('colon') . $procData['chance'] . '%'; + if ($procData['cooldown']) + $_footer['procCD'] = Lang::game('cooldown', [$procData['cooldown']]); + } + + // Effect Name + if ($_ = Lang::spell('effects', $effId)) + $_nameEffect = $this->fmtStaffTip($_, 'EffectId: '.$effId); + else + $_nameEffect = Lang::spell('unkEffect', [$effId]); // parse masks and indizes switch ($effId) { + case SPELL_EFFECT_ENERGIZE_PCT: + $valueFmt = '%s%%'; case SPELL_EFFECT_POWER_DRAIN: case SPELL_EFFECT_ENERGIZE: case SPELL_EFFECT_POWER_BURN: - case SPELL_EFFECT_ENERGIZE_PCT: if ($_ = Lang::spell('powerTypes', $effMV)) - $foo['name'] .= $fmtStaffTT('('.$_.')', 'MiscValue'.Lang::main('colon').$effMV); - else - $foo['name'] .= '('.$effMV.')'; + $_nameMV = $this->fmtStaffTip($_, 'MiscValue: '.$effMV); if ($effMV == POWER_RAGE || $effMV == POWER_RUNIC_POWER) - $foo['value'] = ($effDS && $effDS != 1 ? (($effBP + 1) / 10).Lang::game('valueDelim') : null).(($effBP + $effDS) / 10); - + array_walk($_footer['value'], fn(&$x) => $x /= 10); break; case SPELL_EFFECT_BIND: if ($effMV <= 0) - $foo['name'] .= $fmtStaffTT('('.Lang::spell('currentArea').')', 'MiscValue'.Lang::main('colon').$effMV); + $_nameMV = $this->fmtStaffTip(Lang::spell('currentArea'), 'MiscValue: '.$effMV); else if ($_ = ZoneList::getName($effMV)) - $foo['name'] .= '('.$_.')'; + $_nameMV = ''.$_.''; else - $foo['name'] .= Util::ucFirst(Lang::game('zone')).' #'.$effMV; + $_nameMV = Util::ucFirst(Lang::game('zone')).' #'.$effMV; break; case SPELL_EFFECT_QUEST_COMPLETE: case SPELL_EFFECT_CLEAR_QUEST: case SPELL_EFFECT_QUEST_FAIL: if ($_ = QuestList::getName($effMV)) - $foo['name'] .= '('.$_.')'; + $_nameMV = ''.$_.''; else - $foo['name'] .= Util::ucFirst(Lang::game('quest')).' #'.$effMV; + $_nameMV = Util::ucFirst(Lang::game('quest')).' #'.$effMV; break; - case SPELL_EFFECT_SUMMON: case SPELL_EFFECT_SUMMON_PET: - case SPELL_EFFECT_KILL_CREDIT: + $effMVB = 67; // TC uses hardcoded summon property 67 + // DO NOT BREAK ! + case SPELL_EFFECT_SUMMON: + if (($sp = DB::Aowow()->selectRow('SELECT `control`, `slot` FROM ?_summonproperties WHERE `id` = ?d', $effMVB))) + $_nameMVB = $this->fmtStaffTip(Lang::spell('summonControl', $sp['control']).' – '.Lang::spell('summonSlot', $sp['slot']) , 'SummonProperty: '.$effMVB); + // DO NOT BREAK ! case SPELL_EFFECT_SUMMON_DEMON: + case SPELL_EFFECT_KILL_CREDIT: case SPELL_EFFECT_KILL_CREDIT2: - if ($summon = $this->subject->getModelInfo($this->typeId, $i)) - $redButtons[BUTTON_VIEW3D] = ['type' => Type::NPC, 'displayId' => $summon['displayId']]; - - $_ = Lang::game('npc').' #'.$effMV; - if ($n = CreatureList::getName($effMV)) - $_ = ' ('.$n.')'; - - $foo['name'] .= $_; + if ($_ = CreatureList::getName($effMV)) + $_nameMV = ''.$_.''; + else + $_nameMV = Util::ucFirst(Lang::game('npc')).' #'.$effMV; break; case SPELL_EFFECT_OPEN_LOCK: if ($effMV && ($_ = Lang::spell('lockType', $effMV))) - $foo['name'] .= ' ('.$fmtStaffTT($_, 'MiscValue'.Lang::main('colon').$effMV).')'; - else - $foo['name'] .= ' ('.$effMV.')'; - + $_nameMV = $this->fmtStaffTip($_, 'MiscValue: '.$effMV); break; case SPELL_EFFECT_ENCHANT_ITEM: case SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY: case SPELL_EFFECT_ENCHANT_HELD_ITEM: case SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC: if ($_ = DB::Aowow()->selectRow('SELECT * FROM ?_itemenchantment WHERE id = ?d', $effMV)) - $foo['name'] .= ' ('.Util::localizedString($_, 'name').')'; + $_nameMV = ''.Util::localizedString($_, 'name').''; else - $foo['name'] .= ' #'.$effMV; + $_nameMV = Util::ucFirst(Lang::game('enchantment')).' #'.$effMV; break; case SPELL_EFFECT_DISPEL: case SPELL_EFFECT_STEAL_BENEFICIAL_BUFF: - $_ = Lang::game('dt', $effMV); - if ($_ && User::isInGroup(U_GROUP_EMPLOYEE)) - $_ = sprintf(Util::$dfnString, 'MiscValue'.Lang::main('colon').$effMV, $_); - else if (!$_) - $_ = $effMV; - - $foo['name'] .= ' ('.$_.')'; + if ($effMV && ($_ = Lang::game('dt', $effMV))) + $_nameMV = $this->fmtStaffTip($_, 'MiscValue: '.$effMV); break; case SPELL_EFFECT_LANGUAGE: - $_ = Lang::game('languages', $effMV); - if ($_ && User::isInGroup(U_GROUP_EMPLOYEE)) - $_ = sprintf(Util::$dfnString, 'MiscValue'.Lang::main('colon').$effMV, $_); - else if (!$_) - $_ = $effMV; - - $foo['name'] .= ' ('.$_.')'; + if ($effMV && ($_ = Lang::game('languages', $effMV))) + $_nameMV = $this->fmtStaffTip($_, 'MiscValue: '.$effMV); break; case SPELL_EFFECT_TRANS_DOOR: case SPELL_EFFECT_SUMMON_OBJECT_WILD: @@ -1819,115 +1832,89 @@ class SpellPage extends GenericPage case SPELL_EFFECT_SUMMON_OBJECT_SLOT2: case SPELL_EFFECT_SUMMON_OBJECT_SLOT3: case SPELL_EFFECT_SUMMON_OBJECT_SLOT4: - if ($summon = $this->subject->getModelInfo($this->typeId, $i)) - $redButtons[BUTTON_VIEW3D] = ['type' => Type::OBJECT, 'displayId' => $summon['displayId']]; - - $_ = Util::ucFirst(Lang::game('object')).' #'.$effMV; - if ($n = GameobjectList::getName($effMV)) - $_ = ' ('.$n.')'; - - $foo['name'] .= $_; + if ($_ = GameobjectList::getName($effMV)) + $_nameMV = ''.$_.''; + else + $_nameMV = Util::ucFirst(Lang::game('object')).' #'.$effMV; break; case SPELL_EFFECT_ACTIVATE_OBJECT: - $_ = Lang::gameObject('actions', $effMV); - if ($_ && User::isInGroup(U_GROUP_EMPLOYEE)) - $_ = sprintf(Util::$dfnString, 'MiscValue'.Lang::main('colon').$effMV, $_); - else if (!$_) - $_ = $effMV; - - $foo['name'] .= ' ('.$_.')'; + if ($_ = Lang::gameObject('actions', $effMV)) + $_nameMV = $this->fmtStaffTip($_, 'MiscValue: '.$effMV); break; case SPELL_EFFECT_APPLY_GLYPH: - if ($_ = DB::Aowow()->selectCell('SELECT spellId FROM ?_glyphproperties WHERE id = ?d', $effMV)) + if ($_ = DB::Aowow()->selectCell('SELECT `spellId` FROM ?_glyphproperties WHERE `id` = ?d', $effMV)) { - if ($n = SpellList::getName($_)) - $foo['name'] .= '('.$n.')'; + if ($_ = SpellList::getName($effMV)) + $_nameMV = ''.$_.''; else - $foo['name'] .= Util::ucFirst(Lang::game('spell')).' #'.$effMV; + $_nameMV = Util::ucFirst(Lang::game('spell')).' #'.$effMV; } - else - $foo['name'] .= ' #'.$effMV; break; case SPELL_EFFECT_SKINNING: + $_ = ''; switch ($effMV) { - case 0: $_ = Lang::game('ct', 1).', '.Lang::game('ct', 2); break; // Beast, Dragonkin - case 1: - case 2: $_ = Lang::game('ct', 4); break; // Elemental (herb gathering, mining) - case 3: $_ = Lang::game('ct', 9); break; // Mechanic - default; $_ = ''; + case 0: $_ = Lang::game('ct', 1).', '.Lang::game('ct', 2); break; // Skinning > Beast, Dragonkin + case 1: // Herb gathering > Elemental + case 2: $_ = Lang::game('ct', 4); break; // Mining > Elemental + case 3: $_ = Lang::game('ct', 9); break; // Dismantling > Mechanic } - if (User::isInGroup(U_GROUP_EMPLOYEE)) - $_ = sprintf(Util::$dfnString, 'MiscValue'.Lang::main('colon').$effMV, $_); - else - $_ = $effMV; - - $foo['name'] .= ' ('.$_.')'; + if ($_) + $_nameMV = $this->fmtStaffTip($_, 'MiscValue: '.$effMV); break; case SPELL_EFFECT_DISPEL_MECHANIC: - $_ = Lang::game('me', $effMV); - if ($_ && User::isInGroup(U_GROUP_EMPLOYEE)) - $_ = sprintf(Util::$dfnString, 'MiscValue'.Lang::main('colon').$effMV, $_); - else if (!$_) - $_ = $effMV; - - $foo['name'] .= ' ('.$_.')'; + if ($_ = Lang::game('me', $effMV)) + $_nameMV = $this->fmtStaffTip($_, 'MiscValue: '.$effMV); break; case SPELL_EFFECT_SKILL_STEP: case SPELL_EFFECT_SKILL: if ($_ = SkillList::getName($effMV)) - $foo['name'] .= '('.$_.')'; + $_nameMV = ''.$_.''; else - $foo['name'] .= Util::ucFirst(Lang::game('skill')).' #'.$effMV; + $_nameMV = Util::ucFirst(Lang::game('skill')).' #'.$effMV; break; case SPELL_EFFECT_ACTIVATE_RUNE: - $_ = Lang::spell('powerRunes', $effMV); - if ($_ && User::isInGroup(U_GROUP_EMPLOYEE)) - $_ = sprintf(Util::$dfnString, 'MiscValue'.Lang::main('colon').$effMV, $_); - else if (!$_) - $_ = $effMV; - - $foo['name'] .= ' ('.$_.')'; + if ($_ = Lang::spell('powerRunes', $effMV)) + $_nameMV = $this->fmtStaffTip($_, 'MiscValue: '.$effMV); break; case SPELL_EFFECT_PLAY_SOUND: case SPELL_EFFECT_PLAY_MUSIC: - $foo['markup'] = '[sound='.$effMV.']'; + if (DB::Aowow()->selectCell('SELECT 1 FROM ?_sounds WHERE `id` = ?d', $effMV)) + { + $_markup = '[sound='.$effMV.']'; + $effMV = 0; // prevent default display + } + else + $_nameMV = Util::ucFirst(Lang::game('sound')).' #'.$effMV; break; case SPELL_EFFECT_REPUTATION: - $_ = Util::ucFirst(Lang::game('faction')).' #'.$effMV; - if ($n = FactionList::getName($effMV)) - $_ = ' ('.$n.')'; + if ($_ = FactionList::getName($effMV)) + $_nameMV = ''.$_.''; + else + $_nameMV = Util::ucFirst(Lang::game('faction')).' #'.$effMV; // apply custom reward rated - if ($cuRate = DB::World()->selectCell('SELECT spell_rate FROM reputation_reward_rate WHERE spell_rate <> 1 && faction = ?d', $effMV)) - $foo['value'] .= sprintf(Util::$dfnString, Lang::faction('customRewRate'), ' ('.(($cuRate < 1 ? '-' : '+').intVal(($cuRate - 1) * $foo['value'])).')'); - - $foo['name'] .= $_; - + if ($cuRate = DB::World()->selectCell('SELECT `spell_rate` FROM reputation_reward_rate WHERE `spell_rate` <> 1 AND `faction` = ?d', $effMV)) + $_footer['value'][2] = sprintf(Util::$dfnString, Lang::faction('customRewRate'), ' ('.(($cuRate < 1 ? '-' : '+').intVal(($cuRate - 1) * $_footer['value'][0])).')'); break; case SPELL_EFFECT_SEND_TAXI: - $_ = DB::Aowow()->selectRow(' - SELECT tn1.name_loc0 AS start_loc0, tn1.name_loc?d AS start_loc?d, tn2.name_loc0 AS end_loc0, tn2.name_loc?d AS end_loc?d - FROM ?_taxipath tp - JOIN ?_taxinodes tn1 ON tp.startNodeId = tn1.id - JOIN ?_taxinodes tn2 ON tp.endNodeId = tn2.id - WHERE tp.id = ?d', + $_ = DB::Aowow()->selectRow( + 'SELECT tn1.`name_loc0` AS `start_loc0`, tn1.name_loc?d AS start_loc?d, tn2.`name_loc0` AS `end_loc0`, tn2.name_loc?d AS end_loc?d + FROM ?_taxipath tp + JOIN ?_taxinodes tn1 ON tp.`startNodeId` = tn1.`id` + JOIN ?_taxinodes tn2 ON tp.`endNodeId` = tn2.`id` + WHERE tp.`id` = ?d', User::$localeId, User::$localeId, User::$localeId, User::$localeId, $effMV ); - if ($_ && User::isInGroup(U_GROUP_EMPLOYEE)) - $foo['name'] .= sprintf(Util::$dfnString, 'MiscValue'.Lang::main('colon').$effMV, ' ('.Util::localizedString($_, 'start').''.Util::localizedString($_, 'end').')'); - else if ($_) - $foo['name'] .= ' ('.Util::localizedString($_, 'start').''.Util::localizedString($_, 'end').')'; - else - $foo['name'] .= ' ('.$effMV.')'; + if ($_) + $_nameMV = $this->fmtStaffTip(''.Util::localizedString($_, 'start').''.Util::localizedString($_, 'end'), 'MiscValue: '.$effMV); break; - default: - { - if (($effMV || $effId == 97) && $effId != 155) - $foo['name'] .= ' ('.$effMV.')'; - + case SPELL_EFFECT_TITAN_GRIP: + $effMV = 0; // effMV is trigger spell and was handled earlier + break; + case SPELL_EFFECT_CAST_BUTTON: + $_nameMV = $effMV; // has a valid 0 value break; - } // Aura case SPELL_EFFECT_APPLY_AURA: case SPELL_EFFECT_PERSISTENT_AREA_AURA: @@ -1938,328 +1925,351 @@ class SpellPage extends GenericPage case SPELL_EFFECT_APPLY_AREA_AURA_ENEMY: case SPELL_EFFECT_APPLY_AREA_AURA_OWNER: { - if ($effAura > 0 && ($aurName = Lang::spell('auras', $effAura))) - { - $foo['name'] .= User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, 'AuraId: '.$effAura, $aurName) : $aurName; - - $bar = $effMV; - switch ($effAura) - { - case SPELL_AURA_MOD_STEALTH_DETECT: - if ($_ = Lang::spell('stealthType', $effMV)) - $bar = User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, 'MiscValue'.Lang::main('colon').$effMV, $_) : $_; - - break; - case SPELL_AURA_MOD_INVISIBILITY: - case SPELL_AURA_MOD_INVISIBILITY_DETECT: - if ($_ = Lang::spell('invisibilityType', $effMV)) - $bar = User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, 'MiscValue'.Lang::main('colon').$effMV, $_) : $_; - - break; - case SPELL_AURA_OBS_MOD_POWER: - case SPELL_AURA_PERIODIC_ENERGIZE: - case SPELL_AURA_MOD_INCREASE_ENERGY: - case SPELL_AURA_MOD_POWER_REGEN: - case SPELL_AURA_MOD_POWER_REGEN_PERCENT: - case SPELL_AURA_MOD_INCREASE_ENERGY_PERCENT: - if ($_ = Lang::spell('powerTypes', $effMV)) - $bar = User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, 'MiscValue'.Lang::main('colon').$effMV, $_) : $_; - - break; - case SPELL_AURA_MOD_STAT: - case SPELL_AURA_MOD_PERCENT_STAT: - case SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE: - case SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT: - case SPELL_AURA_MOD_RANGED_ATTACK_POWER_OF_STAT_PERCENT: - case SPELL_AURA_MOD_MANA_REGEN_FROM_STAT: - case SPELL_AURA_MOD_ATTACK_POWER_OF_STAT_PERCENT: - $mask = $effMV < 0 ? 0x1F : 1 << $effMV; - $_ = []; - for ($j = 0; $j < 5; $j++) - if ($mask & (1 << $j)) - $_[] = Lang::game('stats', $j); - - if ($_ = implode(', ', $_)); - $bar = User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, 'MiscValue'.Lang::main('colon').$effMV, $_) : $_; - - break; - case SPELL_AURA_MOD_SHAPESHIFT: - if ($st = $this->subject->getModelInfo($this->typeId, $i)) - { - $redButtons[BUTTON_VIEW3D] = array( - 'type' => Type::NPC, - 'displayId' => $st['displayId'] - ); - - if ($st['creatureType'] > 0) - $infobox[] = Lang::game('type').Lang::main('colon').Lang::game('ct', $st['creatureType']); - - if ($_ = $st['displayName']) - $bar = User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, 'MiscValue'.Lang::main('colon').$effMV, $_) : $_; - } - break; - case SPELL_AURA_EFFECT_IMMUNITY: - if ($_ = Lang::spell('effects', $effMV)) - $bar = User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, 'MiscValue'.Lang::main('colon').$effMV, $_) : $_; - - break; - case SPELL_AURA_STATE_IMMUNITY: - if ($_ = Lang::spell('auras', $effMV)) - $bar = User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, 'MiscValue'.Lang::main('colon').$effMV, $_) : $_; - - break; - case SPELL_AURA_DISPEL_IMMUNITY: - case SPELL_AURA_MOD_DEBUFF_RESISTANCE: - case SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL: - case SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL_NOT_STACK: - if ($_ = Lang::game('dt', $effMV)) - $bar = User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, 'MiscValue'.Lang::main('colon').$effMV, $_) : $_; - - break; - case SPELL_AURA_TRACK_CREATURES: - if ($_ = Lang::game('ct', $effMV)) - $bar = User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, 'MiscValue'.Lang::main('colon').$effMV, $_) : $_; - - break; - case SPELL_AURA_TRACK_RESOURCES: - if ($_ = Lang::spell('lockType', $effMV)) - $bar = User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, 'MiscValue'.Lang::main('colon').$effMV, $_) : $_; - - break; - case SPELL_AURA_MOD_LANGUAGE: - if ($_ = Lang::game('languages', $effMV)) - $bar = User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, 'MiscValue'.Lang::main('colon').$effMV, $_) : $_; - - break; - case SPELL_AURA_MECHANIC_IMMUNITY: - case SPELL_AURA_MOD_MECHANIC_RESISTANCE: - case SPELL_AURA_MECHANIC_DURATION_MOD: - case SPELL_AURA_MECHANIC_DURATION_MOD_NOT_STACK: - case SPELL_AURA_MOD_MECHANIC_DAMAGE_TAKEN_PERCENT: - case SPELL_AURA_MOD_DAMAGE_DONE_FOR_MECHANIC: - if ($_ = Lang::game('me', $effMV)) - $bar = User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, 'MiscValue'.Lang::main('colon').Util::asHex($effMV), $_) : $_; - - break; - case SPELL_AURA_MECHANIC_IMMUNITY_MASK: - $_ = []; - foreach (Lang::game('me') as $k => $str) - if ($k && ($effMV & (1 << $k - 1))) - $_[] = $str; - - if ($_ = implode(', ', $_)) - $bar = User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, 'MiscValue'.Lang::main('colon').Util::asHex($effMV), $_) : $_; - - break; - case SPELL_AURA_MOD_THREAT: - case SPELL_AURA_MOD_DAMAGE_DONE: - case SPELL_AURA_MOD_DAMAGE_TAKEN: - case SPELL_AURA_MOD_RESISTANCE: - case SPELL_AURA_SCHOOL_IMMUNITY: - case SPELL_AURA_DAMAGE_IMMUNITY: - case SPELL_AURA_MOD_CRITICAL_HEALING_AMOUNT: - case SPELL_AURA_MOD_WEAPON_CRIT_PERCENT: - case SPELL_AURA_MOD_SPELL_CRIT_CHANCE: - case SPELL_AURA_SCHOOL_ABSORB: - case SPELL_AURA_MOD_SPELL_CRIT_CHANCE_SCHOOL: - case SPELL_AURA_MOD_POWER_COST_SCHOOL_PCT: - case SPELL_AURA_MOD_POWER_COST_SCHOOL: - case SPELL_AURA_REFLECT_SPELLS_SCHOOL: - case SPELL_AURA_MOD_DAMAGE_PERCENT_DONE: - case SPELL_AURA_SPLIT_DAMAGE_PCT: - case SPELL_AURA_MOD_BASE_RESISTANCE: - case SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN: - case SPELL_AURA_MANA_SHIELD: - case SPELL_AURA_MOD_RESISTANCE_PCT: - case SPELL_AURA_MOD_HEALING: - case SPELL_AURA_MOD_HEALING_PCT: - case SPELL_AURA_MOD_TARGET_RESISTANCE: - case SPELL_AURA_MOD_HEALING_DONE: - case SPELL_AURA_MOD_HEALING_DONE_PERCENT: - case SPELL_AURA_MOD_BASE_RESISTANCE_PCT: - case SPELL_AURA_MOD_RESISTANCE_EXCLUSIVE: - case SPELL_AURA_REDUCE_PUSHBACK: - case SPELL_AURA_MOD_CRIT_DAMAGE_BONUS: - case SPELL_AURA_MOD_SPELL_DAMAGE_OF_STAT_PERCENT: - case SPELL_AURA_MOD_RESISTANCE_OF_STAT_PERCENT: - case SPELL_AURA_MOD_ATTACKER_SPELL_HIT_CHANCE: - case SPELL_AURA_MOD_TARGET_ABSORB_SCHOOL: - case SPELL_AURA_MOD_TARGET_ABILITY_ABSORB_SCHOOL: - case SPELL_AURA_MOD_INCREASES_SPELL_PCT_TO_HIT: - case SPELL_AURA_MOD_AOE_DAMAGE_AVOIDANCE: - case SPELL_AURA_MOD_DAMAGE_FROM_CASTER: - case SPELL_AURA_MOD_CREATURE_AOE_DAMAGE_AVOIDANCE: - case SPELL_AURA_MOD_SPELL_DAMAGE_OF_ATTACK_POWER: - case SPELL_AURA_MOD_SPELL_HEALING_OF_ATTACK_POWER: - case SPELL_AURA_MOD_SPELL_DAMAGE_FROM_HEALING: // ? Mod Spell & Healing Power by % of Int - case SPELL_AURA_MOD_HOT_PCT: - case SPELL_AURA_MOD_IMMUNE_AURA_APPLY_SCHOOL: // ? Cancel Aura Buffer at % of Caster Health - case SPELL_AURA_MOD_IGNORE_TARGET_RESIST: - case SPELL_AURA_MOD_ATTACK_POWER_OF_ARMOR: // ? Mod Attack Power by School Resistance - case SPELL_AURA_SHARE_DAMAGE_PCT: - case SPELL_AURA_SCHOOL_HEAL_ABSORB: - if ($_ = Lang::getMagicSchools($effMV)) - $bar = User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, 'MiscValue'.Lang::main('colon').Util::asHex($effMV), $_) : $_; - - break; - case SPELL_AURA_MOD_SKILL: - case SPELL_AURA_MOD_SKILL_TALENT: - if ($n = SkillList::getName($effMV)) - $bar = ' ('.$n.')'; - else - $bar = Lang::main('colon').Util::ucFirst(Lang::game('skill')).' #'.$effMV; - - break; - case SPELL_AURA_ADD_FLAT_MODIFIER: - case SPELL_AURA_ADD_PCT_MODIFIER: - if ($_ = Lang::spell('spellModOp', $effMV)) - $bar = User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, 'MiscValue'.Lang::main('colon').$effMV, $_) : $_; - - break; - case SPELL_AURA_MOD_RATING: - case SPELL_AURA_MOD_RATING_FROM_STAT: - $_ = []; - foreach (Lang::spell('combatRating') as $k => $str) - if ((1 << $k) & $effMV) - $_[] = $str; - - if ($_ = implode(', ', $_)) - $bar = User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, 'MiscValue'.Lang::main('colon').Util::asHex($effMV), $_) : $_; - - break; - case SPELL_AURA_MOD_DAMAGE_DONE_VERSUS: - case SPELL_AURA_MOD_DAMAGE_DONE_CREATURE: - case SPELL_AURA_MOD_MELEE_ATTACK_POWER_VERSUS: - case SPELL_AURA_MOD_RANGED_ATTACK_POWER_VERSUS: - case SPELL_AURA_MOD_FLAT_SPELL_DAMAGE_VERSUS: - $_ = []; - foreach (Lang::game('ct') as $k => $str) - if ($k && ($effMV & (1 << $k - 1))) - $_[] = $str; - - if ($_ = implode(', ', $_)) - $bar = User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, 'MiscValue'.Lang::main('colon').Util::asHex($effMV), $_) : $_; - - break; - case SPELL_AURA_CONVERT_RUNE: - $from = $effMV; - if ($_ = Lang::spell('powerRunes', $effMV)) - $from = $_; - - $to = $effMVB; - if ($_ = Lang::spell('powerRunes', $effMVB)) - $to = $_; - - if (User::isInGroup(U_GROUP_EMPLOYEE)) - $bar = sprintf(Util::$dfnString, 'MiscValue'.Lang::main('colon').$effMV, $from).' => '.sprintf(Util::$dfnString, 'MiscValueB'.Lang::main('colon').$effMVB, $to); - else - $bar = $from.' => '.$to; - - $effMVB = 0; - - break; - case SPELL_AURA_MOUNTED: - case SPELL_AURA_TRANSFORM: - if ($transform = $this->subject->getModelInfo($this->typeId, $i)) - { - $redButtons[BUTTON_VIEW3D] = ['type' => Type::NPC, 'displayId' => $transform['displayId']]; - $bar = $transform['typeId'] ? ' ('.$transform['displayName'].')' : ' (#0)'; - } - else - $bar = Lang::main('colon').Lang::game('npc').' #'.$effMV; - - break; - case SPELL_AURA_FORCE_REACTION: - $foo['value'] = sprintf(Util::$dfnString, $foo['value'], Lang::game('rep', $foo['value'])); - // DO NOT BREAK - case SPELL_AURA_MOD_FACTION_REPUTATION_GAIN: - $n = FactionList::getName($effMV); - $bar = ' ('.($n ? ''.$n.'' : Util::ucFirst(Lang::game('faction')).' #'.$effMV).')'; - break; // also breaks for SPELL_AURA_FORCE_REACTION - case SPELL_AURA_OVERRIDE_SPELLS: - if ($so = DB::Aowow()->selectRow('SELECT spellId1, spellId2, spellId3, spellId4, spellId5 FROM ?_spelloverride WHERE id = ?d', $effMV)) - { - $buff = []; - for ($j = 1; $j < 6; $j++) - { - if ($x = $so['spellId'.$j]) - { - $this->extendGlobalData([Type::SPELL => [$x]]); - $buff[] = '[spell='.$x.']'; - } - } - $foo['markup'] = implode(', ', $buff); - } - break; - case SPELL_AURA_IGNORE_COMBAT_RESULT: - case SPELL_AURA_MOD_COMBAT_RESULT_CHANCE: - $what = ''; - switch ($effMV) - { - case 2: // Dodged - $what = Lang::spell('combatRating', 2); - break; - case 3: // Blocked - $what = Lang::spell('combatRating', 4); - break; - case 4: // Parried - $what = Lang::spell('combatRating', 3); - break; - case 0; // Evaded - case 1: // Missed - case 5: // Glanced - case 6: // Crited'ed..ed - case 7: // Crushed - case 8: // Regular - default: - trigger_error('unused case #'.$effMV.' found for aura #'.$effAura); - } - - if ($what) - $bar = User::isInGroup(U_GROUP_EMPLOYEE) ? sprintf(Util::$dfnString, 'MiscValue'.Lang::main('colon').$effMV, $what) : $what; - - break; - case SPELL_AURA_CHANGE_MODEL_FOR_ALL_HUMANOIDS: - case SPELL_AURA_X_RAY: - case SPELL_AURA_MOD_FAKE_INEBRIATE: - $bar = ' ('.Lang::game('npc').' #'.$effMV.')'; - if ($summon = $this->subject->getModelInfo($this->typeId, $i)) - { - $redButtons[BUTTON_VIEW3D] = ['type' => Type::NPC, 'displayId' => $summon['displayId']]; - if (isset($summon['humanoid'])) - { - $redButtons[BUTTON_VIEW3D]['typeId'] = $effMV; - $redButtons[BUTTON_VIEW3D]['humanoid'] = 1; - } - } - if ($n = CreatureList::getName($effMV)) - $bar = ' ('.$n.')'; - break; - case SPELL_AURA_SCREEN_EFFECT: - if ($_ = DB::Aowow()->selectCell('SELECT `name` FROM ?_screeneffect_sounds WHERE `id` = ?d', $effMV)) - $bar = User::isInGroup(U_GROUP_EMPLOYEE | U_GROUP_TESTER) ? sprintf(Util::$dfnString, 'MiscValue'.Lang::main('colon').$effMV, $_) : $_; - } - $foo['name'] .= strstr($bar, 'href') || strstr($bar, '#') ? $bar : ($bar ? ' ('.$bar.')' : null); - - if (in_array($effAura, [SPELL_AURA_MOD_SPELL_DAMAGE_OF_STAT_PERCENT, SPELL_AURA_MOD_RATING_FROM_STAT, SPELL_AURA_MOD_RESISTANCE_OF_STAT_PERCENT])) - $foo['name'] .= ' ['.sprintf(Util::$dfnString, 'MiscValueB'.Lang::main('colon').$effMVB, Lang::game('stats', $effMVB)).']'; - else if ($effMVB > 0) - $foo['name'] .= ' ['.$effMVB.']'; - - } + if ($effAura > 0 && ($_ = Lang::spell('auras', $effAura))) + $_nameAura = $this->fmtStaffTip($_, 'AuraId: '.$effAura); else if ($effAura > 0) - $foo['name'] .= Lang::spell('unkAura', [$effAura]); + $_nameAura = Lang::spell('unkAura', [$effAura]); + switch ($effAura) + { + case SPELL_AURA_MOD_STEALTH_DETECT: + if ($_ = Lang::spell('stealthType', $effMV)) + $_nameMV = $this->fmtStaffTip($_, 'MiscValue: '.$effMV); + break; + case SPELL_AURA_MOD_INVISIBILITY: + case SPELL_AURA_MOD_INVISIBILITY_DETECT: + if ($_ = Lang::spell('invisibilityType', $effMV)) + $_nameMV = $this->fmtStaffTip($_, 'MiscValue: '.$effMV); + break; + case SPELL_AURA_MOD_POWER_REGEN_PERCENT: + case SPELL_AURA_MOD_INCREASE_ENERGY_PERCENT: + case SPELL_AURA_OBS_MOD_POWER: + $valueFmt = '%s%%'; + case SPELL_AURA_PERIODIC_ENERGIZE: + case SPELL_AURA_MOD_INCREASE_ENERGY: + case SPELL_AURA_MOD_POWER_REGEN: + if ($_ = Lang::spell('powerTypes', $effMV)) + $_nameMV = $this->fmtStaffTip($_, 'MiscValue: '.$effMV); + break; + case SPELL_AURA_MOD_PERCENT_STAT: + case SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE: + case SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT: + case SPELL_AURA_MOD_RANGED_ATTACK_POWER_OF_STAT_PERCENT: + case SPELL_AURA_MOD_ATTACK_POWER_OF_STAT_PERCENT: + case SPELL_AURA_MOD_MANA_REGEN_FROM_STAT: + $valueFmt = '%s%%'; + case SPELL_AURA_MOD_STAT: + if ($effMV < 0) + $_nameMV = $this->fmtStaffTip(Lang::main('all'), 'MiscValue: '.$effMV); + else if ($_ = Lang::game('stats', $effMV)) + $_nameMV = $this->fmtStaffTip($_, 'MiscValue: '.$effMV); + break; + case SPELL_AURA_MOD_SHAPESHIFT: + if ($_ = Lang::game('st', $effMV)) + $_nameMV = $this->fmtStaffTip($_, 'MiscValue: '.$effMV); + break; + case SPELL_AURA_EFFECT_IMMUNITY: + if ($_ = Lang::spell('effects', $effMV)) + $_nameMV = $this->fmtStaffTip($_, 'MiscValue: '.$effMV); + break; + case SPELL_AURA_STATE_IMMUNITY: + if ($_ = Lang::spell('auras', $effMV)) + $_nameMV = $this->fmtStaffTip($_, 'MiscValue: '.$effMV); + break; + case SPELL_AURA_MOD_DEBUFF_RESISTANCE: + case SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL: + case SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL_NOT_STACK: + $valueFmt = '%s%%'; + case SPELL_AURA_DISPEL_IMMUNITY: + if ($_ = Lang::game('dt', $effMV)) + $_nameMV = $this->fmtStaffTip($_, 'MiscValue: '.$effMV); + break; + case SPELL_AURA_TRACK_CREATURES: + if ($_ = Lang::game('ct', $effMV)) + $_nameMV = $this->fmtStaffTip($_, 'MiscValue: '.$effMV); + break; + case SPELL_AURA_TRACK_RESOURCES: + if ($_ = Lang::spell('lockType', $effMV)) + $_nameMV = $this->fmtStaffTip($_, 'MiscValue: '.$effMV); + break; + case SPELL_AURA_MOD_LANGUAGE: + if ($_ = Lang::game('languages', $effMV)) + $_nameMV = $this->fmtStaffTip($_, 'MiscValue: '.$effMV); + break; + case SPELL_AURA_MOD_MECHANIC_DAMAGE_TAKEN_PERCENT: + case SPELL_AURA_MOD_MECHANIC_RESISTANCE: + case SPELL_AURA_MECHANIC_DURATION_MOD: + case SPELL_AURA_MECHANIC_DURATION_MOD_NOT_STACK: + case SPELL_AURA_MOD_DAMAGE_DONE_FOR_MECHANIC: + $valueFmt = '%s%%'; + case SPELL_AURA_MECHANIC_IMMUNITY: + if ($_ = Lang::game('me', $effMV)) + $_nameMV = $this->fmtStaffTip($_, 'MiscValue: '.$effMV); + break; + case SPELL_AURA_MECHANIC_IMMUNITY_MASK: + $_ = []; + foreach (Lang::game('me') as $k => $str) + if ($k && ($effMV & (1 << $k - 1))) + $_[] = $str; + + if ($_ = implode(', ', $_)) + $_nameMV = $this->fmtStaffTip($_, 'MiscValue: '.Util::asHex($effMV)); + break; + case SPELL_AURA_MOD_SPELL_DAMAGE_OF_STAT_PERCENT: + case SPELL_AURA_MOD_RESISTANCE_OF_STAT_PERCENT: + if ($_ = Lang::game('stats', $effMVB)) + $_nameMVB = $this->fmtStaffTip($_, 'MiscValueB: '.$effMVB); + // ! DO NOT BREAK ! + case SPELL_AURA_MOD_POWER_COST_SCHOOL_PCT: + case SPELL_AURA_SPLIT_DAMAGE_PCT: + case SPELL_AURA_MOD_RESISTANCE_PCT: + case SPELL_AURA_MOD_HEALING_PCT: + case SPELL_AURA_MOD_BASE_RESISTANCE_PCT: + case SPELL_AURA_MOD_INCREASES_SPELL_PCT_TO_HIT: + case SPELL_AURA_MOD_HOT_PCT: + case SPELL_AURA_SHARE_DAMAGE_PCT: + case SPELL_AURA_MOD_THREAT: + case SPELL_AURA_MOD_DAMAGE_PERCENT_DONE: + case SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN: + case SPELL_AURA_MOD_HEALING_DONE_PERCENT: + case SPELL_AURA_MOD_WEAPON_CRIT_PERCENT: + case SPELL_AURA_MOD_CRITICAL_HEALING_AMOUNT: + case SPELL_AURA_MOD_SPELL_CRIT_CHANCE_SCHOOL: + case SPELL_AURA_REFLECT_SPELLS_SCHOOL: + case SPELL_AURA_REDUCE_PUSHBACK: + case SPELL_AURA_MOD_CRIT_DAMAGE_BONUS: + case SPELL_AURA_MOD_ATTACKER_SPELL_HIT_CHANCE: + case SPELL_AURA_MOD_TARGET_ABSORB_SCHOOL: + case SPELL_AURA_MOD_TARGET_ABILITY_ABSORB_SCHOOL: + case SPELL_AURA_MOD_AOE_DAMAGE_AVOIDANCE: + case SPELL_AURA_MOD_DAMAGE_FROM_CASTER: + case SPELL_AURA_MOD_CREATURE_AOE_DAMAGE_AVOIDANCE: + case SPELL_AURA_MOD_SPELL_DAMAGE_OF_ATTACK_POWER: + case SPELL_AURA_MOD_SPELL_HEALING_OF_ATTACK_POWER: + case SPELL_AURA_MOD_SPELL_DAMAGE_FROM_HEALING: // ? Mod Spell & Healing Power by % of Int + $valueFmt = '%s%%'; + case SPELL_AURA_SCHOOL_ABSORB: + case SPELL_AURA_MOD_DAMAGE_DONE: + case SPELL_AURA_MOD_DAMAGE_TAKEN: + case SPELL_AURA_MOD_RESISTANCE: + case SPELL_AURA_SCHOOL_IMMUNITY: + case SPELL_AURA_DAMAGE_IMMUNITY: + case SPELL_AURA_MOD_POWER_COST_SCHOOL: + case SPELL_AURA_MOD_BASE_RESISTANCE: + case SPELL_AURA_MANA_SHIELD: + case SPELL_AURA_MOD_HEALING: + case SPELL_AURA_MOD_TARGET_RESISTANCE: + case SPELL_AURA_MOD_HEALING_DONE: + case SPELL_AURA_MOD_RESISTANCE_EXCLUSIVE: + case SPELL_AURA_MOD_IMMUNE_AURA_APPLY_SCHOOL: // ? Cancel Aura Buffer at % of Caster Health + case SPELL_AURA_MOD_IGNORE_TARGET_RESIST: + case SPELL_AURA_MOD_ATTACK_POWER_OF_ARMOR: // ? Mod Attack Power by School Resistance + case SPELL_AURA_SCHOOL_HEAL_ABSORB: + if ($_ = Lang::getMagicSchools($effMV)) + $_nameMV = $this->fmtStaffTip($_, 'MiscValue: '.Util::asHex($effMV)); + break; + case SPELL_AURA_MOD_SKILL: + case SPELL_AURA_MOD_SKILL_TALENT: + if ($_ = SkillList::getName($effMV)) + $_nameMV = ''.$_.''; + else + $_nameMV = Util::ucFirst(Lang::game('skill')).' #'.$effMV; + break; + case SPELL_AURA_ADD_PCT_MODIFIER: + $valueFmt = '%s%%'; + case SPELL_AURA_ADD_FLAT_MODIFIER: + if ($_ = Lang::spell('spellModOp', $effMV)) + $_nameMV = $this->fmtStaffTip($_, 'MiscValue: '.$effMV); + break; + case SPELL_AURA_MOD_RATING_FROM_STAT: + $valueFmt = '%s%%'; + if ($_ = Lang::game('stats', $effMVB)) + $_nameMVB = $this->fmtStaffTip($_, 'MiscValueB: '.$effMVB); + // DO NOT BREAK ! + case SPELL_AURA_MOD_RATING: + foreach (Lang::spell('combatRatingMask') as $m => $str) + { + if ($effMV != $m) + continue; + $_nameMV = $this->fmtStaffTip($str, 'MiscValue: '.Util::asHex($effMV)); + break 2; + } + + $_ = []; + foreach (Lang::spell('combatRating') as $k => $str) + if ((1 << $k) & $effMV) + $_[] = $str; + + if ($_ = implode(', ', $_)) + $_nameMV = $this->fmtStaffTip($_, 'MiscValue: '.Util::asHex($effMV)); + break; + case SPELL_AURA_MOD_DAMAGE_DONE_VERSUS: + $valueFmt = '%s%%'; + case SPELL_AURA_MOD_DAMAGE_DONE_CREATURE: + case SPELL_AURA_MOD_MELEE_ATTACK_POWER_VERSUS: + case SPELL_AURA_MOD_RANGED_ATTACK_POWER_VERSUS: + case SPELL_AURA_MOD_FLAT_SPELL_DAMAGE_VERSUS: + $_ = []; + foreach (Lang::game('ct') as $k => $str) + if ($k && ($effMV & (1 << $k - 1))) + $_[] = $str; + + if ($_ = implode(', ', $_)) + $_nameMV = $this->fmtStaffTip($_, 'MiscValue: '.Util::asHex($effMV)); + break; + case SPELL_AURA_CONVERT_RUNE: + $from = $effMV; + if ($_ = Lang::spell('powerRunes', $effMV)) + $from = $_; + + $to = $effMVB; + if ($_ = Lang::spell('powerRunes', $effMVB)) + $to = $_; + + $effMVB = 0; // prevent default display + $_nameMV = $this->fmtStaffTip(''.$from.'', 'MiscValue: '.$effMV).$this->fmtStaffTip($to, 'MiscValueB: '.$effMVB); + break; + case SPELL_AURA_MOUNTED: + case SPELL_AURA_TRANSFORM: + case SPELL_AURA_CHANGE_MODEL_FOR_ALL_HUMANOIDS: + case SPELL_AURA_X_RAY: + case SPELL_AURA_MOD_FAKE_INEBRIATE: + if ($effMV && $_ = CreatureList::getName($effMV)) + $_nameMV = ''.$_.''; + else + $_nameMV = Util::ucFirst(Lang::game('npc')).' #'.$effMV; + break; + case SPELL_AURA_FORCE_REACTION: + $_footer['value'][0] = $this->fmtStaffTip(Lang::game('rep', $_footer['value'][0]), $_footer['value'][0]); + // DO NOT BREAK ! + case SPELL_AURA_MOD_FACTION_REPUTATION_GAIN: + $valueFmt = '%s%%'; + if ($_ = FactionList::getName($effMV)) + $_nameMV = ''.$_.''; + else + $_nameMV = Util::ucFirst(Lang::game('faction')).' #'.$effMV; + break; // also breaks for SPELL_AURA_FORCE_REACTION + case SPELL_AURA_OVERRIDE_SPELLS: + if ($so = DB::Aowow()->selectRow('SELECT `spellId1`, `spellId2`, `spellId3`, `spellId4`, `spellId5` FROM ?_spelloverride WHERE `id` = ?d', $effMV)) + { + if ($so = array_filter($so)) + { + $this->extendGlobalData([Type::SPELL => $so]); + $_markup = '[spell='.implode('], [spell=', $so).']'; + $effMV = 0; // prevent default display + } + } + break; + case SPELL_AURA_MOD_COMBAT_RESULT_CHANCE: + $valueFmt = '%s%%'; + case SPELL_AURA_IGNORE_COMBAT_RESULT: + $what = ''; + switch ($effMV) + { + case 2: // Dodged + $what = Lang::spell('combatRating', 2); + break; + case 3: // Blocked + $what = Lang::spell('combatRating', 4); + break; + case 4: // Parried + $what = Lang::spell('combatRating', 3); + break; + case 0; // Evaded + case 1: // Missed + case 5: // Glanced + case 6: // Crited'ed..ed + case 7: // Crushed + case 8: // Regular + default: + trigger_error('unused case #'.$effMV.' found for aura #'.$effAura); + } + + if ($what) + $_nameMV = $this->fmtStaffTip($what, 'MiscValue: '.$effMV); + break; + case SPELL_AURA_SCREEN_EFFECT: + if ($ses = DB::Aowow()->selectRow('SELECT `name`, `ambienceDay` AS "0", IF(`ambienceNight` <> `ambienceDay`, `ambienceNight`, 0) AS "1", `musicDay` AS "2", IF(`musicNight` <> `musicDay`, `musicNight`, 0) AS "3" FROM ?_screeneffect_sounds WHERE `id` = ?d', $effMV)) + { + $_nameMV = $this->fmtStaffTip($ses['name'], 'MiscValue: '.$effMV); + for ($j = 0; $j < 4; $j++) + if ($ses[$j]) + $_markup .= '[sound='.$ses[$j].']'; + } + break; + case SPELL_AURA_MOD_HEALTH_REGEN_PERCENT: + case SPELL_AURA_OBS_MOD_HEALTH: + case SPELL_AURA_MOD_ARMOR_PENETRATION_PCT: + case SPELL_AURA_MOD_SCALE: + case SPELL_AURA_MOD_SCALE_2: + case SPELL_AURA_MOD_SPEED_ALWAYS: + case SPELL_AURA_MOD_SPEED_SLOW_ALL: + case SPELL_AURA_MOD_SPEED_NOT_STACK: + case SPELL_AURA_MOD_INCREASE_SPEED: + case SPELL_AURA_MOD_INCREASE_MOUNTED_SPEED: + case SPELL_AURA_MOD_DECREASE_SPEED: + case SPELL_AURA_MOD_INCREASE_SWIM_SPEED: + case SPELL_AURA_MOD_PARRY_PERCENT: + case SPELL_AURA_MOD_DODGE_PERCENT: + case SPELL_AURA_MOD_BLOCK_PERCENT: + case SPELL_AURA_MOD_BLOCK_CRIT_CHANCE: + case SPELL_AURA_MOD_HIT_CHANCE: + case SPELL_AURA_MOD_CRIT_PCT: + case SPELL_AURA_MOD_SPELL_HIT_CHANCE: + case SPELL_AURA_MOD_SPELL_CRIT_CHANCE: + $valueFmt = '%s%%'; + break; + } break; } + case SPELL_EFFECT_RESURRECT: + case SPELL_EFFECT_SPIRIT_HEAL: + case SPELL_EFFECT_WEAPON_PERCENT_DAMAGE: + case SPELL_EFFECT_DURABILITY_DAMAGE_PCT: + case SPELL_EFFECT_MODIFY_THREAT_PERCENT: + case SPELL_EFFECT_REDIRECT_THREAT: + case SPELL_EFFECT_HEAL_PCT: + $valueFmt = '%s%%'; + break; } - // cases where we dont want 'Value' to be displayed - if (in_array($effAura, [SPELL_AURA_MOD_TAUNT, SPELL_AURA_MOD_STUN, SPELL_AURA_MOD_SHAPESHIFT, SPELL_AURA_MECHANIC_IMMUNITY]) || in_array($effId, [SPELL_EFFECT_PLAY_MUSIC]) || empty($foo['value'])) - unset($foo['value']); - } + if ($_footer['value'][1]) + { + $buffer = Lang::spell('_value').Lang::main('colon').sprintf($valueFmt, $_footer['value'][0]); + if ($_footer['value'][0] != $_footer['value'][1]) + $buffer .= Lang::game('valueDelim').sprintf($valueFmt, $_footer['value'][1]); + if ($effRPPL != 0) + $buffer .= sprintf(Lang::spell('costPerLevel'), sprintf($valueFmt, $effRPPL)); + if (isset($_footer['value'][2])) + $buffer .= $_footer['value'][2]; - unset($foo); // clear reference + $_footer['value'] = $buffer; + } + else + unset($_footer['value']); + + $_header = $_nameEffect; + + if ($_nameAura) + $_header .= Lang::main('colon').$_nameAura; + + if (strlen($_nameMV)) + $_header .= ' ('.$_nameMV.')'; + else if ($effMV) + $_header .= ' ('.$effMV.')'; + + if (strlen($_nameMVB)) + $_header .= ' ['.$_nameMVB.']'; + else if ($effMVB) + $_header .= ' ['.$effMVB.']'; + + $effects[$i] = array( + 'icon' => $_icon, + 'perfectItem' => $_perfItem, + 'name' => $_header, + 'footer' => $_footer + ); + } return $effects; } diff --git a/setup/db_structure.sql b/setup/db_structure.sql index 0457bd0a..95bc2501 100644 --- a/setup/db_structure.sql +++ b/setup/db_structure.sql @@ -3321,7 +3321,7 @@ UNLOCK TABLES; LOCK TABLES `aowow_dbversion` WRITE; /*!40000 ALTER TABLE `aowow_dbversion` DISABLE KEYS */; -INSERT INTO `aowow_dbversion` VALUES (1720969086,0,NULL,NULL); +INSERT INTO `aowow_dbversion` VALUES (1724095917,0,NULL,NULL); /*!40000 ALTER TABLE `aowow_dbversion` ENABLE KEYS */; UNLOCK TABLES; diff --git a/setup/tools/clisetup/setup.us.php b/setup/tools/clisetup/setup.us.php index da3b1918..7e677a33 100644 --- a/setup/tools/clisetup/setup.us.php +++ b/setup/tools/clisetup/setup.us.php @@ -155,7 +155,7 @@ CLISetup::registerUtility(new class extends UtilityScript if ($this->startStep) { CLI::write(); - CLI::write(' You are currently on step '.($this->startStep + 1).' / '.count($this->steps).' ('.($this->steps[$this->startStep][1] ?: $this->steps[$this->startStep][0][1]).'). You can resume or restart the setup process.', -1, false); + CLI::write(' You are currently on step '.($this->startStep + 1).' / '.count($this->steps).' ('.($this->steps[$this->startStep][1] ?: $this->steps[$this->startStep][0]).'). You can resume or restart the setup process.', -1, false); } CLI::write(); diff --git a/setup/tools/dbc/12340.ini b/setup/tools/dbc/12340.ini index d49eb616..0d59bbda 100644 --- a/setup/tools/dbc/12340.ini +++ b/setup/tools/dbc/12340.ini @@ -1345,6 +1345,14 @@ UNUSED19 = x UNUSED20 = x UNUSED21 = x +[summonproperties] +id = n +control = u +faction = x +title = x +slot = u +flags = x + [talent] id = n tabId = i diff --git a/setup/tools/sqlgen/summonproperties.ss.php b/setup/tools/sqlgen/summonproperties.ss.php new file mode 100644 index 00000000..c7842c61 --- /dev/null +++ b/setup/tools/sqlgen/summonproperties.ss.php @@ -0,0 +1,18 @@ + diff --git a/setup/updates/1724095916_01.sql b/setup/updates/1724095916_01.sql new file mode 100644 index 00000000..9620bdbe --- /dev/null +++ b/setup/updates/1724095916_01.sql @@ -0,0 +1 @@ +UPDATE `aowow_dbversion` SET `sql` = CONCAT(IFNULL(`sql`, ''), ' summonproperties'); diff --git a/template/pages/spell.tpl.php b/template/pages/spell.tpl.php index e8a590af..cbc84224 100644 --- a/template/pages/spell.tpl.php +++ b/template/pages/spell.tpl.php @@ -21,41 +21,41 @@ brick('tooltip'); +if ($this->tools): + echo "
\n"; +endif; + if ($this->reagents[1]): - if ($this->tools): - echo "
\n"; - endif; - $this->brick('reagentList', ['reagents' => $this->reagents[1], 'enhanced' => $this->reagents[0]]); +endif; - if ($this->tools): - echo "
\n"; +if ($this->tools): + echo "
\n"; - if ($this->reagents[0]): - echo "
\n"; - endif; + if ($this->reagents[0]): + echo "
\n"; + endif; ?>

tools as $i => $t): - echo ' \n"; - endforeach; + foreach ($this->tools as $i => $t): + echo ' \n"; + endforeach; ?>
'.$t['name']."
'.$t['name']."
reagents[0]): - echo "
\n"; - endif; + if ($this->reagents[0]): + echo "
\n"; endif; endif; ?> @@ -86,23 +86,23 @@ endif; - duration) ? $this->duration : ''.Lang::main('n_a').'');?> + duration ?: ''.Lang::main('n_a').'');?> - school[1]) ? (User::isInGroup(U_GROUP_STAFF) ? sprintf(Util::$dfnString, $this->school[0], $this->school[1]) : $this->school[1]) : ''.Lang::main('n_a').'');?> + school ?: ''.Lang::main('n_a').'');?> - mechanic) ? $this->mechanic : ''.Lang::main('n_a').'');?> + mechanic ?:''.Lang::main('n_a').'');?> - dispel) ? $this->dispel : ''.Lang::main('n_a').'');?> + dispel ?: ''.Lang::main('n_a').'');?> - gcdCat) ? $this->gcdCat : ''.Lang::main('n_a').'');?> + gcdCat ?: ''.Lang::main('n_a').'');?> @@ -113,7 +113,7 @@ endif; - range.' '.Lang::spell('_distUnit').' ('.$this->rangeName;?>) + range.' '.Lang::spell('_distUnit').' ('.$this->rangeName.')';?> @@ -121,7 +121,7 @@ endif; - cooldown) ? $this->cooldown : ''.Lang::main('n_a').'');?> + cooldown ?: ''.Lang::main('n_a').'');?> '.Lang::spell('_gcd');?> @@ -138,7 +138,7 @@ if (!in_array(array_values($this->scaling), [[-1, -1, 0, 0], [0, 0, 0, 0]])): scaling as $k => $s): if ($s > 0): - echo ' '.sprintf(Lang::spell('scaling', $k), $s * 100)."
\n"; + echo ' '.Lang::spell('scaling', $k, [$s * 100])."
\n"; endif; endforeach; ?> @@ -147,7 +147,7 @@ if (!in_array(array_values($this->scaling), [[-1, -1, 0, 0], [0, 0, 0, 0]])): stances)): +if ($this->stances): ?> @@ -156,16 +156,16 @@ if (!empty($this->stances)): items)): +if ($this->items): ?> - ', $this->items[0]), $this->items[1]) : $this->items[1]);?> + items;?> effects as $i => $e): ?> @@ -174,42 +174,8 @@ foreach ($this->effects as $i => $e): '.Lang::spell('_value').Lang::main('colon').$e['value']; - endif; - - if (isset($e['radius'])): - $smallBuf .= '
'.Lang::spell('_radius').Lang::main('colon').$e['radius'].' '.Lang::spell('_distUnit'); - endif; - - if (isset($e['interval'])): - $smallBuf .= '
'.Lang::spell('_interval').Lang::main('colon').$e['interval']; - endif; - - if (isset($e['mechanic'])): - $smallBuf .= '
'.Lang::game('mechanic') .Lang::main('colon').$e['mechanic']; - endif; - - if (isset($e['procData'])): - $smallBuf .= '
'; - - if ($e['procData'][0] < 0): - $smallBuf .= sprintf(Lang::spell('ppm'), Lang::nf(-$e['procData'][0], 1)); - elseif ($e['procData'][0] < 100.0): - $smallBuf .= Lang::spell('procChance').Lang::main('colon').$e['procData'][0].'%'; - endif; - - if ($e['procData'][1]): - if ($e['procData'][0] < 100.0): - $smallBuf .= '
'; - endif; - $smallBuf .= sprintf(Lang::game('cooldown'), $e['procData'][1]); - endif; - endif; - - if ($smallBuf): - echo "".$smallBuf."\n"; + if ($e['footer']): + echo "
".implode("
", $e['footer'])."
\n"; endif; if (isset($e['markup'])): @@ -218,35 +184,37 @@ $WH.aE(window,\'load\',function(){$WH.ge(\'spelleffectmarkup-'.$i.'\').innerHTML //]]>'; endif; - if (isset($e['icon'])): + if ($e['icon']): + ['type' => $ty, 'typeId' => $ti, 'name' => $na, 'quality' => $qu, 'count' => $co] = $e['icon']; ?> '.$e['icon']['name']."\n"; + if ($qu): + echo ' \n"; else: - echo ' \n"; + echo ' \n"; endif; ?>
'.($na ? sprintf('%s', $ti, $na) : Util::ucFirst(Lang::game('item')).' #'.$ti)."'.(strpos($e['icon']['name'], '#') ? $e['icon']['name'] : sprintf('%s', $e['icon']['id'], $e['icon']['name']))."'.($na ? sprintf('%s', $ti, $na) : Util::ucFirst(Lang::game('spell')).' #'.$ti)."
$si, 'spellName' => $sn, 'itemId' => $ii, 'itemName' => $in, 'quality' => $qu, 'icon' => $ic, 'chance' => $ch] = $e['perfectItem']; ?> - - -
+ + +
'.Lang::spell('_seeMore').'