diff --git a/endpoints/data/data.php b/endpoints/data/data.php
index 876c9433..8b38397b 100644
--- a/endpoints/data/data.php
+++ b/endpoints/data/data.php
@@ -31,7 +31,7 @@ class DataBaseResponse extends TextResponse
foreach ($this->params as $set)
{
// requires valid token to hinder automated access
- if ($set != 'item-scaling' && (!$this->_get['t'] || empty($_SESSION['dataKey']) || $this->_get['t'] != $_SESSION['dataKey']))
+ if ($set != 'item-scaling' && $set != 'spell-scaling' && (!$this->_get['t'] || empty($_SESSION['dataKey']) || $this->_get['t'] != $_SESSION['dataKey']))
{
trigger_error('DataBaseResponse::generate - session data key empty or expired', E_USER_ERROR);
continue;
@@ -54,6 +54,7 @@ class DataBaseResponse extends TextResponse
'quick-excludes',
'weight-presets',
'item-scaling',
+ 'spell-scaling',
'realms',
'statistics' => $this->loadAgnosticFile($set),
// localized
diff --git a/includes/dbtypes/spell.class.php b/includes/dbtypes/spell.class.php
index baac2ba0..852fcde8 100644
--- a/includes/dbtypes/spell.class.php
+++ b/includes/dbtypes/spell.class.php
@@ -29,6 +29,11 @@ class SpellList extends DBTypeList
public const EFFECTS_SCALING_DAMAGE = array( // as per Unit::SpellDamageBonusDone() calls in TC
SPELL_EFFECT_SCHOOL_DAMAGE, SPELL_EFFECT_HEALTH_LEECH, SPELL_EFFECT_POWER_BURN
);
+ public const EFFECTS_LDC_SCALING = array(
+ SPELL_EFFECT_SCHOOL_DAMAGE, SPELL_EFFECT_DUMMY, SPELL_EFFECT_POWER_DRAIN, SPELL_EFFECT_HEALTH_LEECH, SPELL_EFFECT_HEAL,
+ SPELL_EFFECT_WEAPON_DAMAGE, SPELL_EFFECT_POWER_BURN, SPELL_EFFECT_SCRIPT_EFFECT, SPELL_EFFECT_NORMALIZED_WEAPON_DMG, SPELL_EFFECT_FORCE_CAST_WITH_VALUE,
+ SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE, SPELL_EFFECT_TRIGGER_MISSILE_SPELL_WITH_VALUE
+ );
public const EFFECTS_ITEM_CREATE = array(
SPELL_EFFECT_CREATE_ITEM, SPELL_EFFECT_SUMMON_CHANGE_ITEM, SPELL_EFFECT_CREATE_RANDOM_ITEM, SPELL_EFFECT_CREATE_MANA_GEM, SPELL_EFFECT_CREATE_ITEM_2
);
@@ -61,6 +66,10 @@ class SpellList extends DBTypeList
public const AURAS_SCALING_DAMAGE = array( // as per Unit::SpellDamageBonusDone() calls in TC
SPELL_AURA_PERIODIC_DAMAGE, SPELL_AURA_PERIODIC_LEECH, SPELL_AURA_DAMAGE_SHIELD, SPELL_AURA_PROC_TRIGGER_DAMAGE
);
+ public const AURAS_LDC_SCALING = array(
+ SPELL_AURA_PERIODIC_DAMAGE, SPELL_AURA_DUMMY, SPELL_AURA_PERIODIC_HEAL, SPELL_AURA_DAMAGE_SHIELD, SPELL_AURA_PROC_TRIGGER_DAMAGE,
+ SPELL_AURA_PERIODIC_LEECH, SPELL_AURA_PERIODIC_MANA_LEECH, SPELL_AURA_SCHOOL_ABSORB, SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE
+ );
public const AURAS_ITEM_CREATE = array(
SPELL_AURA_CHANNEL_DEATH_ITEM
);
@@ -648,6 +657,9 @@ class SpellList extends DBTypeList
$str .= $pcp."% ".Lang::spell('pctCostOf', [mb_strtolower(Lang::spell('powerTypes', $pt))]);
else if ($pc > 0 || $pps > 0 || $pcpl > 0)
{
+ if ($this->curTpl['attributes0'] & SPELL_ATTR0_LEVEL_DAMAGE_CALCULATION)
+ $str .= '';
+
if (Lang::exist('spell', 'powerCost', $pt))
$str .= Lang::spell('powerCost', $pt, intVal($pps > 0), [$pc, $pps]);
else
@@ -690,13 +702,17 @@ class SpellList extends DBTypeList
// formulae base from TC
private function calculateAmountForCurrent(int $effIdx, int $nTicks = 1) : array
{
- $level = $this->charLevel;
- $maxBase = 0;
- $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');
+ $level = $this->charLevel;
+ $maxBase = 0;
+ $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');
+ $spellLvl = $this->getField('spellLevel');
+ $LDSEffs = $this->canLevelDamageScale();
+ $modMin =
+ $modMax = null;
if ($rppl)
{
@@ -705,22 +721,29 @@ class SpellList extends DBTypeList
else if ($level < $baseLvl)
$level = $baseLvl;
- if (!$this->getField('atributes0') & SPELL_ATTR0_PASSIVE)
- $level -= $this->getField('spellLevel');
+ if (!$this->getField('attributes0') & SPELL_ATTR0_PASSIVE)
+ $level -= $spellLvl;
$maxBase += (int)(($level - $baseLvl) * $rppl);
$maxBase *= $nTicks;
+
}
$min = $nTicks * ($add ? $base + 1 : $base);
$max = $nTicks * ($add + $base);
- return [
- $min + $maxBase,
- $max + $maxBase,
- $rppl ? '' : null,
- $rppl ? '' : null
- ];
+ if ($rppl)
+ {
+ $modMin = '';
+ $modMax = '';
+ }
+ else if ($this->getField('attributes0') & SPELL_ATTR0_LEVEL_DAMAGE_CALCULATION && in_array($effIdx, $LDSEffs) && $spellLvl)
+ {
+ $modMin = '';
+ $modMax = '';
+ }
+
+ return [$min + $maxBase, $max + $maxBase, $modMin, $modMax];
}
public function canCreateItem() : array
@@ -766,6 +789,16 @@ class SpellList extends DBTypeList
return $idx;
}
+ public function canLevelDamageScale() : array
+ {
+ $idx = [];
+ for ($i = 1; $i < 4; $i++)
+ if (in_array($this->curTpl['effect'.$i.'Id'], SpellList::EFFECTS_LDC_SCALING) || in_array($this->curTpl['effect'.$i.'AuraId'], SpellList::AURAS_LDC_SCALING))
+ $idx[] = $i;
+
+ return $idx;
+ }
+
public function isChanneledSpell() : bool
{
return $this->curTpl['attributes1'] & (SPELL_ATTR1_CHANNELED_1 | SPELL_ATTR1_CHANNELED_2);
@@ -1970,10 +2003,23 @@ class SpellList extends DBTypeList
if ($xTmp)
$x .= '
';
- $min = $this->scaling[$this->id] ? ($this->getField('baseLevel') ?: 1) : 1;
- $max = $this->scaling[$this->id] ? ($this->getField('maxLevel') ?: MAX_LEVEL) : 1;
- // scaling information - spellId:min:max:curr
- $x .= '';
+ // scaling information - spellId:min:max:curr[:scalingDistribution:ScalingFlags]
+ $scalingInfo = array(
+ $this->id,
+ $this->scaling[$this->id] ? ($this->getField('baseLevel') ?: 1) : 1,
+ $this->scaling[$this->id] ? ($this->getField('maxLevel') ?: MAX_LEVEL) : 1
+ );
+
+ if ($this->getField('attributes0') & SPELL_ATTR0_LEVEL_DAMAGE_CALCULATION)
+ {
+ $scalingInfo[] = $this->getField('spellLevel') ?: 1;
+ $scalingInfo[] = 1; // in 4.x+ proper scaling information; for us just to flag a npc spell as level damage scaling
+ $scalingInfo[] = 1;
+ }
+ else
+ $scalingInfo[] = min($this->charLevel, $scalingInfo[2]);
+
+ $x .= '';
return $x;
}
diff --git a/includes/kernel.php b/includes/kernel.php
index a4a0420e..fafe7593 100644
--- a/includes/kernel.php
+++ b/includes/kernel.php
@@ -7,7 +7,7 @@ mb_substitute_character('none'); // drop invalid char
error_reporting(E_ALL);
mysqli_report(MYSQLI_REPORT_ERROR);
-define('AOWOW_REVISION', 45);
+define('AOWOW_REVISION', 46);
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/setup/sql/updates/1770309983_01.sql b/setup/sql/updates/1770309983_01.sql
new file mode 100644
index 00000000..27c9e220
--- /dev/null
+++ b/setup/sql/updates/1770309983_01.sql
@@ -0,0 +1 @@
+UPDATE `aowow_dbversion` SET `build` = CONCAT(IFNULL(`build`, ''), ' spellscaling itemscaling');
diff --git a/setup/tools/dbc/12340.ini b/setup/tools/dbc/12340.ini
index f2b66696..808fa661 100644
--- a/setup/tools/dbc/12340.ini
+++ b/setup/tools/dbc/12340.ini
@@ -476,6 +476,9 @@ chance = f
[gtcombatratings]
ratio = f
+[gtnpcmanacostscaler]
+factor = f
+
[gtoctclasscombatratingscalar]
idx = n
ratio = f
diff --git a/setup/tools/filegen/spellscaling.ss.php b/setup/tools/filegen/spellscaling.ss.php
new file mode 100644
index 00000000..e91b80c5
--- /dev/null
+++ b/setup/tools/filegen/spellscaling.ss.php
@@ -0,0 +1,42 @@
+ [[], CLISetup::ARGV_PARAM, 'Compiles spell scaling data to file for spells with attribute SPELL_ATTR0_LEVEL_DAMAGE_CALCULATION.']
+ );
+
+ protected $fileTemplateDest = ['datasets/spell-scaling'];
+ protected $fileTemplateSrc = ['spell-scaling.in'];
+
+ protected $dbcSourceFiles = ['gtnpcmanacostscaler'];
+
+ private function debugify(array $data) : string
+ {
+ $buff = [];
+ foreach ($data as $id => $row)
+ $buff[] = str_pad($id, 7, " ", STR_PAD_LEFT).": ".$row;
+
+ return "{\r\n".implode(",\r\n", $buff)."\r\n}";
+ }
+
+ private function spellScalingSV() : string
+ {
+ $data = DB::Aowow()->selectCol('SELECT `idx` + 1 AS ARRAY_KEY, `factor` FROM dbc_gtnpcmanacostscaler');
+
+ return Cfg::get('DEBUG') ? $this->debugify($data) : Util::toJSON($data);
+ }
+})
+
+?>
diff --git a/setup/tools/filegen/templates/item-scaling.in b/setup/tools/filegen/templates/item-scaling.in
index b6521d1b..2e4d7807 100644
--- a/setup/tools/filegen/templates/item-scaling.in
+++ b/setup/tools/filegen/templates/item-scaling.in
@@ -6,5 +6,4 @@ $WH.g_convertScalingFactor.SD = /*setup:itemScalingSD*/;
if ($WH.isset('$WowheadPower')) {
$WowheadPower.loadScales(3);
- $WowheadPower.loadScales(6);
}
diff --git a/setup/tools/filegen/templates/power.js.in b/setup/tools/filegen/templates/power.js.in
index f6e916f2..ce648f5a 100644
--- a/setup/tools/filegen/templates/power.js.in
+++ b/setup/tools/filegen/templates/power.js.in
@@ -90,7 +90,7 @@ if (typeof $WowheadPower == "undefined") {
},
SCALES = {
3: { url: "?data=item-scaling" },
- 6: { url: "?data=item-scaling" }
+ 6: { url: "?data=spell-scaling" }
},
LOCALES = {
0: "enus",
diff --git a/setup/tools/filegen/templates/spell-scaling.in b/setup/tools/filegen/templates/spell-scaling.in
new file mode 100644
index 00000000..75c49c11
--- /dev/null
+++ b/setup/tools/filegen/templates/spell-scaling.in
@@ -0,0 +1,5 @@
+$WH.g_convertScalingSpell.SV = /*setup:spellScalingSV*/;
+
+if ($WH.isset('$WowheadPower')) {
+ $WowheadPower.loadScales(6);
+}
diff --git a/static/js/basic.js b/static/js/basic.js
index 35d9ee3e..9a0a23ad 100644
--- a/static/js/basic.js
+++ b/static/js/basic.js
@@ -1224,6 +1224,24 @@ if (!$WH.wowheadRemote) {
$WH.g_ajaxIshRequest('?data=item-scaling');
}
+// aowow - custom..ish
+$WH.g_convertScalingSpell = function(base, spellLevel, level) {
+ let scaler = $WH.g_convertScalingSpell.SV;
+
+ if (!scaler[level] || !scaler[spellLevel]) {
+ if (g_user.roles & U_GROUP_ADMIN) {
+ alert('There are no spell scaling values for level ' + level);
+ }
+
+ return base;
+ }
+
+ return base *= scaler[level] / scaler[spellLevel];
+}
+
+if(!$WH.wowheadRemote)
+ $WH.g_ajaxIshRequest('?data=spell-scaling');
+
$WH.g_getDataSource = function() {
if ($WH.isset('g_pageInfo')) {
switch (g_pageInfo.type) {
@@ -1330,6 +1348,14 @@ $WH.g_setJsonItemLevel = function (json, level) {
}
};
+$WH.g_setJsonSpellLevel = function(json, level)
+{
+ if (!json.scadist)
+ return;
+
+ $WH.cO(json, $WH.g_convertScalingSpell(level, json.scadist));
+}
+
$WH.g_setTooltipLevel = function(tooltip, level) {
var _ = typeof tooltip;
@@ -1359,7 +1385,8 @@ $WH.g_setTooltipLevel = function(tooltip, level) {
// Update the tooltip
if (scaDist) {
- if (!tooltip.match(//g)) { // Not a spell
+ // if (!tooltip.match(//g)) { // Not a spell
+ if (!tooltip.match(//g)) { // aowow - appropriated for 335a
var
scaFlags = parseInt(_[5]) || 0,
speed = tooltip.match(/(\d\.\d+)/);
@@ -1458,6 +1485,23 @@ $WH.g_setTooltipLevel = function(tooltip, level) {
return '' + prefix + '' + value + suffix + '' + br;
});
}
+ else
+ {
+ var json = {
+ scadist: scaDist
+ };
+
+ // $WH.g_setJsonSpellLevel(json, level);
+
+ // Cast time
+ // tooltip = tooltip.replace(/\d+\.\d+/, '' + json.cast);
+
+ // Spell effects
+ // aowow - custom: spell level damage calculation
+ tooltip = tooltip.replace(/\s*\d+/gi, function(_all, spellLvl, base) {
+ return '' + Math.round($WH.g_convertScalingSpell(base, parseInt(spellLvl), parseInt(level)));
+ });
+ }
}
// Points per level