Profiler/Talents

* fix building talent string for hunter pets.
   the alternate spells (e.g. Dash & Swoop) must both be included
 * align talent order in build scripts talenticons, talentcalc with
   Profiler talent string builder
 * fix Shamans gaining 5% Parry by talent Spirit Weapons
 * cleanup
This commit is contained in:
Sarjuuk
2025-10-19 23:19:51 +02:00
parent 6a32c770cd
commit 2e029f3d96
6 changed files with 65 additions and 54 deletions

View File

@@ -625,7 +625,16 @@ class Profiler
continue; continue;
} }
$_ = DB::Aowow()->selectCol('SELECT `spell` AS ARRAY_KEY, MAX(IF(`spell` IN (?a), `rank`, 0)) FROM ?_talents WHERE `class` = 0 AND `petTypeMask` = ?d GROUP BY `row`, `col` ORDER BY `row`, `col` ASC', $petSpells ?: [0], 1 << $morePet['type']); $_ = DB::Aowow()->selectCol(
'SELECT IFNULL(t2.`rank`, 0)
FROM ?_talents t1
LEFT JOIN (SELECT `id`, `rank` FROM ?_talents WHERE `spell` IN (?a)) t2 ON t2.`id` = t1.`id`
WHERE `class` = 0 AND `petTypeMask` = ?d
GROUP BY t1.`id`
ORDER BY t1.`row`, t1.`col`, t1.`id` ASC',
$petSpells ?: [0], 1 << $morePet['type']
);
$pet = array( $pet = array(
'id' => $petGuid, 'id' => $petGuid,
'owner' => $profileId, 'owner' => $profileId,

View File

@@ -230,56 +230,48 @@ class SpellList extends DBTypeList
// <statistic> => [123, 'add'] // <statistic> => [123, 'add']
// <statistic> => <value> ... as from getStatGain() // <statistic> => <value> ... as from getStatGain()
$modXByStat = function (&$arr, $stat, $pts) use (&$mv) $modXByStat = function (array &$arr, int $srcStat, ?string $destStat, int $pts) : void
{ {
if ($mv == STAT_STRENGTH) match ($srcStat)
$arr[$stat ?: 'str'] = [$pts / 100, 'percentOf', 'str']; {
else if ($mv == STAT_AGILITY) STAT_STRENGTH => $arr[$destStat ?: 'str'] = [$pts / 100, 'percentOf', 'str'],
$arr[$stat ?: 'agi'] = [$pts / 100, 'percentOf', 'agi']; STAT_AGILITY => $arr[$destStat ?: 'agi'] = [$pts / 100, 'percentOf', 'agi'],
else if ($mv == STAT_STAMINA) STAT_STAMINA => $arr[$destStat ?: 'sta'] = [$pts / 100, 'percentOf', 'sta'],
$arr[$stat ?: 'sta'] = [$pts / 100, 'percentOf', 'sta']; STAT_INTELLECT => $arr[$destStat ?: 'int'] = [$pts / 100, 'percentOf', 'int'],
else if ($mv == STAT_INTELLECT) STAT_SPIRIT => $arr[$destStat ?: 'spi'] = [$pts / 100, 'percentOf', 'spi']
$arr[$stat ?: 'int'] = [$pts / 100, 'percentOf', 'int']; };
else if ($mv == STAT_SPIRIT)
$arr[$stat ?: 'spi'] = [$pts / 100, 'percentOf', 'spi'];
}; };
$modXBySchool = function (&$arr, $stat, $val, $mask = null) use (&$mv) $modXBySchool = function (array &$arr, int $srcStat, string $destStat, array|int $val) : void
{ {
if (($mask ?: $mv) & (1 << SPELL_SCHOOL_HOLY)) if ($srcStat & (1 << SPELL_SCHOOL_HOLY))
$arr['hol'.$stat] = is_array($val) ? $val : [$val / 100, 'percentOf', 'hol'.$stat]; $arr['hol'.$destStat] = is_array($val) ? $val : [$val / 100, 'percentOf', 'hol'.$destStat];
if (($mask ?: $mv) & (1 << SPELL_SCHOOL_FIRE)) if ($srcStat & (1 << SPELL_SCHOOL_FIRE))
$arr['fir'.$stat] = is_array($val) ? $val : [$val / 100, 'percentOf', 'fir'.$stat]; $arr['fir'.$destStat] = is_array($val) ? $val : [$val / 100, 'percentOf', 'fir'.$destStat];
if (($mask ?: $mv) & (1 << SPELL_SCHOOL_NATURE)) if ($srcStat & (1 << SPELL_SCHOOL_NATURE))
$arr['nat'.$stat] = is_array($val) ? $val : [$val / 100, 'percentOf', 'nat'.$stat]; $arr['nat'.$destStat] = is_array($val) ? $val : [$val / 100, 'percentOf', 'nat'.$destStat];
if (($mask ?: $mv) & (1 << SPELL_SCHOOL_FROST)) if ($srcStat & (1 << SPELL_SCHOOL_FROST))
$arr['fro'.$stat] = is_array($val) ? $val : [$val / 100, 'percentOf', 'fro'.$stat]; $arr['fro'.$destStat] = is_array($val) ? $val : [$val / 100, 'percentOf', 'fro'.$destStat];
if (($mask ?: $mv) & (1 << SPELL_SCHOOL_SHADOW)) if ($srcStat & (1 << SPELL_SCHOOL_SHADOW))
$arr['sha'.$stat] = is_array($val) ? $val : [$val / 100, 'percentOf', 'sha'.$stat]; $arr['sha'.$destStat] = is_array($val) ? $val : [$val / 100, 'percentOf', 'sha'.$destStat];
if (($mask ?: $mv) & (1 << SPELL_SCHOOL_ARCANE)) if ($srcStat & (1 << SPELL_SCHOOL_ARCANE))
$arr['arc'.$stat] = is_array($val) ? $val : [$val / 100, 'percentOf', 'arc'.$stat]; $arr['arc'.$destStat] = is_array($val) ? $val : [$val / 100, 'percentOf', 'arc'.$destStat];
}; };
$jsonStat = function ($stat) $jsonStat = function (int $statId) : string
{ {
if ($stat == STAT_STRENGTH) return match ($statId)
return 'str'; {
if ($stat == STAT_AGILITY) STAT_STRENGTH => Stat::getJsonString(Stat::STRENGTH),
return 'agi'; STAT_AGILITY => Stat::getJsonString(Stat::AGILITY),
if ($stat == STAT_STAMINA) STAT_STAMINA => Stat::getJsonString(Stat::STAMINA),
return 'sta'; STAT_INTELLECT => Stat::getJsonString(Stat::INTELLECT),
if ($stat == STAT_INTELLECT) STAT_SPIRIT => Stat::getJsonString(Stat::SPIRIT)
return 'int'; };
if ($stat == STAT_SPIRIT)
return 'spi';
}; };
foreach ($this->iterate() as $id => $__) foreach ($this->iterate() as $id => $__)
{ {
// kept for reference - if (($this->getField('cuFlags') & SPELL_CU_TALENTSPELL) && $id != 20711)
if (!($this->getField('attributes0') & SPELL_ATTR0_PASSIVE))
continue;
// Shaman - Spirit Weapons (16268) (parry is normaly stored in g_statistics) // Shaman - Spirit Weapons (16268) (parry is normaly stored in g_statistics)
// i should recurse into SPELL_EFFECT_LEARN_SPELL and apply SPELL_EFFECT_PARRY from there // i should recurse into SPELL_EFFECT_LEARN_SPELL and apply SPELL_EFFECT_PARRY from there
if ($id == 16268) if ($id == 16268)
@@ -288,6 +280,9 @@ class SpellList extends DBTypeList
continue; continue;
} }
if (!($this->getField('attributes0') & SPELL_ATTR0_PASSIVE))
continue;
for ($i = 1; $i < 4; $i++) for ($i = 1; $i < 4; $i++)
{ {
$pts = $this->calculateAmountForCurrent($i)[1]; $pts = $this->calculateAmountForCurrent($i)[1];
@@ -311,18 +306,18 @@ class SpellList extends DBTypeList
if ($mv == (1 << SPELL_SCHOOL_NORMAL)) if ($mv == (1 << SPELL_SCHOOL_NORMAL))
$data[$id]['armor'] = [$pts / 100, 'percentOf', ['armor', 0]]; $data[$id]['armor'] = [$pts / 100, 'percentOf', ['armor', 0]];
else if ($mv) else if ($mv)
$modXBySchool($data[$id], 'res', $pts); $modXBySchool($data[$id], $mv, 'res', $pts);
break; break;
case SPELL_AURA_MOD_RESISTANCE_OF_STAT_PERCENT: case SPELL_AURA_MOD_RESISTANCE_OF_STAT_PERCENT:
// Armor only if explicitly specified // Armor only if explicitly specified
if ($mv == (1 << SPELL_SCHOOL_NORMAL)) if ($mv == (1 << SPELL_SCHOOL_NORMAL))
$data[$id]['armor'] = [$pts / 100, 'percentOf', $jsonStat($mvB)]; $data[$id]['armor'] = [$pts / 100, 'percentOf', $jsonStat($mvB)];
else if ($mv) else if ($mv)
$modXBySchool($data[$id], 'res', [$pts / 100, 'percentOf', $jsonStat($mvB)]); $modXBySchool($data[$id], $mv, 'res', [$pts / 100, 'percentOf', $jsonStat($mvB)]);
break; break;
case SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE: case SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE:
if ($mv > -1) // one stat if ($mv > -1) // one stat
$modXByStat($data[$id], null, $pts); $modXByStat($data[$id], $mv, null, $pts);
else if ($mv < 0) // all stats else if ($mv < 0) // all stats
for ($iMod = ITEM_MOD_AGILITY; $iMod <= ITEM_MOD_STAMINA; $iMod++) for ($iMod = ITEM_MOD_AGILITY; $iMod <= ITEM_MOD_STAMINA; $iMod++)
if ($idx = Stat::getIndexFrom(Stat::IDX_ITEM_MOD, $iMod)) if ($idx = Stat::getIndexFrom(Stat::IDX_ITEM_MOD, $iMod))
@@ -331,19 +326,19 @@ class SpellList extends DBTypeList
break; break;
case SPELL_AURA_MOD_SPELL_DAMAGE_OF_STAT_PERCENT: case SPELL_AURA_MOD_SPELL_DAMAGE_OF_STAT_PERCENT:
$mv = $mv ?: SPELL_MAGIC_SCHOOLS; $mv = $mv ?: SPELL_MAGIC_SCHOOLS;
$modXBySchool($data[$id], 'spldmg', [$pts / 100, 'percentOf', $jsonStat($mvB)]); $modXBySchool($data[$id], $mv, 'spldmg', [$pts / 100, 'percentOf', $jsonStat($mvB)]);
break; break;
case SPELL_AURA_MOD_RANGED_ATTACK_POWER_OF_STAT_PERCENT: case SPELL_AURA_MOD_RANGED_ATTACK_POWER_OF_STAT_PERCENT:
$modXByStat($data[$id], 'rgdatkpwr', $pts); $modXByStat($data[$id], $mv, 'rgdatkpwr', $pts);
break; break;
case SPELL_AURA_MOD_ATTACK_POWER_OF_STAT_PERCENT: case SPELL_AURA_MOD_ATTACK_POWER_OF_STAT_PERCENT:
$modXByStat($data[$id], 'mleatkpwr', $pts); $modXByStat($data[$id], $mv, 'mleatkpwr', $pts);
break; break;
case SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT: case SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT:
$modXByStat($data[$id], 'splheal', $pts); $modXByStat($data[$id], $mv, 'splheal', $pts);
break; break;
case SPELL_AURA_MOD_MANA_REGEN_FROM_STAT: case SPELL_AURA_MOD_MANA_REGEN_FROM_STAT:
$modXByStat($data[$id], 'manargn', $pts); $modXByStat($data[$id], $mv, 'manargn', $pts);
break; break;
case SPELL_AURA_MOD_MANA_REGEN_INTERRUPT: case SPELL_AURA_MOD_MANA_REGEN_INTERRUPT:
$data[$id]['icmanargn'] = [$pts / 100, 'percentOf', 'oocmanargn']; $data[$id]['icmanargn'] = [$pts / 100, 'percentOf', 'oocmanargn'];
@@ -351,7 +346,7 @@ class SpellList extends DBTypeList
case SPELL_AURA_MOD_SPELL_CRIT_CHANCE: case SPELL_AURA_MOD_SPELL_CRIT_CHANCE:
case SPELL_AURA_MOD_SPELL_CRIT_CHANCE_SCHOOL: case SPELL_AURA_MOD_SPELL_CRIT_CHANCE_SCHOOL:
$mv = $mv ?: SPELL_MAGIC_SCHOOLS; $mv = $mv ?: SPELL_MAGIC_SCHOOLS;
$modXBySchool($data[$id], 'splcritstrkpct', [$pts, 'add']); $modXBySchool($data[$id], $mv, 'splcritstrkpct', [$pts, 'add']);
if (($mv & SPELL_MAGIC_SCHOOLS) == SPELL_MAGIC_SCHOOLS) if (($mv & SPELL_MAGIC_SCHOOLS) == SPELL_MAGIC_SCHOOLS)
$data[$id]['splcritstrkpct'] = [$pts, 'add']; $data[$id]['splcritstrkpct'] = [$pts, 'add'];
break; break;
@@ -392,7 +387,7 @@ class SpellList extends DBTypeList
$data[$id]['health'] = [$pts / 100, 'percentOf', 'health']; $data[$id]['health'] = [$pts / 100, 'percentOf', 'health'];
break; break;
case SPELL_AURA_MOD_BASE_HEALTH_PCT: // only Tauren - Endurance (20550) ... if you are looking for something elegant, look away! case SPELL_AURA_MOD_BASE_HEALTH_PCT: // only Tauren - Endurance (20550) ... if you are looking for something elegant, look away!
$data[$id]['health'] = [$pts / 100, 'functionOf', '$function(p) { return g_statistics.combo[p.classs][p.level][5]; }']; $data[$id]['health'] = [$pts / 100, 'functionOf', '$(x) => g_statistics.combo[x.classs][x.level][5]'];
break; break;
case SPELL_AURA_MOD_SHIELD_BLOCKVALUE_PCT: case SPELL_AURA_MOD_SHIELD_BLOCKVALUE_PCT:
$data[$id]['block'] = [$pts / 100, 'percentOf', 'block']; $data[$id]['block'] = [$pts / 100, 'percentOf', 'block'];
@@ -404,7 +399,7 @@ class SpellList extends DBTypeList
break; break;
case SPELL_AURA_MOD_SPELL_DAMAGE_OF_ATTACK_POWER: case SPELL_AURA_MOD_SPELL_DAMAGE_OF_ATTACK_POWER:
$mv = $mv ?: SPELL_MAGIC_SCHOOLS; $mv = $mv ?: SPELL_MAGIC_SCHOOLS;
$modXBySchool($data[$id], 'spldmg', [$pts / 100, 'percentOf', 'mleatkpwr']); $modXBySchool($data[$id], $mv, 'spldmg', [$pts / 100, 'percentOf', 'mleatkpwr']);
break; break;
case SPELL_AURA_MOD_SPELL_HEALING_OF_ATTACK_POWER: case SPELL_AURA_MOD_SPELL_HEALING_OF_ATTACK_POWER:
$data[$id]['splheal'] = [$pts / 100, 'percentOf', 'mleatkpwr']; $data[$id]['splheal'] = [$pts / 100, 'percentOf', 'mleatkpwr'];

View File

@@ -1919,7 +1919,7 @@ CREATE TABLE `aowow_profiler_pets` (
`family` tinyint(3) unsigned DEFAULT NULL, `family` tinyint(3) unsigned DEFAULT NULL,
`npc` smallint(5) unsigned DEFAULT NULL, `npc` smallint(5) unsigned DEFAULT NULL,
`displayId` smallint(5) unsigned DEFAULT NULL, `displayId` smallint(5) unsigned DEFAULT NULL,
`talents` varchar(20) DEFAULT NULL, `talents` varchar(22) DEFAULT NULL,
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
KEY `owner` (`owner`), KEY `owner` (`owner`),
CONSTRAINT `FK_pr_pets` FOREIGN KEY (`owner`) REFERENCES `aowow_profiler_profiles` (`id`) ON DELETE CASCADE ON UPDATE CASCADE CONSTRAINT `FK_pr_pets` FOREIGN KEY (`owner`) REFERENCES `aowow_profiler_profiles` (`id`) ON DELETE CASCADE ON UPDATE CASCADE

View File

@@ -0,0 +1,7 @@
ALTER TABLE `aowow_profiler_pets`
MODIFY COLUMN `talents` varchar(22) DEFAULT NULL;
UPDATE `aowow_dbversion` SET `build` = CONCAT(IFNULL(`build`, ''), ' talenticons talentcalc');
-- flag all hunters as requiring update
UPDATE `aowow_profiler_profiles` SET `flags` = `flags` | 16, `lastupdated` = 0 WHERE `class` = 3 AND `realmGUID` IS NOT NULL;

View File

@@ -100,7 +100,7 @@ CLISetup::registerSetup("build", new class extends SetupScript
LOWER(SUBSTRING_INDEX(si.`iconPath`, "\\\\", -1)) AS "iconString" LOWER(SUBSTRING_INDEX(si.`iconPath`, "\\\\", -1)) AS "iconString"
FROM dbc_talent t, dbc_spell s, dbc_spellicon si FROM dbc_talent t, dbc_spell s, dbc_spellicon si
WHERE si.`id` = s.`iconId` AND t.`tabId`= ?d AND s.`id` = t.`rank1` WHERE si.`id` = s.`iconId` AND t.`tabId`= ?d AND s.`id` = t.`rank1`
ORDER BY t.`row`, t.`column`', ORDER BY t.`row`, t.`column`, t.`id` ASC',
$tabs[$tabIdx]['id'] $tabs[$tabIdx]['id']
); );

View File

@@ -85,7 +85,7 @@ CLISetup::registerSetup("build", new class extends SetupScript
JOIN dbc_talent t ON t.`rank1` = s.`id` JOIN dbc_talent t ON t.`rank1` = s.`id`
JOIN dbc_talenttab tt ON tt.`id` = t.`tabId` JOIN dbc_talenttab tt ON tt.`id` = t.`tabId`
WHERE tt.?# = ?d AND tt.`tabNumber` = ?d WHERE tt.?# = ?d AND tt.`tabNumber` = ?d
ORDER BY t.`row`, t.`column` ASC, s.`id` DESC', ORDER BY t.`row`, t.`column`, t.`id` ASC',
$ttField, $searchMask, $tabIdx); $ttField, $searchMask, $tabIdx);
if (empty($icons)) if (empty($icons))