Paragon: weapon-class subclass bypass for proc talents (Maelstrom Weapon any weapon)
Cross-class wildcard now also relaxes the EquippedItemSubClassMask gate on weapon-class proc talents so e.g. Maelstrom Weapon procs from any weapon a Paragon has equipped, not just the talent's stock melee subset (axe / mace / staff / fist / dagger / 2H sword/axe/mace). Three independent gates run in the proc chain; all three needed the bypass for the proc to actually fire: - Player::HasItemFitToSpellRequirements -- talent-attach check at item-equip / login time. Without this the passive talent aura never even applies for a Paragon wielding a non-stock weapon. - Player::CheckAttackFitToAuraRequirement -- per-swing match the proc engine uses to decide whether attackType + weapon is compatible with the aura's EquippedItemClass / SubClassMask. - Aura::IsProcTriggeredOnEvent (SpellAuras.cpp) -- per-event proc evaluator that calls Item::IsFitToSpellRequirements again, independently of the previous two. Was the proc-killing gate before this commit: talent attached, swing matched, but this evaluator returned 0 charges for any weapon outside the stock subclass mask, so no stack was ever applied. All three bypasses are gated on: - IsParagonWildcardCaller(this) (player class 12 + config flag Paragon.WildcardFamilyMatching = 1). - spellInfo->EquippedItemClass == ITEM_CLASS_WEAPON. ARMOR-class gates (shield) are deliberately left alone -- shield-required talents (Shield Specialization, Shield Block, etc.) still need an actual shield equipped. Each bypass also requires *some* weapon to be in the relevant slot (MAINHAND / OFFHAND / RANGED). Unarmed Paragons do not auto-activate every weapon-gated talent in the game. Net effect for Paragon characters with Maelstrom Weapon talented: proc fires from any melee weapon -- 1H sword / polearm / spear / fist / dagger / staff / 2H weapons / axes / maces. Stock Shamans and every other non-Paragon class are unchanged. Caveat (not addressed by this commit): the talent's stock ProcFlags (0xC00014) only fire on melee swings + melee abilities. Ranged auto-attacks (bow / gun / crossbow / wand) fire PROC_FLAG_DONE_RANGED_AUTO_ATTACK (0x40), which the proc engine never matches against this talent, so the new weapon-subclass bypass is moot for those weapons. Adding ranged-auto-attack support would require a Paragon-only ProcFlags expansion at the proc engine layer; deferred until requested. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -7143,6 +7143,16 @@ bool Player::CheckAttackFitToAuraRequirement(WeaponAttackType attackType, AuraEf
|
||||
if (spellInfo->EquippedItemClass == -1)
|
||||
return true;
|
||||
|
||||
// Fractured / Paragon: cross-class wildcard relaxes weapon-class subclass
|
||||
// gates on per-swing proc matches. A Paragon's talent list spans every
|
||||
// class so a stock weapon-subclass mask (e.g. Maelstrom Weapon's
|
||||
// axe/mace/staff/fist/dagger restriction) excludes weapons the player
|
||||
// can legitimately wield. Accept any equipped weapon in attackType slot
|
||||
// when listener is a Paragon AND the spell gates on ITEM_CLASS_WEAPON;
|
||||
// ITEM_CLASS_ARMOR (shield) gates still enforce the original mask.
|
||||
if (spellInfo->EquippedItemClass == ITEM_CLASS_WEAPON && IsParagonWildcardCaller(this))
|
||||
return GetWeaponForAttack(attackType, true) != nullptr;
|
||||
|
||||
Item* item = GetWeaponForAttack(attackType, true);
|
||||
if (!item || !item->IsFitToSpellRequirements(spellInfo))
|
||||
return false;
|
||||
@@ -12581,6 +12591,27 @@ bool Player::HasItemFitToSpellRequirements(SpellInfo const* spellInfo, Item cons
|
||||
if (spellInfo->EquippedItemClass < 0)
|
||||
return true;
|
||||
|
||||
// Fractured / Paragon: cross-class wildcard relaxes weapon-class subclass
|
||||
// gates so passive talent auras (e.g. Maelstrom Weapon talents 51528-51532)
|
||||
// attach for any equipped weapon, not just the talent's restrictive
|
||||
// subclass mask. Mirrors CheckAttackFitToAuraRequirement so per-swing
|
||||
// proc match agrees with talent-attach time. Still requires *some* weapon
|
||||
// to be equipped (otherwise unarmed Paragons would auto-activate every
|
||||
// weapon-gated talent in the game). ITEM_CLASS_ARMOR (shield) is left
|
||||
// alone -- shield-gated talents still need an actual shield.
|
||||
if (spellInfo->EquippedItemClass == ITEM_CLASS_WEAPON && IsParagonWildcardCaller(this))
|
||||
{
|
||||
for (uint8 i = EQUIPMENT_SLOT_MAINHAND; i < EQUIPMENT_SLOT_TABARD; ++i)
|
||||
if (Item const* item = GetUseableItemByPos(INVENTORY_SLOT_BAG_0, i))
|
||||
if (item != ignoreItem)
|
||||
if (ItemTemplate const* proto = item->GetTemplate())
|
||||
if (proto->Class == ITEM_CLASS_WEAPON)
|
||||
return true;
|
||||
// No weapon equipped at all -- fall through to stock logic, which
|
||||
// returns false for passive talent auras (correct: an unarmed
|
||||
// Paragon shouldn't have weapon talents active).
|
||||
}
|
||||
|
||||
// scan other equipped items for same requirements (mostly 2 daggers/etc)
|
||||
// for optimize check 2 used cases only
|
||||
switch (spellInfo->EquippedItemClass)
|
||||
|
||||
@@ -2251,8 +2251,26 @@ uint8 Aura::GetProcEffectMask(AuraApplication* aurApp, ProcEventInfo& eventInfo,
|
||||
item = target->ToPlayer()->GetUseableItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND);
|
||||
}
|
||||
|
||||
if (!item || item->IsBroken() || !item->IsFitToSpellRequirements(GetSpellInfo()))
|
||||
if (!item || item->IsBroken())
|
||||
return 0;
|
||||
if (!item->IsFitToSpellRequirements(GetSpellInfo()))
|
||||
{
|
||||
// Fractured / Paragon: cross-class wildcard relaxes weapon-
|
||||
// class subclass gates on per-event proc evaluation. This
|
||||
// mirrors Player::CheckAttackFitToAuraRequirement and
|
||||
// Player::HasItemFitToSpellRequirements -- without this
|
||||
// third bypass, the talent attaches (HasItemFit lets it),
|
||||
// the per-swing match accepts the weapon (CheckAttackFit
|
||||
// lets it), but IsProcTriggeredOnEvent still kills the
|
||||
// proc here for any weapon outside the talent's stock
|
||||
// subclass mask (e.g. Maelstrom Weapon on a Paragon
|
||||
// wielding a 1H sword or polearm). Restricted to
|
||||
// ITEM_CLASS_WEAPON so shield-gated talents still need
|
||||
// an actual shield.
|
||||
if (!(GetSpellInfo()->EquippedItemClass == ITEM_CLASS_WEAPON
|
||||
&& IsParagonWildcardCaller(target)))
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user