From 3aede189262318b281b3f5f8ff5682db6765a2e6 Mon Sep 17 00:00:00 2001 From: Sarjuuk Date: Sat, 24 Aug 2024 19:16:38 +0200 Subject: [PATCH] SpellDetailPage/Fixup * fix empty scaling bar * fix setting max level for scaling tooltips * fix displayed periodic power gain value for runic power and rage * attempt to fix spell coefficient calculation (dear god...) * append % sign to value for two more auras * display value per combo point --- includes/defines.php | 6 +++ includes/types/spell.class.php | 4 +- localization/locale_dede.php | 1 + localization/locale_enus.php | 1 + localization/locale_eses.php | 1 + localization/locale_frfr.php | 1 + localization/locale_ruru.php | 1 + localization/locale_zhcn.php | 1 + pages/spell.php | 82 +++++++++++++++++++--------------- template/pages/spell.tpl.php | 8 ++-- 10 files changed, 63 insertions(+), 43 deletions(-) diff --git a/includes/defines.php b/includes/defines.php index eb6e729f..65b9d791 100644 --- a/includes/defines.php +++ b/includes/defines.php @@ -519,6 +519,12 @@ define('SPELL_SCHOOL_ARCANE', 6); define('SPELL_MAGIC_SCHOOLS', 0x7E); define('SPELL_ALL_SCHOOLS', 0x7F); +// DamageClass +define('SPELL_DAMAGE_CLASS_NONE', 0); +define('SPELL_DAMAGE_CLASS_MAGIC', 1); +define('SPELL_DAMAGE_CLASS_MELEE', 2); +define('SPELL_DAMAGE_CLASS_RANGED', 3); + // CharacterSlot define('SLOT_HEAD', 0); define('SLOT_NECK', 1); diff --git a/includes/types/spell.class.php b/includes/types/spell.class.php index 53892951..2d9ce1af 100644 --- a/includes/types/spell.class.php +++ b/includes/types/spell.class.php @@ -678,7 +678,7 @@ class SpellList extends BaseType if (!$this->curTpl['castTime'] && $this->isChanneledSpell()) return Lang::spell('channeled'); // SPELL_ATTR0_ABILITY instant ability.. yeah, wording thing only (todo (low): rule is imperfect) - else if (!$this->curTpl['castTime'] && ($this->curTpl['damageClass'] != 1 || $this->curTpl['attributes0'] & SPELL_ATTR0_ABILITY)) + else if (!$this->curTpl['castTime'] && ($this->curTpl['damageClass'] != SPELL_DAMAGE_CLASS_MAGIC || $this->curTpl['attributes0'] & SPELL_ATTR0_ABILITY)) return Lang::spell('instantPhys'); // show instant only for player/pet/npc abilities (todo (low): unsure when really hidden (like talent-case)) else if ($noInstant && !in_array($this->curTpl['typeCat'], [11, 7, -3, -6, -8, 0]) && !($this->curTpl['cuFlags'] & SPELL_CU_TALENTSPELL)) @@ -1957,7 +1957,7 @@ class SpellList extends BaseType $x .= '
'.implode('
', $xTmp).'
'; $min = $this->scaling[$this->id] ? ($this->getField('baseLevel') ?: 1) : 1; - $max = $this->scaling[$this->id] ? MAX_LEVEL : 1; + $max = $this->scaling[$this->id] ? ($this->getField('maxLevel') ?: MAX_LEVEL) : 1; // scaling information - spellId:min:max:curr $x .= ''; diff --git a/localization/locale_dede.php b/localization/locale_dede.php index ae1251b5..36196a91 100644 --- a/localization/locale_dede.php +++ b/localization/locale_dede.php @@ -1463,6 +1463,7 @@ $lang = array( 'pctCostOf' => "vom Grund%s", 'costPerSec' => ", plus %s pro Sekunde", 'costPerLevel' => ", plus %s pro Stufe", + 'pointsPerCP' => ", plus %s pro Combopunkt", 'stackGroup' => "Stack Gruppierung", 'linkedWith' => "Verknüpft mit", '_scaling' => "Skalierung", diff --git a/localization/locale_enus.php b/localization/locale_enus.php index 41824f6b..599732b7 100644 --- a/localization/locale_enus.php +++ b/localization/locale_enus.php @@ -1464,6 +1464,7 @@ $lang = array( 'pctCostOf' => "of base %s", 'costPerSec' => ", plus %s per sec", // see 'powerTypes' 'costPerLevel' => ", plus %s per level", // not used? + 'pointsPerCP' => ", plus %s per combo point", 'stackGroup' => "Stack Group", 'linkedWith' => "Linked with", '_scaling' => "Scaling", diff --git a/localization/locale_eses.php b/localization/locale_eses.php index a34e44e2..37fceca9 100644 --- a/localization/locale_eses.php +++ b/localization/locale_eses.php @@ -1463,6 +1463,7 @@ $lang = array( 'pctCostOf' => "del %s base", 'costPerSec' => ", mas %s por segundo", 'costPerLevel' => ", mas %s por nivel", + 'pointsPerCP' => ", mas %s por punto de combo", 'stackGroup' => "Grupo de aplilamiento", 'linkedWith' => "Asociado con", '_scaling' => "Escala", diff --git a/localization/locale_frfr.php b/localization/locale_frfr.php index 9f52e1e6..3792ba0f 100644 --- a/localization/locale_frfr.php +++ b/localization/locale_frfr.php @@ -1463,6 +1463,7 @@ $lang = array( 'pctCostOf' => "de la %s de base", 'costPerSec' => ", plus %s par seconde", 'costPerLevel' => ", plus %s par niveau", + 'pointsPerCP' => ", plus %s par point de combo", 'stackGroup' => "[Stack Group]", 'linkedWith' => "[Linked with]", '_scaling' => "[Scaling]", diff --git a/localization/locale_ruru.php b/localization/locale_ruru.php index ad989cc3..34f916a1 100644 --- a/localization/locale_ruru.php +++ b/localization/locale_ruru.php @@ -1463,6 +1463,7 @@ $lang = array( 'pctCostOf' => "от базовой %s", 'costPerSec' => ", плюс %s в секунду", 'costPerLevel' => ", плюс %s за уровень", + 'pointsPerCP' => ", плюс %s в прием в серии", 'stackGroup' => "[Stack Group]", 'linkedWith' => "[Linked with]", '_scaling' => "[Scaling]", diff --git a/localization/locale_zhcn.php b/localization/locale_zhcn.php index fdbc95bb..6f160cd5 100644 --- a/localization/locale_zhcn.php +++ b/localization/locale_zhcn.php @@ -1463,6 +1463,7 @@ $lang = array( 'pctCostOf' => "的基础%s", 'costPerSec' => ",加%s每秒", 'costPerLevel' => ",加%s每级", + 'pointsPerCP' => ",加%s每连击", 'stackGroup' => "Stack Group", 'linkedWith' => "Linked with", '_scaling' => "缩放比例", diff --git a/pages/spell.php b/pages/spell.php index 264ff62b..2d7c8141 100644 --- a/pages/spell.php +++ b/pages/spell.php @@ -1470,23 +1470,43 @@ class SpellPage extends GenericPage private function createScalingData() : array // calculation mostly like seen in TC { - $scaling = array_merge( - array( - 'directSP' => -1, - 'dotSP' => -1, - '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) - ); + $scaling = ['directSP' => 0, 'dotSP' => 0, 'directAP' => 0, 'dotAP' => 0]; + $pMask = $this->subject->periodicEffectsMask(); + $allDoTs = true; + + for ($i = 1; $i < 4; $i++) + { + if (!$this->subject->getField('effect'.$i.'Id')) + continue; + + if ($pMask & 1 << ($i - 1)) + { + $scaling['dotSP'] = $this->subject->getField('effect'.$i.'BonusMultiplier'); + continue; + } + else + $scaling['directSP'] = $this->subject->getField('effect'.$i.'BonusMultiplier'); + + $allDoTs = false; + } + + if ($s = 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)) + $scaling = $s; if (!$this->subject->isDamagingSpell() && !$this->subject->isHealingSpell()) - return $scaling; + return array_filter($scaling, fn($x) => $x > 0); + + // only calculate for class/pet spells + if (!in_array($this->subject->getField('typeCat'), [-2, -3, -7, 7])) + return array_filter($scaling, fn($x) => $x > 0); + + if ($this->subject->getField('damageClass') == SPELL_DAMAGE_CLASS_NONE) + return array_filter($scaling, fn($x) => $x > 0); foreach ($scaling as $k => $v) { - // only calculate for class/pet spells - if ($v != -1 || !in_array($this->subject->getField('typeCat'), [-2, -3, -7, 7])) + // recalculate if spell_bonus_data says so + if ($v != -1) continue; // no known calculation for physical abilities @@ -1494,12 +1514,10 @@ class SpellPage extends GenericPage continue; // dont use spellPower to scale physical Abilities - if ($this->subject->getField('schoolMask') == 0x1 && ($k == 'directSP' || $k == 'dotSP')) + if ($this->subject->getField('schoolMask') == (1 << SPELL_SCHOOL_NORMAL) && ($k == 'directSP' || $k == 'dotSP')) continue; $isDOT = false; - $pMask = $this->subject->periodicEffectsMask(); - if ($k == 'dotSP' || $k == 'dotAP') { if ($pMask) @@ -1507,23 +1525,8 @@ class SpellPage extends GenericPage else continue; } - else // if all used effects are periodic, dont calculate direct component - { - $bar = true; - for ($i = 1; $i < 4; $i++) - { - if (!$this->subject->getField('effect'.$i.'Id')) - continue; - - if ($pMask & 1 << ($i - 1)) - continue; - - $bar = false; - } - - if ($bar) - continue; - } + else if ($allDoTs) // if all used effects are periodic, dont calculate direct component + continue; // Damage over Time spells bonus calculation $dotFactor = 1.0; @@ -1546,8 +1549,7 @@ class SpellPage extends GenericPage // 50% for damage and healing spells for leech spells from damage bonus and 0% from healing for ($j = 1; $j < 4; ++$j) { - // SPELL_EFFECT_HEALTH_LEECH || SPELL_AURA_PERIODIC_LEECH - if ($this->subject->getField('effectId'.$j) == 9 || $this->subject->getField('effect'.$j.'AuraId') == 53) + if ($this->subject->getField('effectId'.$j) == SPELL_EFFECT_HEALTH_LEECH || $this->subject->getField('effect'.$j.'AuraId') == SPELL_AURA_PERIODIC_LEECH) { $castingTime /= 2; break; @@ -1558,13 +1560,13 @@ class SpellPage extends GenericPage $castingTime *= 1.88; // SPELL_SCHOOL_MASK_NORMAL - if ($this->subject->getField('schoolMask') != 0x1) + if ($this->subject->getField('schoolMask') != (1 << SPELL_SCHOOL_NORMAL)) $scaling[$k] = ($castingTime / 3500.0) * $dotFactor; else $scaling[$k] = 0; // would be 1 ($dotFactor), but we dont want it to be displayed } - return $scaling; + return array_filter($scaling, fn($x) => $x > 0); } private function createRequiredItems() : string @@ -1650,6 +1652,7 @@ class SpellPage extends GenericPage $effBP = $this->subject->getField('effect'.$i.'BasePoints'); $effDS = $this->subject->getField('effect'.$i.'DieSides'); $effRPPL = $this->subject->getField('effect'.$i.'RealPointsPerLevel'); + $effPPCP = $this->subject->getField('effect'.$i.'PointsPerComboPoint'); $effAura = $this->subject->getField('effect'.$i.'AuraId'); /* Effect Format @@ -1950,6 +1953,9 @@ class SpellPage extends GenericPage case SPELL_AURA_MOD_POWER_REGEN: if ($_ = Lang::spell('powerTypes', $effMV)) $_nameMV = $this->fmtStaffTip($_, 'MiscValue: '.$effMV); + + if ($effMV == POWER_RAGE || $effMV == POWER_RUNIC_POWER) + array_walk($_footer['value'], fn(&$x) => $x /= 10); break; case SPELL_AURA_MOD_PERCENT_STAT: case SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE: @@ -2217,6 +2223,8 @@ class SpellPage extends GenericPage case SPELL_AURA_MOD_CRIT_PCT: case SPELL_AURA_MOD_SPELL_HIT_CHANCE: case SPELL_AURA_MOD_SPELL_CRIT_CHANCE: + case SPELL_AURA_MOD_MELEE_RANGED_HASTE: + case SPELL_AURA_MOD_CASTING_SPEED_NOT_STACK: $valueFmt = '%s%%'; break; } @@ -2240,6 +2248,8 @@ class SpellPage extends GenericPage $buffer .= Lang::game('valueDelim').sprintf($valueFmt, $_footer['value'][1]); if ($effRPPL != 0) $buffer .= sprintf(Lang::spell('costPerLevel'), sprintf($valueFmt, $effRPPL)); + if ($effPPCP != 0) + $buffer .= sprintf(Lang::spell('pointsPerCP'), sprintf($valueFmt, $effPPCP)); if (isset($_footer['value'][2])) $buffer .= $_footer['value'][2]; diff --git a/template/pages/spell.tpl.php b/template/pages/spell.tpl.php index cbc84224..8a89ff84 100644 --- a/template/pages/spell.tpl.php +++ b/template/pages/spell.tpl.php @@ -129,17 +129,15 @@ endif; scaling), [[-1, -1, 0, 0], [0, 0, 0, 0]])): +if ($this->scaling): ?> scaling as $k => $s): - if ($s > 0): - echo ' '.Lang::spell('scaling', $k, [$s * 100])."
\n"; - endif; + foreach ($this->scaling as $k => $v): + echo ' '.Lang::spell('scaling', $k, [$v * 100])."
\n"; endforeach; ?>