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
This commit is contained in:
Sarjuuk
2024-08-24 19:16:38 +02:00
parent 075e15ba0c
commit 3aede18926
10 changed files with 63 additions and 43 deletions

View File

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

View File

@@ -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 .= '<table><tr><td>'.implode('<br />', $xTmp).'</td></tr></table>';
$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 .= '<!--?'.$this->id.':'.$min.':'.$max.':'.min($this->charLevel, $max).'-->';

View File

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

View File

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

View File

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

View File

@@ -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]",

View File

@@ -1463,6 +1463,7 @@ $lang = array(
'pctCostOf' => "от базовой %s",
'costPerSec' => ", плюс %s в секунду",
'costPerLevel' => ", плюс %s за уровень",
'pointsPerCP' => ", плюс %s в прием в серии",
'stackGroup' => "[Stack Group]",
'linkedWith' => "[Linked with]",
'_scaling' => "[Scaling]",

View File

@@ -1463,6 +1463,7 @@ $lang = array(
'pctCostOf' => "的基础%s",
'costPerSec' => ",加%s每秒",
'costPerLevel' => ",加%s每级",
'pointsPerCP' => ",加%s每连击",
'stackGroup' => "Stack Group",
'linkedWith' => "Linked with",
'_scaling' => "缩放比例",

View File

@@ -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,24 +1525,9 @@ 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'))
else if ($allDoTs) // if all used effects are periodic, dont calculate direct component
continue;
if ($pMask & 1 << ($i - 1))
continue;
$bar = false;
}
if ($bar)
continue;
}
// Damage over Time spells bonus calculation
$dotFactor = 1.0;
if ($isDOT)
@@ -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];

View File

@@ -129,17 +129,15 @@ endif;
</tr>
<?php
// not default values
if (!in_array(array_values($this->scaling), [[-1, -1, 0, 0], [0, 0, 0, 0]])):
if ($this->scaling):
?>
<tr>
<th><?=Lang::spell('_scaling');?></th>
<td colspan="3">
<?php
foreach ($this->scaling as $k => $s):
if ($s > 0):
echo ' '.Lang::spell('scaling', $k, [$s * 100])."<br>\n";
endif;
foreach ($this->scaling as $k => $v):
echo ' '.Lang::spell('scaling', $k, [$v * 100])."<br>\n";
endforeach;
?>
</td>