Jump to content

Lightguard

Members
  • Posts

    208
  • Joined

  • Last visited

    Never
  • Donations

    0.00 GBP 

Posts posted by Lightguard

  1. As you may have already discovered, wowhead says that "Requires You to be standing next to Bloodmage Laurith at the Bloodspore Plains."

    You also get this message ingame if you try to cast it while not standing near a gameobject that it needs.

    It is due to a field called RequireSpellFocus that is defined for this spell in Spell.dbc.

    The check related to this you'll find in Spell::CheckItems() in Spell.cpp but you might need to add the gameobject for it on the right place to solve the problem. Anyway to show how it actually works i paste the code here:

        // check spell focus object
       if(m_spellInfo->RequiresSpellFocus)
       {
           CellPair p(MaNGOS::ComputeCellPair(m_caster->GetPositionX(), m_caster->GetPositionY()));
           Cell cell(p);
           cell.data.Part.reserved = ALL_DISTRICT;
    
           GameObject* ok = NULL;
           MaNGOS::GameObjectFocusCheck go_check(m_caster,m_spellInfo->RequiresSpellFocus);
           MaNGOS::GameObjectSearcher<MaNGOS::GameObjectFocusCheck> checker(m_caster, ok, go_check);
    
           TypeContainerVisitor<MaNGOS::GameObjectSearcher<MaNGOS::GameObjectFocusCheck>, GridTypeMapContainer > object_checker(checker);
           CellLock<GridReadGuard> cell_lock(cell, p);
           cell_lock->Visit(cell_lock, object_checker, *m_caster->GetMap());
    
           if(!ok)
               return SPELL_FAILED_REQUIRES_SPELL_FOCUS;
    
           focusObject = ok;                                   // game object found in range
       }

    Well, finding this will still not solve your problem. If you don't have you'll probably have to place the gamobject there, but you still don't have the id so let's take a look at the code that 'defines' the gamobject to be searched. It is actaully a searcher class:

        class GameObjectFocusCheck
       {
           public:
               GameObjectFocusCheck(Unit const* unit,uint32 focusId) : i_unit(unit), i_focusId(focusId) {}
               bool operator()(GameObject* go) const
               {
                   if(go->GetGOInfo()->type != GAMEOBJECT_TYPE_SPELL_FOCUS)
                       return false;
    
                   if(go->GetGOInfo()->spellFocus.focusId != i_focusId)
                       return false;
    
                   float dist = go->GetGOInfo()->spellFocus.dist;
    
                   return go->IsWithinDistInMap(i_unit, dist);
               }
           private:
               Unit const* i_unit;
               uint32 i_focusId;
       };

    GAMEOBJET_TYPE_SPELLFOCUS = 8. This means that you'll have to search your gameobject template for a gamobject of type 8 and for the corresponding SpellFocusId which is data0 and in this case equals 1499 (from Spell.dbc).

    So, by a query like:

    SELECT entry FROM gameobject_template WHERE type=8 AND data0=1499;

    You'll surely get the gamobject that you need to place there to make the quest working as intended.

    Hopefully this solves it, and was enough detailed.

  2. What bug does the patch fix? What features does the patch add?

    - This patch would add aura SPELL_AURA_MOD_AOE_DAMAGE_AVOIDANCE

    For which repository revision was the patch created?

    - Created for revision 8076

    Is there a thread in the bug report section or at lighthouse? If yes, please add a link to the thread.

    - There was a bug report somewhere but the forum's search engine is like hell. Feint and a few other spells are using it.

    From 1176f71e200ffbc8c53edf7f041ee9bca37b75a8 Mon Sep 17 00:00:00 2001
    From: Lightguard <[email protected]>
    Date: Fri, 26 Jun 2009 23:11:01 +0200
    Subject: [PATCH] Add aura 229
    
    ---
    src/game/SpellAuras.cpp |    2 +-
    src/game/Unit.cpp       |   16 ++++++++++++++++
    2 files changed, 17 insertions(+), 1 deletions(-)
    
    diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp
    index 442da50..89913de 100644
    --- a/src/game/SpellAuras.cpp
    +++ b/src/game/SpellAuras.cpp
    @@ -279,7 +279,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS]=
        &Aura::HandleAuraPeriodicDummy,                         //226 SPELL_AURA_PERIODIC_DUMMY
        &Aura::HandlePeriodicTriggerSpellWithValue,             //227 SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE
        &Aura::HandleNoImmediateEffect,                         //228 stealth detection
    -    &Aura::HandleNULL,                                      //229 SPELL_AURA_MOD_AOE_DAMAGE_AVOIDANCE
    +    &Aura::HandleNoImmediateEffect,                         //229 SPELL_AURA_MOD_AOE_DAMAGE_AVOIDANCE implemented in Unit::SpellDamageBonus
        &Aura::HandleAuraModIncreaseMaxHealth,                  //230 Commanding Shout
        &Aura::HandleNoImmediateEffect,                         //231 SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE
        &Aura::HandleNoImmediateEffect,                         //232 SPELL_AURA_MECHANIC_DURATION_MOD           implement in Unit::CalculateSpellDuration
    diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
    index e0196c9..0accc92 100644
    --- a/src/game/Unit.cpp
    +++ b/src/game/Unit.cpp
    @@ -7903,6 +7903,14 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3
                    TakenTotalMod *= ((*i)->GetModifier()->m_amount+100.0f)/100.0f;
        }
    
    +    // Mod damage taken from AoE spells
    +    if(IsAreaOfEffectSpell(spellProto))
    +    {
    +        AuraList const& avoidAuras = pVictim->GetAurasByType(SPELL_AURA_MOD_AOE_DAMAGE_AVOIDANCE);
    +        for(AuraList::const_iterator itr = avoidAuras.begin(); itr != avoidAuras.end(); ++itr)
    +            TakenTotalMod *= ((*itr)->GetModifier()->m_amount+100.0f)/100.0f;
    +    }
    +
        // Taken/Done fixed damage bonus auras
        int32 DoneAdvertisedBenefit  = SpellBaseDamageBonus(GetSpellSchoolMask(spellProto));
        int32 TakenAdvertisedBenefit = SpellBaseDamageBonusForVictim(GetSpellSchoolMask(spellProto), pVictim);
    @@ -8746,6 +8754,14 @@ void Unit::MeleeDamageBonus(Unit *pVictim, uint32 *pdamage,WeaponAttackType attT
                TakenTotalMod *= ((*i)->GetModifier()->m_amount+100.0f)/100.0f;
        }
    
    +    // Mod damage taken from AoE spells
    +    if(spellProto && IsAreaOfEffectSpell(spellProto))
    +    {
    +        AuraList const& avoidAuras = pVictim->GetAurasByType(SPELL_AURA_MOD_AOE_DAMAGE_AVOIDANCE);
    +        for(AuraList::const_iterator itr = avoidAuras.begin(); itr != avoidAuras.end(); ++itr)
    +            TakenTotalMod *= ((*itr)->GetModifier()->m_amount+100.0f)/100.0f;
    +    }
    +
        float tmpDamage = float(int32(*pdamage) + DoneFlatBenefit) * DoneTotalMod;
    
        // apply spellmod to Done damage
    -- 
    1.6.3.2.1299.gee46c
    
    

    Patchfile

  3. "2"

    - Fixes the currently incorrect healing of the spell.

    "2"

    - 7894

    "2"

    - Didn't find any.

    diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
    index a5a7917..511704e 100644
    --- a/src/game/Unit.cpp
    +++ b/src/game/Unit.cpp
    @@ -5094,8 +5094,8 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
                    target = GetPet();
                    if (!target)
                        return false;
    +                basepoints0 = damage * 15 / 100;
                    triggered_spell_id = 54181;
    -                basepoints0 = damage * triggerAmount / 100;
                    break;
                }
                switch(dummySpell->Id)
    

    Patchfile

  4. "2"

    - This patch would add procflag death (16777216) required by a few spells like Undying Resolve.

    "2"

    - 7819

    "2"

    - Didin't find any.

    diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp
    index 7c72d2e..c8a8a09 100644
    --- a/src/game/SpellMgr.cpp
    +++ b/src/game/SpellMgr.cpp
    @@ -943,7 +943,7 @@ bool SpellMgr::IsSpellProcEventCanTriggeredBy(SpellProcEventEntry const * spellP
            return false;
    
        // Always trigger for this
    -    if (EventProcFlag & (PROC_FLAG_KILLED | PROC_FLAG_KILL | PROC_FLAG_ON_TRAP_ACTIVATION))
    +    if (EventProcFlag & (PROC_FLAG_KILLED | PROC_FLAG_KILL | PROC_FLAG_ON_TRAP_ACTIVATION | PROC_FLAG_ON_DEATH))
            return true;
    
        if (spellProcEvent)     // Exist event data
    diff --git a/src/game/SpellMgr.h b/src/game/SpellMgr.h
    index 8061dbe..bc6cb4f 100644
    --- a/src/game/SpellMgr.h
    +++ b/src/game/SpellMgr.h
    @@ -351,7 +351,9 @@ enum ProcFlags
       PROC_FLAG_ON_TRAP_ACTIVATION            = 0x00200000,    // 21 On trap activation
    
       PROC_FLAG_TAKEN_OFFHAND_HIT             = 0x00400000,    // 22 Taken off-hand melee attacks(not used)
    -   PROC_FLAG_SUCCESSFUL_OFFHAND_HIT        = 0x00800000     // 23 Successful off-hand melee attacks
    +   PROC_FLAG_SUCCESSFUL_OFFHAND_HIT        = 0x00800000,    // 23 Successful off-hand melee attacks
    +
    +   PROC_FLAG_ON_DEATH                      = 0x01000000     // 24 On caster's death
    };
    
    #define MELEE_BASED_TRIGGER_MASK (PROC_FLAG_SUCCESSFUL_MILEE_HIT        | \\
    diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
    index 5ea3681..f706bfd 100644
    --- a/src/game/Unit.cpp
    +++ b/src/game/Unit.cpp
    @@ -9411,6 +9411,7 @@ void Unit::setDeathState(DeathState s)
            // remove aurastates allowing special moves
            ClearAllReactives();
            ClearDiminishings();
    +        ProcDamageAndSpell(this, PROC_FLAG_NONE, PROC_FLAG_ON_DEATH, PROC_EX_NONE, 0);
        }
        else if(s == JUST_ALIVED)
        {
    

    Patchfile

    mysql> SELECT entry FROM wow_dbc.spell_309 WHERE ProcFlags=16777216;
    +-------+
    | entry |
    +-------+
    | 42454 | 
    | 43504 | 
    | 43546 | 
    | 44541 | 
    | 45469 | 
    | 49163 | 
    | 51915 | 
    | 52418 | 
    | 57348 | 
    | 57378 | 
    +-------+
    10 rows in set (1.36 sec)

  5. Ok, (hopefully) last version. Suggestions are welcome:)

    diff --git a/src/game/Item.cpp b/src/game/Item.cpp
    index 2d25b7f..f4acf34 100644
    --- a/src/game/Item.cpp
    +++ b/src/game/Item.cpp
    @@ -740,6 +740,10 @@ bool Item::IsFitToSpellRequirements(SpellEntry const* spellInfo) const
    {
        ItemPrototype const* proto = GetProto();
    
    +    if(spellInfo->Effect[0] == SPELL_EFFECT_ENCHANT_ITEM && ((spellInfo->EquippedItemClass == ITEM_CLASS_ARMOR && IsArmorVellum()) ||
    +      (spellInfo->EquippedItemClass == ITEM_CLASS_WEAPON && IsWeaponVellum())))
    +        return true;
    +
        if (spellInfo->EquippedItemClass != -1)                 // -1 == any item class
        {
            if(spellInfo->EquippedItemClass != int32(proto->Class))
    diff --git a/src/game/Item.h b/src/game/Item.h
    index 2f7376a..e0694e6 100644
    --- a/src/game/Item.h
    +++ b/src/game/Item.h
    @@ -221,6 +221,8 @@ class MANGOS_DLL_SPEC Item : public Object
            void DeleteFromInventoryDB();
    
            bool IsBag() const { return GetProto()->InventoryType == INVTYPE_BAG; }
    +        bool IsArmorVellum() const { return (GetProto()->Class == ITEM_CLASS_TRADE_GOODS && GetProto()->SubClass == ITEM_SUBCLASS_ARMOR_ENCHANTMENT); }
    +        bool IsWeaponVellum() const { return (GetProto()->Class == ITEM_CLASS_TRADE_GOODS && GetProto()->SubClass == ITEM_SUBCLASS_WEAPON_ENCHANTMENT); }
            bool IsBroken() const { return GetUInt32Value(ITEM_FIELD_MAXDURABILITY) > 0 && GetUInt32Value(ITEM_FIELD_DURABILITY) == 0; }
            bool CanBeTraded() const;
            void SetInTrade(bool b = true) { mb_in_trade = b; }
    diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp
    index 02ec11a..6f8f64c 100644
    --- a/src/game/Spell.cpp
    +++ b/src/game/Spell.cpp
    @@ -3526,6 +3526,18 @@ void Spell::TakeReagents()
        if (p_caster->CanNoReagentCast(m_spellInfo))
            return;
    
    +    if(m_CastItem)
    +    {
    +        for(int i=0; i<3; ++i)
    +        {
    +            if(m_spellInfo->EffectItemType[i] == m_CastItem->GetEntry())
    +            {
    +                p_caster->DestroyItemCount(m_CastItem->GetEntry(), 1, true);
    +                return;
    +            }
    +        }
    +    }
    +
        for(uint32 x=0;x<8;x++)
        {
            if(m_spellInfo->Reagent[x] <= 0)
    @@ -4336,6 +4348,23 @@ SpellCastResult Spell::CheckCast(bool strict)
                        return SPELL_FAILED_BAD_TARGETS;
                    break;
                }
    +            case SPELL_EFFECT_ENCHANT_ITEM:
    +            {
    +                if(m_spellInfo->EffectItemType[i] && m_targets.getItemTarget())
    +                {
    +                    if(m_targets.getItemTarget()->IsWeaponVellum() || m_targets.getItemTarget()->IsArmorVellum())
    +                    {
    +                         ItemPosCountVec dest;
    +                         uint8 msg = ((Player*)m_caster)->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, m_spellInfo->EffectItemType[i], 1 );
    +                         if(msg != EQUIP_ERR_OK)
    +                         {
    +                            ((Player*)m_caster)->SendEquipError( msg, NULL, NULL );
    +                            return SPELL_FAILED_DONT_REPORT;
    +                         }
    +                    }
    +                }
    +                break;
    +            }
                default:break;
            }
        }
    @@ -4806,11 +4835,13 @@ SpellCastResult Spell::CheckItems()
    
        Player* p_caster = (Player*)m_caster;
    
    +    bool isNoReagentReqCast = m_CastItem ? m_CastItem->GetEntry() == m_spellInfo->EffectItemType[0] : false;
    +
        // cast item checks
        if(m_CastItem)
        {
            uint32 itemid = m_CastItem->GetEntry();
    -        if( !p_caster->HasItemCount(itemid,1) )
    +        if( !p_caster->HasItemCount(itemid,1) && !isNoReagentReqCast)
                return SPELL_FAILED_ITEM_NOT_READY;
    
            ItemPrototype const *proto = m_CastItem->GetProto();
    @@ -4883,7 +4914,7 @@ SpellCastResult Spell::CheckItems()
            if(!m_targets.getItemTarget())
                return SPELL_FAILED_ITEM_GONE;
    
    -        if(!m_targets.getItemTarget()->IsFitToSpellRequirements(m_spellInfo))
    +        if(!m_targets.getItemTarget()->IsFitToSpellRequirements(m_spellInfo) && !isNoReagentReqCast)
                return SPELL_FAILED_EQUIPPED_ITEM_CLASS;
        }
        // if not item target then required item must be equipped
    @@ -4915,7 +4946,7 @@ SpellCastResult Spell::CheckItems()
        }
    
        // check reagents (ignore triggered spells with reagents processed by original spell) and special reagent ignore case.
    -    if (!m_IsTriggeredSpell && !p_caster->CanNoReagentCast(m_spellInfo))
    +    if (!m_IsTriggeredSpell && !p_caster->CanNoReagentCast(m_spellInfo) && !isNoReagentReqCast)
        {
            for(uint32 i=0;i<8;++i)
            {
    @@ -4979,7 +5010,7 @@ SpellCastResult Spell::CheckItems()
            else
                TotemCategory -= 1;
        }
    -    if(TotemCategory != 0)
    +    if(TotemCategory != 0 && !isNoReagentReqCast)
            return SPELL_FAILED_TOTEM_CATEGORY;                 //0x7B
    
        // special checks for spell effects
    diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp
    index f208f50..8146127 100644
    --- a/src/game/SpellEffects.cpp
    +++ b/src/game/SpellEffects.cpp
    @@ -2646,7 +2646,11 @@ void Spell::DoCreateItem(uint32 i, uint32 itemtype)
    
            // send info to the client
            if(pItem)
    +        {
    +            if(itemTarget && (itemTarget->IsArmorVellum() || itemTarget->IsWeaponVellum()))
    +               player->DestroyItemCount(itemTarget->GetEntry(), 1, true);
                player->SendNewItem(pItem, num_to_add, true, true);
    +        }
    
            // we succeeded in creating at least one item, so a levelup is possible
            player->UpdateCraftSkill(m_spellInfo->Id);
    @@ -3779,6 +3783,19 @@ void Spell::EffectEnchantItemPerm(uint32 effect_idx)
        if(!pEnchant)
            return;
    
    +    ItemPrototype const* targetProto = itemTarget->GetProto();
    +    // EffectItemType serves as the entry of the item to be created.
    +    if(m_spellInfo->EffectItemType[effect_idx])
    +    {
    +        if((m_spellInfo->EquippedItemClass == ITEM_CLASS_ARMOR && itemTarget->IsArmorVellum()) ||
    +           (m_spellInfo->EquippedItemClass == ITEM_CLASS_WEAPON && itemTarget->IsWeaponVellum()))
    +        {
    +             unitTarget = m_caster;
    +             DoCreateItem(effect_idx,m_spellInfo->EffectItemType[effect_idx]);
    +             return;
    +        }
    +    }
    +    
        // item can be in trade slot and have owner diff. from caster
        Player* item_owner = itemTarget->GetOwner();
        if(!item_owner)
    

    Patchfile

  6. Ok, this one works correctly.

    This patch checks if the 2 auras are of the same type, and depending on CompareAuraRanks (basepoints) decides if the existing has to be replaced or not.

    I included only SPELL_AURA_MOD_ATTACK_POWER for testing, as we should be sure about which aura types are affected by this stacking system (if not all).

    diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp
    index 863c01d..466fd52 100644
    --- a/src/game/SpellMgr.cpp
    +++ b/src/game/SpellMgr.cpp
    @@ -256,17 +256,27 @@ bool IsSingleFromSpellSpecificPerCaster(SpellSpecific spellSpec1,SpellSpecific s
        }
    }
    
    -bool IsSingleFromSpellSpecificRanksPerTarget(SpellSpecific spellId_spec, SpellSpecific i_spellId_spec)
    +bool IsSingleFromSpellSpecificRanksPerTarget(SpellEntry const *spellInfo_1, SpellEntry const *spellInfo_2)
    {
    -    switch(spellId_spec)
    +    if(!spellInfo_1 || !spellInfo_2)
    +        return false;
    +
    +    uint32 aur_1 = spellInfo_1->EffectApplyAuraName[0];
    +    uint32 aur_2 = spellInfo_2->EffectApplyAuraName[0];
    +
    +    if(!aur_1 ||!aur_2)
    +        return false;
    +
    +    switch(aur_1)
        {
    -        case SPELL_BLESSING:
    -        case SPELL_AURA:
    -        case SPELL_CURSE:
    -            return spellId_spec==i_spellId_spec;
    +        case SPELL_AURA_MOD_ATTACK_POWER:
    +            if(aur_1==aur_2)
    +                return true;
            default:
                return false;
        }
    +
    +    return false;
    }
    
    bool IsPositiveTarget(uint32 targetA, uint32 targetB)
    diff --git a/src/game/SpellMgr.h b/src/game/SpellMgr.h
    index 8061dbe..4a47914 100644
    --- a/src/game/SpellMgr.h
    +++ b/src/game/SpellMgr.h
    @@ -146,7 +146,7 @@ inline bool IsLootCraftingSpell(SpellEntry const *spellInfo)
    
    int32 CompareAuraRanks(uint32 spellId_1, uint32 effIndex_1, uint32 spellId_2, uint32 effIndex_2);
    bool IsSingleFromSpellSpecificPerCaster(SpellSpecific spellSpec1,SpellSpecific spellSpec2);
    -bool IsSingleFromSpellSpecificRanksPerTarget(SpellSpecific spellId_spec, SpellSpecific i_spellId_spec);
    +bool IsSingleFromSpellSpecificRanksPerTarget(SpellEntry const *spellInfo_1, SpellEntry const *spellInfo_2);
    bool IsPassiveSpell(uint32 spellId);
    
    inline bool IsPassiveSpellStackableWithRanks(SpellEntry const* spellProto)
    diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
    index a2928a4..d902b2d 100644
    --- a/src/game/Unit.cpp
    +++ b/src/game/Unit.cpp
    @@ -3547,7 +3547,7 @@ bool Unit::RemoveNoStackAurasDueToAura(Aura *Aur)
            SpellSpecific i_spellId_spec = GetSpellSpecific(i_spellId);
    
            bool is_sspc = IsSingleFromSpellSpecificPerCaster(spellId_spec,i_spellId_spec);
    -        bool is_sspt = IsSingleFromSpellSpecificRanksPerTarget(spellId_spec,i_spellId_spec);
    +        bool is_sspt = IsSingleFromSpellSpecificRanksPerTarget(spellProto,i_spellProto);
    
            if( is_sspc && Aur->GetCasterGUID() == (*i).second->GetCasterGUID() )
            {
    @@ -3569,7 +3569,7 @@ bool Unit::RemoveNoStackAurasDueToAura(Aura *Aur)
                else
                    next =  m_Auras.begin();
            }
    -        else if( is_sspt && Aur->GetCasterGUID() != (*i).second->GetCasterGUID() && spellmgr.IsRankSpellDueToSpell(spellProto, i_spellId) )
    +        else if( is_sspt && Aur->GetCasterGUID() != (*i).second->GetCasterGUID() )
            {
                // cannot remove higher rank
                if(CompareAuraRanks(spellId, effIndex, i_spellId, i_effIndex) < 0) 
    

    Patchfile

    ::Edit::

    Forgot default case. Added.

    But still it will also need effect indexes, and lots of info from off.

  7. Ok, this patch should solve both the items and enchanting vellums. Probably it could be improved (need somewhat simplified checks), so any suggestions are welcome.

    diff --git a/src/game/Item.cpp b/src/game/Item.cpp
    index 2d25b7f..3b58f2e 100644
    --- a/src/game/Item.cpp
    +++ b/src/game/Item.cpp
    @@ -740,6 +740,10 @@ bool Item::IsFitToSpellRequirements(SpellEntry const* spellInfo) const
    {
        ItemPrototype const* proto = GetProto();
    
    +    if(spellInfo->Effect[0] == SPELL_EFFECT_ENCHANT_ITEM && ((spellInfo->EquippedItemClass == ITEM_CLASS_ARMOR && proto->SubClass == ITEM_SUBCLASS_ARMOR_ENCHANTMENT) ||
    +        (spellInfo->EquippedItemClass == ITEM_CLASS_WEAPON && proto->SubClass == ITEM_SUBCLASS_WEAPON_ENCHANTMENT)) && proto->Class == ITEM_CLASS_TRADE_GOODS)
    +        return true;
    +
        if (spellInfo->EquippedItemClass != -1)                 // -1 == any item class
        {
            if(spellInfo->EquippedItemClass != int32(proto->Class))
    diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp
    index c3af8e2..1b95a93 100644
    --- a/src/game/Spell.cpp
    +++ b/src/game/Spell.cpp
    @@ -4797,11 +4797,14 @@ SpellCastResult Spell::CheckItems()
    
        Player* p_caster = (Player*)m_caster;
    
    +    // if m_CastItem = EffectItemType[0] of the spell we don't need reagents (e.g.: Scroll of Enchant *)
    +    bool isNoReagentReqCast = m_CastItem ? m_CastItem->GetEntry() == m_spellInfo->EffectItemType[0] : false;
    +
        // cast item checks
        if(m_CastItem)
        {
            uint32 itemid = m_CastItem->GetEntry();
    -        if( !p_caster->HasItemCount(itemid,1) )
    +        if( !p_caster->HasItemCount(itemid,1) && !isNoReagentReqCast)
                return SPELL_FAILED_ITEM_NOT_READY;
    
            ItemPrototype const *proto = m_CastItem->GetProto();
    @@ -4906,7 +4909,7 @@ SpellCastResult Spell::CheckItems()
        }
    
        // check reagents (ignore triggered spells with reagents processed by original spell) and special reagent ignore case.
    -    if (!m_IsTriggeredSpell && !p_caster->CanNoReagentCast(m_spellInfo))
    +    if (!m_IsTriggeredSpell && !p_caster->CanNoReagentCast(m_spellInfo) && !isNoReagentReqCast)
        {
            for(uint32 i=0;i<8;++i)
            {
    @@ -4952,7 +4955,7 @@ SpellCastResult Spell::CheckItems()
            }else
            totems -= 1;
        }
    -    if(totems != 0)
    +    if(totems != 0 && !isNoReagentReqCast)
            return SPELL_FAILED_TOTEMS;                         //0x7C
    
        // Check items for TotemCategory  (items presence in inventory)
    @@ -4970,7 +4973,7 @@ SpellCastResult Spell::CheckItems()
            else
                TotemCategory -= 1;
        }
    -    if(TotemCategory != 0)
    +    if(TotemCategory != 0 && !isNoReagentReqCast)
            return SPELL_FAILED_TOTEM_CATEGORY;                 //0x7B
    
        // special checks for spell effects
    diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp
    index 30d2c62..5f94c19 100644
    --- a/src/game/SpellEffects.cpp
    +++ b/src/game/SpellEffects.cpp
    @@ -3807,6 +3807,55 @@ void Spell::EffectEnchantItemPerm(uint32 effect_idx)
                item_owner->GetName(),item_owner->GetSession()->GetAccountId());
        }
    
    +    if(ItemPrototype const* targetProto = itemTarget->GetProto())
    +    {
    +        // EffectItemType serves as the entry of the item to be created.
    +        if(m_spellInfo->EffectItemType[effect_idx] && targetProto->Class == ITEM_CLASS_TRADE_GOODS)
    +        {
    +            if((m_spellInfo->EquippedItemClass == ITEM_CLASS_ARMOR && targetProto->SubClass == ITEM_SUBCLASS_ARMOR_ENCHANTMENT) ||
    +               (m_spellInfo->EquippedItemClass == ITEM_CLASS_WEAPON && targetProto->SubClass == ITEM_SUBCLASS_WEAPON_ENCHANTMENT))
    +            {
    +                // If the target is correct create the new item and store it if possible
    +                uint32 newitemid = m_spellInfo->EffectItemType[effect_idx];
    +                if(!newitemid)
    +                    return;
    +
    +                uint16 pos = itemTarget->GetPos();
    +
    +                Item *pNewItem = Item::CreateItem( newitemid, 1, p_caster);
    +                if( !pNewItem )
    +                    return;
    +
    +                if( p_caster->IsInventoryPos( pos ) )
    +                {
    +                    ItemPosCountVec dest;
    +                    uint8 msg = p_caster->CanStoreItem( itemTarget->GetBagSlot(), itemTarget->GetSlot(), dest, pNewItem, true );
    +                    if( msg == EQUIP_ERR_OK )
    +                    {
    +                        p_caster->DestroyItem(itemTarget->GetBagSlot(), itemTarget->GetSlot(),true);
    +                        itemTarget = NULL;
    +
    +                        p_caster->StoreItem( dest, pNewItem, true);
    +                        return;
    +                    }
    +                }
    +                else if( p_caster->IsBankPos ( pos ) )
    +                {
    +                    ItemPosCountVec dest;
    +                    uint8 msg = p_caster->CanBankItem( itemTarget->GetBagSlot(), itemTarget->GetSlot(), dest, pNewItem, true );
    +                    if( msg == EQUIP_ERR_OK )
    +                    {
    +                        p_caster->DestroyItem(itemTarget->GetBagSlot(), itemTarget->GetSlot(),true);
    +                        itemTarget = NULL;
    +
    +                        p_caster->BankItem( dest, pNewItem, true);
    +                        return;
    +                    }
    +                }
    +            }
    +        }
    +    }
    +
        // remove old enchanting before applying new if equipped
        item_owner->ApplyEnchantment(itemTarget,PERM_ENCHANTMENT_SLOT,false);
    
    

    Patchfile

    Commit

  8. This should solve it:

    diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp
    index 0ace799..da173f5 100644
    --- a/src/game/Spell.cpp
    +++ b/src/game/Spell.cpp
    @@ -4797,11 +4797,14 @@ SpellCastResult Spell::CheckItems()
    
        Player* p_caster = (Player*)m_caster;
    
    +    // m_CastItem with flag 0x10000000 does not need reagents (e.g.: Scroll of Enchant *)
    +    bool isNoReagentReqItem =  m_CastItem ? m_CastItem->GetProto()->Flags & 0x10000000 : false;
    +
        // cast item checks
        if(m_CastItem)
        {
            uint32 itemid = m_CastItem->GetEntry();
    -        if( !p_caster->HasItemCount(itemid,1) )
    +        if( !p_caster->HasItemCount(itemid,1) && !isNoReagentReqItem )
                return SPELL_FAILED_ITEM_NOT_READY;
    
            ItemPrototype const *proto = m_CastItem->GetProto();
    @@ -4906,7 +4909,7 @@ SpellCastResult Spell::CheckItems()
        }
    
        // check reagents (ignore triggered spells with reagents processed by original spell) and special reagent ignore case.
    -    if (!m_IsTriggeredSpell && !p_caster->CanNoReagentCast(m_spellInfo))
    +    if (!m_IsTriggeredSpell && !p_caster->CanNoReagentCast(m_spellInfo) && !isNoReagentReqItem)
        {
            for(uint32 i=0;i<8;i++)
            {
    @@ -4970,7 +4973,7 @@ SpellCastResult Spell::CheckItems()
            else
                TotemCategory -= 1;
        }
    -    if(TotemCategory != 0)
    +    if(TotemCategory != 0 && !isNoReagentReqItem)
            return SPELL_FAILED_TOTEM_CATEGORY;                 //0x7B
    
        // special checks for spell effects
    

    Patchfile

    Just be sure about the flags... :)

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. Privacy Policy Terms of Use