Jump to content

"flags|268435456" Item Enchants


Recommended Posts

Tied the patch, scrolls get greated, one annoyance and on big problem

1. When a char uses the scroll the char gets a skillup in enchanting (annoyance)

2. When the char logs out the char data cannot be saved and is save is aborted.

e.g use scroll to apply enchantment. log out, check server log see that save is not done.

or just log back in you will see that the save was not done.

Hopefully I applied the patch correctly.

Sorry, fix already posted, should have tried reading first

http://getmangos.eu/community/viewtopic.php?id=7901

Link to comment
Share on other sites

  • 39 years later...

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... :)

Link to comment
Share on other sites

Just be sure about the flags...

Well, I wouldn't bet my life on it, but I would wager a few beers. :)

http://udbforums.org/index.php?topic=12792.0

Every "scroll of enchant*" has this flag. No other items have this flag, except item # 40076, which also falls into the same category (spell casted from the item should not require reagents).

That having been said, wowhead lists 259 "scroll of enchant*" items, and we only have 251 of them in UDB. I can't say with 100% certainty that this flag is correct since we're missing the other 8 scrolls.

It would be nice if we could get WDB data on the missing 8 items to be 100% certain. Right now, I guess you can say we're 97% certain. :)

Perhaps it would be nicer with 0x10000000

Yes, it would- MaNGOS usually uses hex values for flags, so this would be conforming to current style.

On another note, wouldn't it be better to make a change in player.ccp bool Player::CanNoReagentCast(SpellEntry const* spellInfo) const

Link to comment
Share on other sites

Perfect! Applied the patch, compiled and it works great. Thanks a bunch. You should post this into patches as it should be in core by default.

As for the missing items, here is a new search, with only 2 missing items.

http://www.wowhead.com/?items=0.6&filter=qu=1:3;na=Scroll+of+Enchant;cr=82:107;crs=2:0;crv=0:Use

One of the items not in the DB is "Scroll of Enchant Weapon - Titanguard", so that leaves us at 1 missing item. I'm 99.61% sure that flag is for those items. (Did the math)

EDIT: Found the other enchant "Scroll of Enchant Bracer - Major Stamina", now I'm 100% sure.

44946

44947

are the item ID's

Link to comment
Share on other sites

Yeh, I agree. It's not that big of a deal to me, as I'm just going to throw them into a vendor.

None the less, it should be fixed at some point. I would do it, but I can't find any documentation on mangos, and I don't feel like reading the entire source code to learn it, and I'm limited in c++ anyways.

Still awesome job on fixing the scrolls.

Link to comment
Share on other sites

"Scroll of Enchant Bracer - Major Stamina", now I'm 100% sure.

44946

44947

are the item ID's

I just queried those items and they have the flags 268435520 and 268439616, which both contain 268435456. So the theorie seems to be right :)
Link to comment
Share on other sites

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

Link to comment
Share on other sites

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

Link to comment
Share on other sites

I tried your patch on the following setup:

MaNGOS/0.13.0 (* * Revision 7809 - 04a788ba038903879b5490cf3f94daf9db2382be) for Unix (little-endian)
Using script library: ScriptDev2 (for MaNGOS 7723+) Revision [1065] 2009-05-09 15:22:10 (Unix)
Using World DB: PSDB WotLK (196)
Using creature EventAI: PSDB EventAI
Online players: 1 (max: 1) Queued players: 0 (max: 0)
Server uptime: 1 Minute(s) 47 Second(s).

And the only problem so far is that it still requires the rod, otherwise you cannot apply the enchant.

On my tests I tried to use the item Scroll of Enchant Gloves - Crusher, if that matters.

Link to comment
Share on other sites

Guest
This topic is now closed to further replies.
×
×
  • 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