The numbers are likely based on tiered formulas (i.e. from level 1-60, one formula, from level 60-70, another, etc). Considering you are managing an addon, I'd recommend the approach that Wowhead takes. Wowhead doesn't calculate these values on the fly. They save the values on the server-side and reuse them.
Considering Wowhead is a reliable source for in-game data, I'd recommend simply scraping your values from Wowhead and using those.
UPDATED
To expand on the tables in the link, I dug into the Wowhead code just deep enough to determine how some of these values are used for Greater Healing Wave. Note that all of the data and functions used are visible in the $WH
JavaScript object.
The link has 2 JSON objects:
- The
$WH.g_convertScalingSpell.SD
object lists scaling values for different distribution types. Each element is an array with 15 values.
- The
$WH.g_convertScalingSpell.SV
object lists scaling values for different levels. Each element is an array with 12 values.
The function where the magic happens is the $WH.g_convertScalingSpell
function. Basically, it accepts a level and a scaling type, then uses the tables to match up the two and calculate the final value. A quick glance at the $WH
object shows there are a couple more g_convert
functions for different values.
While I can't speak on behalf of what all of the values of the scaling tables represent, I can expose the formula used in the $WH.g_convertScalingSpell
function.
a = $WH.g_convertScalingSpell.SD[ distribution_type ]
b = $WH.g_convertScalingSpell.SV[ level ]
c = b[a[3] - 1] * (min(level, a[14]) + (a[13] * max(0, level - a[14]))) / level
Then, using c
, an object is built out with multiple min, max, and avg values. Only the first min and max values are visible in Greater Healing Wave's tooltip. The value i
displayed below is evaluated at 0, 1, and 2. If you are only interested in the first object that is built, you can omit the i
entirely, as it's value is 0.
avg = a[4 + i] * c * (a[1] > 0 ? cast / a[1] : 1)
min = round(avg) - floor(avg * a[7 + i] / 2)
max = round(avg) + floor(avg * a[7 + i] / 2)
And if you are curious, the cast
value (casting time in milliseconds) comes from this formula, and is only rounded after calculations, prior to displaying the value to the user:
cast = min(a[1], a[1] > 0 && level > 1 ? a[0] + (((level - 1) * (a[1] - a[0])) / (a[2] - 1)) : a[0])
When applying this, you have to know the desired distribution type. This is found in an HTML comment in the tooltip's markup, starting with a question mark. So, to show the example of Greater Healing Wave, the HTML comment is <!--?77472:68:85:85:355:0:1000-->
. While I do not know what all of the values are, I know the first few are spellId
, minLevel
, maxLevel
, defaultLevel
, and distScale
.
Let's do the math:
a = $WH.g_convertScalingSpell.SD[355]
= [3000, 3000, 20, 7, 9.564, 0, 0, 0.133, 0, 0, 0, 0, 0, 1, 0]
b = $WH.g_convertScalingSpell.SV[85]
= [1125.23, 1029.49, 1125.23, 1125.23, 945.189, 1125.23, 1004.49, 937.33, 962.336, 0, 986.626, 443]
c = b[a[3] - 1] * (min(level, a[14]) + (a[13] * max(0, level - a[14]))) / level
= b[7 - 1] * (min(85, 0 ) + (1 * max(0, 85 - 0 ))) / 85
= b[6] * (min(85, 0 ) + (1 * max(0, 85 ))) / 85
= 1004.49 * (min(85, 0) + (1 * max(0, 85))) / 85
= 1004.49 * (0 + (1 * 85)) / 85
= 1004.49 * 85 / 85
= 1004.49
And then the spell values:
cast = min(a[1], a[1] > 0 && level > 1 ? a[0] + (((level - 1) * (a[1] - a[0])) / (a[2] - 1)) : a[0])
= min(3000, 3000 > 0 && 85 > 1 ? 3000 + (((85 - 1) * (3000 - 3000)) / (20 - 1)) : 3000)
= min(3000, true && true ? 3000 + ((84 * 0) / (19)) : 3000)
= min(3000, true ? 3000 + (0 / 19) : 3000)
= min(3000, 3000 + 0)
= 3000
avg = a[4 + i] * c * (a[1] > 0 ? cast / a[1] : 1)
= a[4 + 0] * c * (a[1] > 0 ? 3000 / a[1] : 1)
= 9.564 * c * (3000 > 0 ? 3000 / 3000 : 1)
= 9.564 * c * (true ? 1 : 1)
= 9.564 * 1004.49
= 9606.942360000001
min = round(avg) - floor(avg * a[7 + i] / 2)
= round(8964.62412) - floor(9606.942360000001 * a[7 + 0] / 2)
= 9607 - floor(9606.942360000001 * 0.133 / 2)
= 9607 - floor(1277.7233338800002 / 2)
= 9607 - floor(638.8616669400001 )
= 9607 - 638
= 8969
max = round(avg) + floor(avg * a[7 + i] / 2)
= 9607 + 638
= 10245
Hope this helps!