Paragon: AE/TE currency, Character Advancement commit/reset, panel SQL

- mod-paragon: Paragon_Essence addon channel (PARAA), commit queue, resets,
  spell chain learn with passive child tracking, silence-window hints for
  cascade learns, trainer exemptions for pet/portal trainers
- SQL: character_paragon_panel_* tables, paragon_spell_ae_cost world data
- Core: Player Paragon class talent learn hook; Trainer skip for Paragon
  where appropriate
- Ignore local build-worldserver.log

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Docker Build
2026-05-08 21:42:39 -04:00
parent e2bed00b5c
commit 203356aca8
7 changed files with 1500 additions and 17 deletions
@@ -208,6 +208,46 @@ namespace Trainer
bool Trainer::IsTrainerValidForPlayer(Player const* player) const
{
// Paragon (class 12) learns class abilities exclusively through the
// Character Advancement panel (mod-paragon). Generic class trainers
// refuse interaction. Pet trainers, mount/profession trainers, and
// specialized portal/teleport trainers (mage portal NPCs) stay valid:
// - Pet trainers: pet-skill purchases for hunter pets aren't covered
// by the panel and should remain trainer-driven.
// - Portal/teleport trainers: identified at runtime as a Class-type
// trainer whose spells are ALL TELEPORT_UNITS or TRANS_DOOR
// effects. The big general mage trainer fails this check (it
// teaches Fireball, Frostbolt, etc.) and is correctly blocked.
if (player && player->getClass() == CLASS_PARAGON
&& GetTrainerType() == Type::Class
&& !_spells.empty())
{
bool onlyPortalsAndTeleports = true;
for (Spell const& s : _spells)
{
SpellInfo const* info = sSpellMgr->GetSpellInfo(s.SpellId);
if (!info)
continue;
bool isPortalOrTeleport = false;
for (SpellEffectInfo const& eff : info->GetEffects())
{
if (eff.Effect == SPELL_EFFECT_TELEPORT_UNITS
|| eff.Effect == SPELL_EFFECT_TRANS_DOOR)
{
isPortalOrTeleport = true;
break;
}
}
if (!isPortalOrTeleport)
{
onlyPortalsAndTeleports = false;
break;
}
}
if (!onlyPortalsAndTeleports)
return false;
}
if (!GetTrainerRequirement())
return true;
+4 -1
View File
@@ -14052,7 +14052,10 @@ void Player::LearnTalent(uint32 talentId, uint32 talentRank, bool command /*= fa
return;
// xinef: prevent learn talent for different class (cheating)
if ((getClassMask() & talentTabInfo->ClassMask) == 0)
// mod-paragon: Paragon (class 12) can spec into any class's talent tree
// via the Character Advancement panel; bypass the class-mask check.
if (getClass() != CLASS_PARAGON
&& (getClassMask() & talentTabInfo->ClassMask) == 0)
return;
// xinef: find current talent rank