All pastes #499710 Raw Edit

Anonymous

public cpp v1 · immutable
·published 2007-05-21 06:11 UTC
rendered paste body
Index: src/game/Bag.cpp===================================================================--- src/game/Bag.cpp	(revision 3677)+++ src/game/Bag.cpp	(working copy)@@ -219,6 +219,17 @@         if( pItem && pItem != eItem && pItem->GetEntry() == item )             count += pItem->GetCount();     }++    if(eItem && eItem->GetProto()->GemProperties)+    {+        for(uint32 i=0; i < ContainerSlots; i++)+        {+            pItem = m_bagslot[i];+            if( pItem && pItem != eItem && pItem->GetProto()->Socket[0].Color )+                count += pItem->GetGemCountWithID(item);+        }+    }+         return count; } Index: src/game/Item.cpp===================================================================--- src/game/Item.cpp	(revision 3677)+++ src/game/Item.cpp	(working copy)@@ -168,6 +168,7 @@     m_container = NULL;     m_lootGenerated = false;     mb_in_trade = false;+    forcenextenchant = false; }  bool Item::Create( uint32 guidlow, uint32 itemid, Player* owner)@@ -964,3 +965,62 @@         SetUInt32Value(ITEM_FIELD_ENCHANTMENT+slot*3+x,0);     SetState(ITEM_CHANGED); }++bool Item::GemsFitSockets() const+{+    bool fits = true;+    for(uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+3; ++enchant_slot)+    {+        uint8 SocketColor = GetProto()->Socket[enchant_slot-SOCK_ENCHANTMENT_SLOT].Color;++        uint32 enchant_id = GetEchantmentId(EnchantmentSlot(enchant_slot));+        if(!enchant_id)+        {+            if(SocketColor) fits &= false;+            continue;+        }++        SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(enchant_id);+        if(!enchantEntry)+        {+            if(SocketColor) fits &= false;+            continue;+        }++        uint8 GemColor = 0;++        uint32 gemid = enchantEntry->GemID;+        if(gemid)+        {+            ItemPrototype const* gemProto = sItemStorage.LookupEntry<ItemPrototype>(gemid);+            if(gemProto)+            {+                GemPropertiesEntry const* gemProperty = sGemPropertiesStore.LookupEntry(gemProto->GemProperties);+                if(gemProperty)+                    GemColor = gemProperty->color;+            }+        }++        fits &= (GemColor & SocketColor) ? true : false;+    }+    return fits;+}++uint8 Item::GetGemCountWithID(uint32 GemID) const+{+    uint8 count = 0;+    for(uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+3; ++enchant_slot)+    {+        uint32 enchant_id = GetEchantmentId(EnchantmentSlot(enchant_slot));+        if(!enchant_id)+            continue;++        SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(enchant_id);+        if(!enchantEntry)+            continue;++        if(GemID == enchantEntry->GemID)+            count++;+    }+    return count;+}Index: src/game/Item.h===================================================================--- src/game/Item.h	(revision 3677)+++ src/game/Item.h	(working copy)@@ -197,11 +197,13 @@         bool IsInTrade() const { return mb_in_trade; }          bool IsFitToSpellRequirements(SpellEntry const* spellInfo) const;+        bool GemsFitSockets() const;          uint32 GetEntry() const { return GetUInt32Value(OBJECT_FIELD_ENTRY); }         uint32 GetCount() const { return GetUInt32Value (ITEM_FIELD_STACK_COUNT); }         void SetCount(uint32 value) { SetUInt32Value (ITEM_FIELD_STACK_COUNT, value); }         uint32 GetMaxStackCount() const { return GetProto()->Stackable ? GetProto()->Stackable : 1; }+        uint8 GetGemCountWithID(uint32 GemID) const;          uint8 GetSlot() const {return m_slot;}         Bag *GetContainer() { return m_container; }@@ -243,6 +245,8 @@             uState = state;         } +        bool forcenextenchant;+         bool hasQuest(uint32 quest_id) const          {             ItemPrototype const *itemProto = GetProto();Index: src/game/ItemHandler.cpp===================================================================--- src/game/ItemHandler.cpp	(revision 3677)+++ src/game/ItemHandler.cpp	(working copy)@@ -266,7 +266,8 @@                 data << uint32(0);                 if (pItem)                 {-                    if ((s < 3) && (pItem->GetUInt32Value(ITEM_FIELD_SOCKETS_ENCHANTMENT+s*3)))+                    // SOCK_ENCHANTMENT_SLOT.. SOCK_ENCHANTMENT_SLOT+2 is gem sockets+                    if ((s < 3) && (pItem->GetEchantmentId(EnchantmentSlot(SOCK_ENCHANTMENT_SLOT+ s))))                     {                         data << uint32(1);                     }@@ -907,63 +908,86 @@  void WorldSession::HandleSocketOpcode(WorldPacket& recv_data) {-    sLog.outDebug("Received opcode CMSG_SOCKET_ITEM");-    uint64 itemguid;-    uint64 gemguid[3];-    uint32 gemProperty[3];+    sLog.outDebug("WORLD: CMSG_SOCKET_ITEM"); -    recv_data >> itemguid >> gemguid[0] >> gemguid[1] >> gemguid[2];+    CHECK_PACKET_SIZE(recv_data,8*4); -    bool propercolor[3], full[3];-    Item *pItem = _player->GetItemByPos(_player->GetPosByGuid(itemguid));-    if(pItem)+    uint64 guids[4];+    uint32 GemEnchants[3], OldEnchants[3];+    Item *Gems[3];+    bool SocketBonusActivated, SocketBonusToBeActivated;+++    for(int i = 0; i < 4; i++)+        recv_data >> guids[i];++    //cheat -> tried to socket same gem multiple times+    if((guids[1] && (guids[1] == guids[2] || guids[1] == guids[3])) || (guids[2] && (guids[2] == guids[3]))) +        return;++    uint16 pos = _player->GetPosByGuid(guids[0]);+    Item *itemTarget = _player->GetItemByPos(pos);+    if(!itemTarget) //missing item to socket+        return;++    uint16 slot = pos & 255;                                //this slot is excepted when applying / removing meta gem bonus++    for(int i = 0; i < 3; i++)     {-        bool HasBonus = 1;-        for(int s = 0; s < 3; s++)-        {-            if(gemguid[s])-            {-                Item *pGem = _player->GetItemByPos(_player->GetPosByGuid(gemguid[s]));-                if(pGem)-                {-                    gemProperty[s] = pGem->GetProto()->GemProperties;-                    GemPropertiesEntry const *gemInfo = sGemPropertiesStore.LookupEntry(gemProperty[s]);-                    if(gemInfo)-                    {-                        propercolor[s] = (gemInfo->color & pItem->GetProto()->Socket[s].Color);-                        if ((gemInfo->color & SOCKET_COLOR_META) & !propercolor[s])-                        {-                            // ToDo : Error message-                            continue;-                        }-                        pItem->SetUInt32Value(ITEM_FIELD_SOCKETS_ENCHANTMENT+s*3, gemInfo->spellitemenchantement);-                        _player->DestroyItem(pGem->GetBagSlot(), pGem->GetSlot(), true);-                        full[s] = 1;-                    }-                }-            }-            else-            {-                gemProperty[s] = 0;-                propercolor[s] = 1;-                if(pItem->GetProto()->Socket[s].Color)-                {-                    full[s]=0;-                }-                else-                {-                    full[s]=1;-                }-                HasBonus &= full[s] & propercolor[s];-            }+        pos = _player->GetPosByGuid(guids[i + 1]);+        Gems[i] = _player->GetItemByPos(pos);+    } -            // Now if all full[s] are true and all propercolor[s] are true, also apply the bonus pItemProto->socketBonus-            if(HasBonus)-            {-                pItem->SetUInt32Value(ITEM_FIELD_SOCKETS_ENCHANTMENT+3*3, pItem->GetProto()->socketBonus);-            }+    GemPropertiesEntry const *GemProps[3];+    for(int i = 0; i < 3; ++i)                              //get geminfo from dbc storage+    {+        GemProps[i] = (Gems[i]) ? sGemPropertiesStore.LookupEntry(Gems[i]->GetProto()->GemProperties) : NULL;+    } -            _player->_ApplyItemMods(pItem, pItem->GetSlot(), true);+    for(int i = 0; i < 3; ++i)                              //check for hack maybe+    {+        // tried to put gem in socket where no socket exists / tried to put normal gem in meta socket+        // tried to put meta gem in normal socket+        if( GemProps[i] && ( (!itemTarget->GetProto()->Socket[i].Color) || (itemTarget->GetProto()->Socket[i].Color == 1 && GemProps[i]->color != 1) || (itemTarget->GetProto()->Socket[i].Color != 1 && GemProps[i]->color == 1))) +            return;+    }++    for(int i = 0; i < 3; ++i)                              //get new and old enchantments+    {+        GemEnchants[i] = (GemProps[i]) ? GemProps[i]->spellitemenchantement : 0;+        OldEnchants[i] = itemTarget->GetEchantmentId(EnchantmentSlot(SOCK_ENCHANTMENT_SLOT+i));+    }++    SocketBonusActivated = itemTarget->GemsFitSockets();    //save state of socketbonus+    _player->ToggleMetaGemsActive(slot, false);             //turn off all metagems (except for the target item)++    //if a meta gem is being equipped, all information has to be written to the item before testing if the conditions for the gem are met++    //remove ALL enchants+    for(uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+3; ++enchant_slot)+        _player->ApplyEnchantment(itemTarget,EnchantmentSlot(enchant_slot),false);++    for(int i = 0; i < 3; ++i)+    {+        if(GemEnchants[i])+        {+            itemTarget->SetEchantment(EnchantmentSlot(SOCK_ENCHANTMENT_SLOT+i), GemEnchants[i],0,0);+            pos = _player->GetPosByGuid(guids[i + 1]);+            _player->DestroyItem((pos >> 8), (pos & 255), true );         }     }++    for(uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+3; ++enchant_slot)+        _player->ApplyEnchantment(itemTarget,EnchantmentSlot(enchant_slot),true);+    +    SocketBonusToBeActivated = itemTarget->GemsFitSockets();    //current socketbonus state+    if(SocketBonusActivated ^ SocketBonusToBeActivated)    //if there was a change...+    {+        _player->ApplyEnchantment(itemTarget,BONUS_ENCHANTMENT_SLOT,false);+        itemTarget->SetEchantment(BONUS_ENCHANTMENT_SLOT, (SocketBonusToBeActivated ? itemTarget->GetProto()->socketBonus : 0), 0, 0);+        _player->ApplyEnchantment(itemTarget,BONUS_ENCHANTMENT_SLOT,true);+        //it is not displayed, client has an inbuilt system to determine if the bonus is activated+    }++    _player->ToggleMetaGemsActive(slot, true);    //turn on all metagems (except for target item) }Index: src/game/Player.cpp===================================================================--- src/game/Player.cpp	(revision 3677)+++ src/game/Player.cpp	(working copy)@@ -4974,6 +4974,9 @@      ApplyEnchantment(item, apply); +    if(proto->Socket[0].Color)    //only (un)equipping of items with sockets can influence metagems, so no need to waste time with normal items+        CorrectMetaGemEnchants(slot, apply);+     sLog.outDebug("_ApplyItemMods complete."); } @@ -6454,6 +6457,16 @@             count += pBag->GetItemCount(item,eItem);     } +    if(eItem && eItem->GetProto()->GemProperties)+    {+        for(int i = EQUIPMENT_SLOT_START; i < INVENTORY_SLOT_ITEM_END; i++)+        {+            pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i );+            if( pItem && pItem != eItem && pItem->GetProto()->Socket[0].Color )+                count += pItem->GetGemCountWithID(item);+        }+    }+     return count; } @@ -6474,6 +6487,17 @@         if( pBag )             count += pBag->GetItemCount(item,eItem);     }+    +    if(eItem && eItem->GetProto()->GemProperties)+    {+        for(int i = BANK_SLOT_ITEM_START; i < BANK_SLOT_ITEM_END; i++)+        {+            pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i );+            if( pItem && pItem != eItem && pItem->GetProto()->Socket[0].Color )+                count += pItem->GetGemCountWithID(item);+        }+    }+         return count; } @@ -8923,6 +8947,11 @@     if(!pEnchant)         return; +    if(pEnchant->EnchantmentCondition && !item->forcenextenchant && !((Player*)this)->EnchantmentFitsRequirements(pEnchant->EnchantmentCondition, -1))+        return;++    item->forcenextenchant = false;+     for (int s=0; s<3; s++)     {         uint32 enchant_display_type = pEnchant->display_type[s];@@ -12942,6 +12971,162 @@     return m_AuraModifiers[SPELL_AURA_MOD_SHIELD_BLOCKVALUE]*(m_AuraModifiers[SPELL_AURA_MOD_SHIELD_BLOCKVALUE_PCT]+100)/100; } +bool Player::EnchantmentFitsRequirements(uint32 enchantmentcondition, int8 slot)    //slot to be excluded while counting+{+    if(!enchantmentcondition)+        return true;++    SpellItemEnchantmentConditionEntry const *Condition = sSpellItemEnchantmentConditionStore.LookupEntry(enchantmentcondition);++    if(!Condition)+            return true;++    uint8 curcount[4] = {0, 0, 0, 0};++    //counting current equipped gem colors+    for(uint8 i = EQUIPMENT_SLOT_START; i < EQUIPMENT_SLOT_END; ++i)+    {+        if(i == slot)+                continue;+        uint16 pos = ((INVENTORY_SLOT_BAG_0 << 8) | i );+        Item *pItem2 = GetItemByPos( pos );+        if(pItem2 && pItem2->GetProto()->Socket[0].Color)+        {+            for(uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+3; ++enchant_slot)+            {+                uint32 enchant_id = pItem2->GetEchantmentId(EnchantmentSlot(enchant_slot));+                if(!enchant_id)+                    continue;++                SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(enchant_id);+                if(!enchantEntry)+                    continue;++                uint32 gemid = enchantEntry->GemID;+                if(!gemid)+                    continue;++                ItemPrototype const* gemProto = sItemStorage.LookupEntry<ItemPrototype>(gemid);+                if(!gemProto)+                    continue;++                GemPropertiesEntry const* gemProperty = sGemPropertiesStore.LookupEntry(gemProto->GemProperties);+                if(!gemProperty)+                    continue;++                uint8 GemColor = gemProperty->color;++                for(uint8 b = 0, tmpcolormask = 1; b < 4; b++, tmpcolormask <<= 1)+                {+                    if(tmpcolormask & GemColor)+                        curcount[b]++;+                }+            }+        }+    }++    bool activate = true;++    for(int i = 0; i < 5; i++)+    {+        if(!Condition->Color[i])+            continue;++        uint32 _cur_gem = curcount[Condition->Color[i] - 1];++        // if have <CompareColor> use them as count, else use <value> from Condition+        uint32 _cmp_gem = Condition->CompareColor[i] ? curcount[Condition->CompareColor[i] - 1]: Condition->Value[i];++        switch(Condition->Comparator[i]) {+            case 2: // requires less <color> than (<value> || <comparecolor>) gems+                activate &= (_cur_gem < _cmp_gem) ? true : false;+                break;+            case 3: // requires more <color> than (<value> || <comparecolor>) gems+                activate &= (_cur_gem > _cmp_gem) ? true : false;+                break;+            case 5: // requires at least <color> than (<value> || <comparecolor>) gems+                activate &= (_cur_gem >= _cmp_gem) ? true : false;+                break;+        }+    }++    sLog.outDebug("Checking Condition %u, there are %u Meta Gems, %u Red Gems, %u Yellow Gems and %u Blue Gems, Activate:%s", enchantmentcondition, curcount[0], curcount[1], curcount[2], curcount[3], activate ? "yes" : "no");++    return activate;+}+++void Player::CorrectMetaGemEnchants(uint8 exceptslot, bool apply)+{++    for(uint32 slot = EQUIPMENT_SLOT_START; slot < EQUIPMENT_SLOT_END; ++slot)    //cycle all equipped items+    {+        //enchants for the slot being socketed are handeled by Player::ApplyItemMods+        if(slot == exceptslot)+            continue;++        uint16 pos = ( (INVENTORY_SLOT_BAG_0 << 8) | slot );+        Item* pItem = GetItemByPos( pos );++        if(!pItem || !pItem->GetProto()->Socket[0].Color)+            continue;++        for(uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+3; ++enchant_slot)+        {+            uint32 enchant_id = pItem->GetEchantmentId(EnchantmentSlot(enchant_slot));+            if(!enchant_id)+                continue;++            SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(enchant_id);+            if(!enchantEntry)+                continue;++            uint32 condition = enchantEntry->EnchantmentCondition;+            if(condition)+            {+                bool wasactive = EnchantmentFitsRequirements(condition, apply ? exceptslot : -1);    //was enchant active with/without item?+                if(wasactive ^ EnchantmentFitsRequirements(condition, apply ? -1 : exceptslot))    //should it now be?+                {+                    pItem->forcenextenchant = true;+                    ApplyEnchantment(pItem,EnchantmentSlot(enchant_slot),!wasactive);                            //if state changed, (dis)apply enchant+                }+            }+        }+    }+}++void Player::ToggleMetaGemsActive(uint16 exceptslot, bool apply)        //if false -> then toggled off if was on| if true -> toggled on if was off AND meets requirements+{+    for(int slot = EQUIPMENT_SLOT_START; slot < EQUIPMENT_SLOT_END; slot++)    //cycle all equipped items+    {+        //enchants for the slot being socketed are handeled by WorldSession::HandleSocketOpcode(WorldPacket& recv_data)+        if(slot == exceptslot) continue;++        uint16 pos = ( (INVENTORY_SLOT_BAG_0 << 8) | slot );+        Item *pItem = GetItemByPos( pos );++        if(!pItem || !pItem->GetProto()->Socket[0].Color)    //if item has no sockets or no item is equipped go to next item+            continue;++        //cycle all (gem)enchants+        for(uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+3; ++enchant_slot)+        {+            uint32 enchant_id = pItem->GetEchantmentId(EnchantmentSlot(enchant_slot));+            if(!enchant_id)                                    //if no enchant go to next enchant(slot)+                continue;++            SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(enchant_id);+            if(!enchantEntry)+                continue;++            //only metagems to be (de)activated, so only enchants with condition+            uint32 condition = enchantEntry->EnchantmentCondition;+            if(condition)+                ApplyEnchantment(pItem,EnchantmentSlot(enchant_slot), apply);+        }+    }+}+ bool Player::DropBattleGroundFlag() {     if(InBattleGround())Index: src/game/Player.h===================================================================--- src/game/Player.h	(revision 3677)+++ src/game/Player.h	(working copy)@@ -1182,6 +1182,9 @@         void _ApplyAllItemMods();         void _ApplyItemBonuses(ItemPrototype const *proto,uint8 slot,bool apply);         void _ApplyAmmoBonuses(bool apply);+        bool EnchantmentFitsRequirements(uint32 enchantmentcondition, int8 slot);+        void ToggleMetaGemsActive(uint16 exceptslot, bool apply);+        void CorrectMetaGemEnchants(uint8 slot, bool apply);         void InitDataForForm();          void CastItemEquipSpell(Item *item);Index: src/game/UpdateFields.h===================================================================--- src/game/UpdateFields.h	(revision 3677)+++ src/game/UpdateFields.h	(working copy)@@ -46,7 +46,6 @@     ITEM_FIELD_SPELL_CHARGES_04                = OBJECT_END + 0x0E,     ITEM_FIELD_FLAGS                           = OBJECT_END + 0x0F, // Size:1     ITEM_FIELD_ENCHANTMENT                     = OBJECT_END + 0x10, // Size: 33 = (temp+perm+sockets*3+bonus+temp2*2+property*3)*3-    ITEM_FIELD_SOCKETS_ENCHANTMENT             = OBJECT_END + 0x16, //    include (3 slots) * 3 = 9     ITEM_FIELD_PROPERTY_SEED                   = OBJECT_END + 0x31, // Size:1     ITEM_FIELD_RANDOM_PROPERTIES_ID            = OBJECT_END + 0x32, // Size:1     ITEM_FIELD_ITEM_TEXT_ID                    = OBJECT_END + 0x33, // Size:1