示例#1
0
uint8 Item::GetGemCountWithLimitCategory(uint32 limitCategory) const
{
    uint8 count = 0;
    for (uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+MAX_GEM_SOCKETS; ++enchant_slot)
    {
        uint32 enchant_id = GetEnchantmentId(EnchantmentSlot(enchant_slot));
        if (!enchant_id)
            continue;

        SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
        if (!enchantEntry)
            continue;

        ItemTemplate const* gemProto = sObjectMgr->GetItemTemplate(enchantEntry->GemID);
        if (!gemProto)
            continue;

        if (gemProto->ItemLimitCategory == limitCategory)
            ++count;
    }
    return count;
}
示例#2
0
文件: Item.cpp 项目: Gengeru/mangos
bool Item::GemsFitSockets() const
{
    bool fits = true;
    for(uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+MAX_GEM_SOCKETS; ++enchant_slot)
    {
        uint8 SocketColor = GetProto()->Socket[enchant_slot-SOCK_ENCHANTMENT_SLOT].Color;

        uint32 enchant_id = GetEnchantmentId(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;
}
示例#3
0
文件: Item.cpp 项目: Splash/mangos
uint8 Item::GetJewelcraftingGemCount() const
{
    uint8 count = 0;
    for (uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT + MAX_GEM_SOCKETS; ++enchant_slot)
    {
        uint32 enchant_id = GetEnchantmentId(EnchantmentSlot(enchant_slot));

        if (!enchant_id)
            continue;

        SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
        if (!enchantEntry)
            continue;

        ItemPrototype const* gemProto = ObjectMgr::GetItemPrototype(enchantEntry->GemID);
        if (!gemProto)
            continue;

        if (gemProto->RequiredSkill == SKILL_JEWELCRAFTING)
            ++count;
    }
    return count;
}
示例#4
0
bool Item::GemsFitSockets() const
{
    for (uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+MAX_GEM_SOCKETS; ++enchant_slot)
    {
        uint8 SocketColor = GetTemplate()->Socket[enchant_slot-SOCK_ENCHANTMENT_SLOT].Color;

        if (!SocketColor) // no socket slot
            continue;

        uint32 enchant_id = GetEnchantmentId(EnchantmentSlot(enchant_slot));
        if (!enchant_id) // no gems on this socket
            return false;

        SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
        if (!enchantEntry) // invalid gem id on this socket
            return false;

        uint8 GemColor = 0;

        uint32 gemid = enchantEntry->GemID;
        if (gemid)
        {
            ItemTemplate const* gemProto = sObjectMgr->GetItemTemplate(gemid);
            if (gemProto)
            {
                GemPropertiesEntry const* gemProperty = sGemPropertiesStore.LookupEntry(gemProto->GemProperties);
                if (gemProperty)
                    GemColor = gemProperty->color;
            }
        }

        if (!(GemColor & SocketColor)) // bad gem color on this socket
            return false;
    }
    return true;
}
示例#5
0
bool Item::IsBoundByEnchant() const
{
    // Check all enchants for soulbound
    for (uint32 enchant_slot = PERM_ENCHANTMENT_SLOT; enchant_slot < MAX_ENCHANTMENT_SLOT; ++enchant_slot)
    {
        uint32 enchant_id = GetEnchantmentId(EnchantmentSlot(enchant_slot));
        if (!enchant_id)
            continue;

        if (enchant_slot == TRANSMOGRIFY_ENCHANTMENT_SLOT)
            return true;

        if (enchant_slot > PRISMATIC_ENCHANTMENT_SLOT && enchant_slot < PROP_ENCHANTMENT_SLOT_0)
            continue;

        SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
        if (!enchantEntry)
            continue;

        if (enchantEntry->slot & ENCHANTMENT_CAN_SOULBOUND)
            return true;
    }
    return false;
}
示例#6
0
void Item::SaveToDB(SQLTransaction& trans)
{
    bool isInTransaction = !(trans.null());
    if (!isInTransaction)
        trans = CharacterDatabase.BeginTransaction();

    uint32 guid = GetGUIDLow();
    switch (uState)
    {
        case ITEM_NEW:
        case ITEM_CHANGED:
        {
            uint8 index = 0;
            PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(uState == ITEM_NEW ? CHAR_REP_ITEM_INSTANCE : CHAR_UPD_ITEM_INSTANCE);
            stmt->setUInt32(  index, GetEntry());
            stmt->setUInt32(++index, GUID_LOPART(GetOwnerGUID()));
            stmt->setUInt32(++index, GUID_LOPART(GetUInt64Value(ITEM_FIELD_CREATOR)));
            stmt->setUInt32(++index, GUID_LOPART(GetUInt64Value(ITEM_FIELD_GIFTCREATOR)));
            stmt->setUInt32(++index, GetCount());
            stmt->setUInt32(++index, GetUInt32Value(ITEM_FIELD_DURATION));

            std::ostringstream ssSpells;
            for (uint8 i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
                ssSpells << GetSpellCharges(i) << ' ';
            stmt->setString(++index, ssSpells.str());

            stmt->setUInt32(++index, GetUInt32Value(ITEM_FIELD_FLAGS));

            std::ostringstream ssEnchants;
            for (uint8 i = 0; i < MAX_ENCHANTMENT_SLOT; ++i)
            {
                ssEnchants << GetEnchantmentId(EnchantmentSlot(i)) << ' ';
                ssEnchants << GetEnchantmentDuration(EnchantmentSlot(i)) << ' ';
                ssEnchants << GetEnchantmentCharges(EnchantmentSlot(i)) << ' ';
            }
            stmt->setString(++index, ssEnchants.str());

            stmt->setInt16 (++index, GetItemRandomPropertyId());
            stmt->setUInt16(++index, GetUInt32Value(ITEM_FIELD_DURABILITY));
            stmt->setUInt32(++index, GetUInt32Value(ITEM_FIELD_CREATE_PLAYED_TIME));
            stmt->setString(++index, m_text);
            stmt->setUInt32(++index, guid);

            trans->Append(stmt);

            if ((uState == ITEM_CHANGED) && HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_WRAPPED))
            {
                stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GIFT_OWNER);
                stmt->setUInt32(0, GUID_LOPART(GetOwnerGUID()));
                stmt->setUInt32(1, guid);
                trans->Append(stmt);
            }
            break;
        }
        case ITEM_REMOVED:
        {
            PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ITEM_INSTANCE);
            stmt->setUInt32(0, guid);
            trans->Append(stmt);

            if (HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_WRAPPED))
            {
                stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GIFT);
                stmt->setUInt32(0, guid);
                trans->Append(stmt);
            }

            if (!isInTransaction)
                CharacterDatabase.CommitTransaction(trans);

            delete this;
            return;
        }
        case ITEM_UNCHANGED:
            break;
    }

    SetState(ITEM_UNCHANGED);

    if (!isInTransaction)
        CharacterDatabase.CommitTransaction(trans);
}
示例#7
0
void WorldSession::HandleSocketOpcode(WorldPacket& recv_data)
{
    sLog.outDebug("WORLD: CMSG_SOCKET_GEMS");

    CHECK_PACKET_SIZE(recv_data,8*4);

    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];

    if(!guids[0])
        return;

    //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;

    Item *itemTarget = _player->GetItemByGuid(guids[0]);
    if(!itemTarget)                                         //missing item to socket
        return;

    //this slot is excepted when applying / removing meta gem bonus
    uint8 slot = itemTarget->IsEquipped() ? itemTarget->GetSlot() : NULL_SLOT;

    for(int i = 0; i < 3; i++)
        Gems[i] = guids[i + 1] ? _player->GetItemByGuid(guids[i + 1]) : NULL;

    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;
    }

    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 == SOCKET_COLOR_META && GemProps[i]->color != SOCKET_COLOR_META ||
            itemTarget->GetProto()->Socket[i].Color != SOCKET_COLOR_META && GemProps[i]->color == SOCKET_COLOR_META ) )
            return;
    }

    for(int i = 0; i < 3; ++i)                              //get new and old enchantments
    {
        GemEnchants[i] = (GemProps[i]) ? GemProps[i]->spellitemenchantement : 0;
        OldEnchants[i] = itemTarget->GetEnchantmentId(EnchantmentSlot(SOCK_ENCHANTMENT_SLOT+i));
    }

    // check unique-equipped conditions
    for(int i = 0; i < 3; ++i)
    {
        if (Gems[i] && (Gems[i]->GetProto()->Flags & ITEM_FLAGS_UNIQUE_EQUIPPED))
        {
            // for equipped item check all equipment for duplicate equipped gems
            if(itemTarget->IsEquipped())
            {
                if(GetPlayer()->GetItemOrItemWithGemEquipped(Gems[i]->GetEntry()))
                {
                    _player->SendEquipError( EQUIP_ERR_ITEM_UNIQUE_EQUIPABLE, itemTarget, NULL );
                    return;
                }
            }

            // continue check for case when attempt add 2 similar unique equipped gems in one item.
            for (int j = 0; j < 3; ++j)
            {
                if ((i != j) && (Gems[j]) && (Gems[i]->GetProto()->ItemId == Gems[j]->GetProto()->ItemId))
                {
                    _player->SendEquipError( EQUIP_ERR_ITEM_UNIQUE_EQUIPPABLE_SOCKETED, itemTarget, NULL );
                    return;
                }
            }
            for (int j = 0; j < 3; ++j)
            {
                if (OldEnchants[j])
                {
                    SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(OldEnchants[j]);
                    if(!enchantEntry)
                        continue;

                    if ((enchantEntry->GemID == Gems[i]->GetProto()->ItemId) && (i != j))
                    {
                        _player->SendEquipError( EQUIP_ERR_ITEM_UNIQUE_EQUIPPABLE_SOCKETED, itemTarget, NULL );
                        return;
                    }
                }
            }
        }
    }

    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->SetEnchantment(EnchantmentSlot(SOCK_ENCHANTMENT_SLOT+i), GemEnchants[i],0,0);
            if(Item* guidItem = _player->GetItemByGuid(guids[i + 1]))
                _player->DestroyItem(guidItem->GetBagSlot(), guidItem->GetSlot(), 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->SetEnchantment(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)
}
示例#8
0
void WorldSession::SendUpdateTrade(bool trader_data /*= true*/)
{
    TradeData* view_trade = trader_data ? _player->GetTradeData()->GetTraderData() : _player->GetTradeData();

    ByteBuffer itemData(7*2 + 7*4 + 3*4 + 3*4 + 1);

    uint8 count = 0;
    for (uint8 i = 0; i < TRADE_SLOT_COUNT; ++i)
        if (view_trade->GetItem(TradeSlots(i)))
            ++count;

    WorldPacket data(SMSG_TRADE_STATUS_EXTENDED, 4*6 + 8 + 1 + 3 + count * 70);
    data << uint32(0);                                      // this value must be equal to value from TRADE_STATUS_OPEN_WINDOW status packet (different value for different players to block multiple trades?)
    data << uint32(0);                                      // unk 2
    data << uint64(view_trade->GetMoney());                 // trader gold
    data << uint32(view_trade->GetSpell());                 // spell casted on lowest slot item
    data << uint32(TRADE_SLOT_COUNT);                       // trade slots count/number?, = next field in most cases
    data << uint32(0);                                      // unk 5
    data << uint8(trader_data);                             // 1 means traders data, 0 means own
    data << uint32(TRADE_SLOT_COUNT);                       // trade slots count/number?, = prev field in most cases
    data.WriteBits(count, 22);

    for (uint8 i = 0; i < TRADE_SLOT_COUNT; ++i)
    {
        Item* item = view_trade->GetItem(TradeSlots(i));
        if (!item)
            continue;

        ObjectGuid giftCreatorGuid = item->GetUInt64Value(ITEM_FIELD_GIFTCREATOR);
        ObjectGuid creatorGuid = item->GetUInt64Value(ITEM_FIELD_CREATOR);

        data.WriteBit(giftCreatorGuid[7]);
        data.WriteBit(giftCreatorGuid[1]);
        bool notWrapped = data.WriteBit(!item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_WRAPPED));
        data.WriteBit(giftCreatorGuid[3]);

        if (notWrapped)
        {
            data.WriteBit(creatorGuid[7]);
            data.WriteBit(creatorGuid[1]);
            data.WriteBit(creatorGuid[4]);
            data.WriteBit(creatorGuid[6]);
            data.WriteBit(creatorGuid[2]);
            data.WriteBit(creatorGuid[3]);
            data.WriteBit(creatorGuid[5]);
            data.WriteBit(item->GetTemplate()->LockID != 0);
            data.WriteBit(creatorGuid[0]);

            itemData.WriteByteSeq(creatorGuid[1]);

            itemData << uint32(item->GetEnchantmentId(PERM_ENCHANTMENT_SLOT));
            for (uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+MAX_GEM_SOCKETS /*3*/; ++enchant_slot)
                itemData << uint32(item->GetEnchantmentId(EnchantmentSlot(enchant_slot)));
            itemData << uint32(item->GetUInt32Value(ITEM_FIELD_MAXDURABILITY));

            itemData.WriteByteSeq(creatorGuid[6]);
            itemData.WriteByteSeq(creatorGuid[2]);
            itemData.WriteByteSeq(creatorGuid[7]);
            itemData.WriteByteSeq(creatorGuid[4]);

            itemData << uint32(item->GetEnchantmentId(REFORGE_ENCHANTMENT_SLOT));
            itemData << uint32(item->GetUInt32Value(ITEM_FIELD_DURABILITY));
            itemData << uint32(item->GetItemRandomPropertyId());

            itemData.WriteByteSeq(creatorGuid[3]);

            itemData << uint32(0); // unk7

            itemData.WriteByteSeq(creatorGuid[0]);

            itemData << uint32(item->GetSpellCharges());
            itemData << uint32(item->GetItemSuffixFactor());

            itemData.WriteByteSeq(creatorGuid[5]);
        }

        data.WriteBit(giftCreatorGuid[6]);
        data.WriteBit(giftCreatorGuid[4]);
        data.WriteBit(giftCreatorGuid[2]);
        data.WriteBit(giftCreatorGuid[0]);
        data.WriteBit(giftCreatorGuid[5]);

        itemData.WriteByteSeq(giftCreatorGuid[6]);
        itemData.WriteByteSeq(giftCreatorGuid[1]);
        itemData.WriteByteSeq(giftCreatorGuid[7]);
        itemData.WriteByteSeq(giftCreatorGuid[4]);

        itemData << uint32(item->GetTemplate()->ItemId);

        itemData.WriteByteSeq(giftCreatorGuid[0]);

        itemData << uint32(item->GetCount());

        itemData.WriteByteSeq(giftCreatorGuid[5]);

        itemData << uint8(i);

        itemData.WriteByteSeq(giftCreatorGuid[2]);
        itemData.WriteByteSeq(giftCreatorGuid[3]);
    }

    data.FlushBits();
    data.append(itemData);

    SendPacket(&data);
}
示例#9
0
void WorldSession::SendUpdateTrade(bool trader_state /*= true*/)
{
    TradeData* view_trade = trader_state ? _player->GetTradeData()->GetTraderData() : _player->GetTradeData();

    WorldPacket data(SMSG_TRADE_STATUS_EXTENDED, (100));    // guess size
    data << uint32(0);                                      // added in 2.4.0, this value must be equal to value from TRADE_STATUS_OPEN_WINDOW status packet (different value for different players to block multiple trades?)
    data << uint32(0);                                      // unk 2
    data << uint64(view_trade->GetMoney());                 // trader gold
    data << uint32(view_trade->GetSpell());                 // spell casted on lowest slot item
    data << uint32(TRADE_SLOT_COUNT);                       // trade slots count/number?
    data << uint32(0);                                      // unk 5
    data << uint8(trader_state ? 1 : 0);                    // send trader or own trade windows state (last need for proper show spell apply to non-trade slot)
    data << uint32(TRADE_SLOT_COUNT);                       // trade slots count/number?

    uint8 itemCount = 0;
    for (uint8 i = 0; i < TRADE_SLOT_COUNT; ++i)
        if (Item* item = view_trade->GetItem(TradeSlots(i)))
            ++itemCount;

    data.WriteBits(itemCount, 22);

    for (uint8 i = 0; i < TRADE_SLOT_COUNT; ++i)
    {
        if (Item* item = view_trade->GetItem(TradeSlots(i)))
        {
            ObjectGuid creatorGuid = item->GetGuidValue(ITEM_FIELD_CREATOR);
            ObjectGuid giftCreatorGuid = item->GetGuidValue(ITEM_FIELD_GIFTCREATOR);

            data.WriteGuidMask<7, 1>(giftCreatorGuid);
            data.WriteBit(!item->HasFlag(ITEM_FIELD_FLAGS, ITEM_DYNFLAG_WRAPPED));
            data.WriteGuidMask<3>(giftCreatorGuid);
            if (!item->HasFlag(ITEM_FIELD_FLAGS, ITEM_DYNFLAG_WRAPPED))
            {
                data.WriteGuidMask<7, 1, 4, 6, 2, 3, 5>(creatorGuid);
                data.WriteBit(item->GetProto()->LockID && !item->HasFlag(ITEM_FIELD_FLAGS, ITEM_DYNFLAG_UNLOCKED));
                data.WriteGuidMask<0>(creatorGuid);
            }
            data.WriteGuidMask<6, 4, 2, 0, 5>(giftCreatorGuid);
        }
    }

    for (uint8 i = 0; i < TRADE_SLOT_COUNT; ++i)
    {
        if (Item* item = view_trade->GetItem(TradeSlots(i)))
        {
            ObjectGuid creatorGuid = item->GetGuidValue(ITEM_FIELD_CREATOR);
            ObjectGuid giftCreatorGuid = item->GetGuidValue(ITEM_FIELD_GIFTCREATOR);

            if (!item->HasFlag(ITEM_FIELD_FLAGS, ITEM_DYNFLAG_WRAPPED))
            {
                data.WriteGuidBytes<1>(creatorGuid);
                data << uint32(item->GetEnchantmentId(PERM_ENCHANTMENT_SLOT));
                for (uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT + MAX_GEM_SOCKETS; ++enchant_slot)
                    data << uint32(item->GetEnchantmentId(EnchantmentSlot(enchant_slot)));
                data << uint32(item->GetUInt32Value(ITEM_FIELD_MAXDURABILITY));
                data.WriteGuidBytes<6, 2, 7, 4>(creatorGuid);
                data << uint32(item->GetEnchantmentId(REFORGE_ENCHANTMENT_SLOT));                                  // reforge Id
                data << uint32(item->GetUInt32Value(ITEM_FIELD_DURABILITY));
                data << uint32(item->GetItemRandomPropertyId());
                data.WriteGuidBytes<3>(creatorGuid);
                data << uint32(0);                                  // unk
                data.WriteGuidBytes<0>(creatorGuid);
                data << uint32(item->GetSpellCharges());            // charges
                data << uint32(item->GetItemSuffixFactor());
                data.WriteGuidBytes<5>(creatorGuid);
            }

            data.WriteGuidBytes<6, 1, 7, 4>(giftCreatorGuid);
            data << uint32(item->GetProto()->ItemId);               // entry
            data.WriteGuidBytes<0>(giftCreatorGuid);
            data << uint32(item->GetCount());                       // stack count
            data.WriteGuidBytes<5>(giftCreatorGuid);
            data << uint8(i);                                       // slot id
            data.WriteGuidBytes<2, 3>(giftCreatorGuid);
        }
    }

    SendPacket(&data);
}
示例#10
0
            void HandleAfterHit()
            {
                if (_stackAmount < 5)
                    return;

                Player* player = GetCaster()->ToPlayer();

                if (Unit* target = GetHitUnit())
                {

                    Item* item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND);

                    if (item == GetCastItem())
                        item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND);

                    if (!item)
                        return;

                    // item combat enchantments
                    for (uint8 slot = 0; slot < MAX_ENCHANTMENT_SLOT; ++slot)
                    {
                        SpellItemEnchantmentEntry const* enchant = sSpellItemEnchantmentStore.LookupEntry(item->GetEnchantmentId(EnchantmentSlot(slot)));
                        if (!enchant)
                            continue;

                        for (uint8 s = 0; s < 3; ++s)
                        {
                            if (enchant->type[s] != ITEM_ENCHANTMENT_TYPE_COMBAT_SPELL)
                                continue;

                            SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(enchant->spellid[s]);
                            if (!spellInfo)
                            {
                                sLog->outError("Player::CastItemCombatSpell Enchant %i, player (Name: %s, GUID: %u) cast unknown spell %i", enchant->ID, player->GetName(), player->GetGUIDLow(), enchant->spellid[s]);
                                continue;
                            }

                            // Proc only rogue poisons
                            if (spellInfo->SpellFamilyName != SPELLFAMILY_ROGUE || spellInfo->Dispel != DISPEL_POISON)
                                continue;

                            // Do not reproc deadly
                            if (spellInfo->SpellFamilyFlags.IsEqual(0x10000, 0x80000, 0))
                                continue;

                            if (spellInfo->IsPositive())
                                player->CastSpell(player, enchant->spellid[s], true, item);
                            else
                                player->CastSpell(target, enchant->spellid[s], true, item);
                        }
                    }
                }
            }
示例#11
0
void WorldSession::HandleSocketOpcode(WorldPacket& recv_data)
{
    DEBUG_LOG("WORLD: CMSG_SOCKET_GEMS");

    ObjectGuid itemGuid;
    ObjectGuid gemGuids[MAX_GEM_SOCKETS];

    recv_data >> itemGuid;
    if (!itemGuid.IsItem())
        return;

    for (int i = 0; i < MAX_GEM_SOCKETS; ++i)
        recv_data >> gemGuids[i];

    // cheat -> tried to socket same gem multiple times
    for (int i = 0; i < MAX_GEM_SOCKETS; ++i)
    {
        ObjectGuid gemGuid = gemGuids[i];
        if (!gemGuid)
            continue;

        if (!gemGuid.IsItem())
            return;

        for (int j = i + 1; j < MAX_GEM_SOCKETS; ++j)
            if (gemGuids[j] == gemGuid)
                return;
    }

    Item* itemTarget = _player->GetItemByGuid(itemGuid);
    if (!itemTarget)                                        // missing item to socket
        return;

    ItemPrototype const* itemProto = itemTarget->GetProto();
    if (!itemProto)
        return;

    // this slot is excepted when applying / removing meta gem bonus
    uint8 slot = itemTarget->IsEquipped() ? itemTarget->GetSlot() : uint8(NULL_SLOT);

    Item* Gems[MAX_GEM_SOCKETS];
    for (int i = 0; i < MAX_GEM_SOCKETS; ++i)
        Gems[i] = gemGuids[i] ? _player->GetItemByGuid(gemGuids[i]) : NULL;

    GemPropertiesEntry const* GemProps[MAX_GEM_SOCKETS];
    for (int i = 0; i < MAX_GEM_SOCKETS; ++i)               // get geminfo from dbc storage
        GemProps[i] = (Gems[i]) ? sGemPropertiesStore.LookupEntry(Gems[i]->GetProto()->GemProperties) : NULL;

    for (int i = 0; i < MAX_GEM_SOCKETS; ++i)               // check for hack maybe
    {
        if (!GemProps[i])
            continue;

        // tried to put gem in socket where no socket exists
        if (!itemProto->Socket[i].Color)
            return;

        // tried to put normal gem in meta socket
        if (itemProto->Socket[i].Color == SOCKET_COLOR_META && GemProps[i]->color != SOCKET_COLOR_META)
            return;

        // tried to put meta gem in normal socket
        if (itemProto->Socket[i].Color != SOCKET_COLOR_META && GemProps[i]->color == SOCKET_COLOR_META)
            return;
    }

    uint32 GemEnchants[MAX_GEM_SOCKETS];
    uint32 OldEnchants[MAX_GEM_SOCKETS];
    for (int i = 0; i < MAX_GEM_SOCKETS; ++i)               // get new and old enchantments
    {
        GemEnchants[i] = (GemProps[i]) ? GemProps[i]->spellitemenchantement : 0;
        OldEnchants[i] = itemTarget->GetEnchantmentId(EnchantmentSlot(SOCK_ENCHANTMENT_SLOT + i));
    }

    // check unique-equipped conditions
    for (int i = 0; i < MAX_GEM_SOCKETS; ++i)
    {
        if (!Gems[i])
            continue;

        // continue check for case when attempt add 2 similar unique equipped gems in one item.
        ItemPrototype const* iGemProto = Gems[i]->GetProto();

        // unique item (for new and already placed bit removed enchantments
        if (iGemProto->Flags & ITEM_FLAG_UNIQUE_EQUIPPED)
        {
            for (int j = 0; j < MAX_GEM_SOCKETS; ++j)
            {
                if (i == j)                                 // skip self
                    continue;

                if (Gems[j])
                {
                    if (iGemProto->ItemId == Gems[j]->GetEntry())
                    {
                        _player->SendEquipError(EQUIP_ERR_ITEM_UNIQUE_EQUIPPABLE_SOCKETED, itemTarget, NULL);
                        return;
                    }
                }
                else if (OldEnchants[j])
                {
                    if (SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(OldEnchants[j]))
                    {
                        if (iGemProto->ItemId == enchantEntry->GemID)
                        {
                            _player->SendEquipError(EQUIP_ERR_ITEM_UNIQUE_EQUIPPABLE_SOCKETED, itemTarget, NULL);
                            return;
                        }
                    }
                }
            }
        }

        // for equipped item check all equipment for duplicate equipped gems
        if (itemTarget->IsEquipped())
        {
            if (InventoryResult res = _player->CanEquipUniqueItem(Gems[i], slot))
            {
                _player->SendEquipError(res, itemTarget, NULL);
                return;
            }
        }
    }

    bool 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 + MAX_GEM_SOCKETS; ++enchant_slot)
        _player->ApplyEnchantment(itemTarget, EnchantmentSlot(enchant_slot), false);

    for (int i = 0; i < MAX_GEM_SOCKETS; ++i)
    {
        if (GemEnchants[i])
        {
            itemTarget->SetEnchantment(EnchantmentSlot(SOCK_ENCHANTMENT_SLOT + i), GemEnchants[i], 0, 0);
            if (Item* guidItem = gemGuids[i] ? _player->GetItemByGuid(gemGuids[i]) : NULL)
                _player->DestroyItem(guidItem->GetBagSlot(), guidItem->GetSlot(), true);
        }
    }

    for (uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT + MAX_GEM_SOCKETS; ++enchant_slot)
        _player->ApplyEnchantment(itemTarget, EnchantmentSlot(enchant_slot), true);

    bool SocketBonusToBeActivated = itemTarget->GemsFitSockets();// current socketbonus state
    if (SocketBonusActivated != SocketBonusToBeActivated)   // if there was a change...
    {
        _player->ApplyEnchantment(itemTarget, BONUS_ENCHANTMENT_SLOT, false);
        itemTarget->SetEnchantment(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)
}
示例#12
0
int32 Item::GetReforgableStat(ItemModType statType) const
{
    ItemTemplate const* proto = GetTemplate();
    for (uint32 i = 0; i < MAX_ITEM_PROTO_STATS; ++i)
        if (proto->ItemStat[i].ItemStatType == statType)
            return proto->ItemStat[i].ItemStatValue;

    int32 randomPropId = GetItemRandomPropertyId();
    if (!randomPropId)
        return 0;

    if (randomPropId < 0)
    {
        ItemRandomSuffixEntry const* randomSuffix = sItemRandomSuffixStore.LookupEntry(-randomPropId);
        if (!randomSuffix)
            return 0;

        for (uint32 e = PROP_ENCHANTMENT_SLOT_0; e <= PROP_ENCHANTMENT_SLOT_4; ++e)
            if (SpellItemEnchantmentEntry const* enchant = sSpellItemEnchantmentStore.LookupEntry(GetEnchantmentId(EnchantmentSlot(e))))
                for (uint32 f = 0; f < MAX_ITEM_ENCHANTMENT_EFFECTS; ++f)
                    if (enchant->type[f] == ITEM_ENCHANTMENT_TYPE_STAT && enchant->spellid[f] == statType)
                        for (int k = 0; k < 5; ++k)
                            if (randomSuffix->enchant_id[k] == enchant->ID)
                                return int32((randomSuffix->prefix[k] * GetItemSuffixFactor()) / 10000);
    }
    else
    {
        ItemRandomPropertiesEntry const* randomProp = sItemRandomPropertiesStore.LookupEntry(randomPropId);
        if (!randomProp)
            return 0;

        for (uint32 e = PROP_ENCHANTMENT_SLOT_0; e <= PROP_ENCHANTMENT_SLOT_4; ++e)
            if (SpellItemEnchantmentEntry const* enchant = sSpellItemEnchantmentStore.LookupEntry(GetEnchantmentId(EnchantmentSlot(e))))
                for (uint32 f = 0; f < MAX_ITEM_ENCHANTMENT_EFFECTS; ++f)
                    if (enchant->type[f] == ITEM_ENCHANTMENT_TYPE_STAT && enchant->spellid[f] == statType)
                        for (int k = 0; k < MAX_ITEM_ENCHANTMENT_EFFECTS; ++k)
                            if (randomProp->enchant_id[k] == enchant->ID)
                                return int32(enchant->amount[k]);
    }

    return 0;
}
示例#13
0
void WorldSession::HandleSocketGems(WorldPackets::Item::SocketGems& socketGems)
{
    if (!socketGems.ItemGuid)
        return;

    //cheat -> tried to socket same gem multiple times
    if ((!socketGems.GemItem[0].IsEmpty() && (socketGems.GemItem[0] == socketGems.GemItem[1] || socketGems.GemItem[0] == socketGems.GemItem[2])) ||
        (!socketGems.GemItem[1].IsEmpty() && (socketGems.GemItem[1] == socketGems.GemItem[2])))
        return;

    Item* itemTarget = _player->GetItemByGuid(socketGems.ItemGuid);
    if (!itemTarget)                                         //missing item to socket
        return;

    ItemTemplate const* itemProto = itemTarget->GetTemplate();
    if (!itemProto)
        return;

    //this slot is excepted when applying / removing meta gem bonus
    uint8 slot = itemTarget->IsEquipped() ? itemTarget->GetSlot() : uint8(NULL_SLOT);

    Item* gems[MAX_GEM_SOCKETS];
    memset(gems, 0, sizeof(gems));
    ItemDynamicFieldGems gemData[MAX_GEM_SOCKETS];
    memset(gemData, 0, sizeof(gemData));
    GemPropertiesEntry const* gemProperties[MAX_GEM_SOCKETS];
    memset(gemProperties, 0, sizeof(gemProperties));
    ItemDynamicFieldGems const* oldGemData[MAX_GEM_SOCKETS];
    memset(oldGemData, 0, sizeof(oldGemData));
    for (uint32 i = 0; i < MAX_GEM_SOCKETS; ++i)
    {
        if (Item* gem = _player->GetItemByGuid(socketGems.GemItem[i]))
        {
            gems[i] = gem;
            gemData[i].ItemId = gem->GetEntry();
            gemData[i].Context = gem->GetUInt32Value(ITEM_FIELD_CONTEXT);
            for (std::size_t b = 0; b < gem->GetDynamicValues(ITEM_DYNAMIC_FIELD_BONUSLIST_IDS).size() && b < 16; ++b)
                gemData[i].BonusListIDs[b] = gem->GetDynamicValue(ITEM_DYNAMIC_FIELD_BONUSLIST_IDS, b);

            gemProperties[i] = sGemPropertiesStore.LookupEntry(gem->GetTemplate()->GetGemProperties());
        }

        oldGemData[i] = itemTarget->GetGem(i);
    }

    // Find first prismatic socket
    uint32 firstPrismatic = 0;
    while (firstPrismatic < MAX_GEM_SOCKETS && itemTarget->GetSocketColor(firstPrismatic))
        ++firstPrismatic;

    for (uint32 i = 0; i < MAX_GEM_SOCKETS; ++i)                //check for hack maybe
    {
        if (!gemProperties[i])
            continue;

        // tried to put gem in socket where no socket exists (take care about prismatic sockets)
        if (!itemTarget->GetSocketColor(i))
        {
            // no prismatic socket
            if (!itemTarget->GetEnchantmentId(PRISMATIC_ENCHANTMENT_SLOT))
                return;

            if (i != firstPrismatic)
                return;
        }

        // Gem must match socket color
        if (SocketColorToGemTypeMask[itemTarget->GetSocketColor(i)] != gemProperties[i]->Type)
        {
            // unless its red, blue, yellow or prismatic
            if (!(SocketColorToGemTypeMask[itemTarget->GetSocketColor(i)] & SOCKET_COLOR_PRISMATIC) || !(gemProperties[i]->Type & SOCKET_COLOR_PRISMATIC))
                return;
        }
    }

    // check unique-equipped conditions
    for (uint32 i = 0; i < MAX_GEM_SOCKETS; ++i)
    {
        if (!gems[i])
            continue;

        // continue check for case when attempt add 2 similar unique equipped gems in one item.
        ItemTemplate const* iGemProto = gems[i]->GetTemplate();

        // unique item (for new and already placed bit removed enchantments
        if (iGemProto->GetFlags() & ITEM_FLAG_UNIQUE_EQUIPPABLE)
        {
            for (uint32 j = 0; j < MAX_GEM_SOCKETS; ++j)
            {
                if (i == j)                                    // skip self
                    continue;

                if (gems[j])
                {
                    if (iGemProto->GetId() == gems[j]->GetEntry())
                    {
                        _player->SendEquipError(EQUIP_ERR_ITEM_UNIQUE_EQUIPPABLE_SOCKETED, itemTarget, NULL);
                        return;
                    }
                }
                else if (oldGemData[j])
                {
                    if (iGemProto->GetId() == oldGemData[j]->ItemId)
                    {
                        _player->SendEquipError(EQUIP_ERR_ITEM_UNIQUE_EQUIPPABLE_SOCKETED, itemTarget, NULL);
                        return;
                    }
                }
            }
        }

        // unique limit type item
        int32 limit_newcount = 0;
        if (iGemProto->GetItemLimitCategory())
        {
            if (ItemLimitCategoryEntry const* limitEntry = sItemLimitCategoryStore.LookupEntry(iGemProto->GetItemLimitCategory()))
            {
                // NOTE: limitEntry->mode is not checked because if item has limit then it is applied in equip case
                for (int j = 0; j < MAX_GEM_SOCKETS; ++j)
                {
                    if (gems[j])
                    {
                        // new gem
                        if (iGemProto->GetItemLimitCategory() == gems[j]->GetTemplate()->GetItemLimitCategory())
                            ++limit_newcount;
                    }
                    else if (oldGemData[j])
                    {
                        // existing gem
                        if (ItemTemplate const* jProto = sObjectMgr->GetItemTemplate(oldGemData[j]->ItemId))
                            if (iGemProto->GetItemLimitCategory() == jProto->GetItemLimitCategory())
                                ++limit_newcount;
                    }
                }

                if (limit_newcount > 0 && uint32(limit_newcount) > limitEntry->Quantity)
                {
                    _player->SendEquipError(EQUIP_ERR_ITEM_UNIQUE_EQUIPPABLE_SOCKETED, itemTarget, NULL);
                    return;
                }
            }
        }

        // for equipped item check all equipment for duplicate equipped gems
        if (itemTarget->IsEquipped())
        {
            if (InventoryResult res = _player->CanEquipUniqueItem(gems[i], slot, std::max(limit_newcount, 0)))
            {
                _player->SendEquipError(res, itemTarget, NULL);
                return;
            }
        }
    }

    bool 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 mods - gem can change item level
    if (itemTarget->IsEquipped())
        _player->_ApplyItemMods(itemTarget, itemTarget->GetSlot(), false);

    for (uint16 i = 0; i < MAX_GEM_SOCKETS; ++i)
    {
        if (gems[i])
        {
            uint32 gemScalingLevel = _player->getLevel();
            if (uint32 fixedLevel = gems[i]->GetModifier(ITEM_MODIFIER_SCALING_STAT_DISTRIBUTION_FIXED_LEVEL))
                gemScalingLevel = fixedLevel;

            itemTarget->SetGem(i, &gemData[i], gemScalingLevel);

            if (gemProperties[i] && gemProperties[i]->EnchantID)
                itemTarget->SetEnchantment(EnchantmentSlot(SOCK_ENCHANTMENT_SLOT + i), gemProperties[i]->EnchantID, 0, 0, _player->GetGUID());

            uint32 gemCount = 1;
            _player->DestroyItemCount(gems[i], gemCount, true);
        }
    }

    if (itemTarget->IsEquipped())
        _player->_ApplyItemMods(itemTarget, itemTarget->GetSlot(), true);

    if (Item* childItem = _player->GetChildItemByGuid(itemTarget->GetChildItem()))
    {
        if (childItem->IsEquipped())
            _player->_ApplyItemMods(childItem, childItem->GetSlot(), false);
        childItem->CopyArtifactDataFromParent(itemTarget);
        if (childItem->IsEquipped())
            _player->_ApplyItemMods(childItem, childItem->GetSlot(), true);
    }

    bool SocketBonusToBeActivated = itemTarget->GemsFitSockets();//current socketbonus state
    if (SocketBonusActivated ^ SocketBonusToBeActivated)     //if there was a change...
    {
        _player->ApplyEnchantment(itemTarget, BONUS_ENCHANTMENT_SLOT, false);
        itemTarget->SetEnchantment(BONUS_ENCHANTMENT_SLOT, (SocketBonusToBeActivated ? itemTarget->GetTemplate()->GetSocketBonus() : 0), 0, 0, _player->GetGUID());
        _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)

    _player->RemoveTradeableItem(itemTarget);
    itemTarget->ClearSoulboundTradeable(_player);           // clear tradeable flag

    itemTarget->SendUpdateSockets();
}
示例#14
0
void WorldSession::SendUpdateTrade(bool trader_data /*= true*/)
{
    TradeData* view_trade = trader_data ? _player->GetTradeData()->GetTraderData() : _player->GetTradeData();

    WorldPacket data(SMSG_TRADE_STATUS_EXTENDED, 1+4+4+4+4+4+7*(1+4+4+4+4+8+4+4+4+4+8+4+4+4+4+4+4));

    data << uint32(0);
    data << uint32(0);
    data << uint8(1);
    data << uint32(0);
    data << uint32(0);
    data << uint32(0);  // trade ID? has to match what we sent in TRADE_STATUS for TRADE_STATUS_OPEN_WINDOW
    data << uint32(TRADE_SLOT_COUNT); // slot count
    data << uint64(view_trade->GetMoney()); // trade money
    data << uint32(0);

    for (uint8 i = 0; i < TRADE_SLOT_COUNT; ++i)
    {
        uint32 id = 0;
        if (Item* item = view_trade->GetItem(TradeSlots(i)))
        {
            uint32 id = item->GetTemplate()->ItemId;
            data << uint32(0);
            data << uint64(item->GetUInt64Value(ITEM_FIELD_CREATOR)); // Creator GUID
            data << uint32(item->GetEnchantmentId(PERM_ENCHANTMENT_SLOT)); // Permanent Enchantment
            data << uint32(id);
            data << uint32(item->GetEnchantmentId(EnchantmentSlot(SOCK_ENCHANTMENT_SLOT+1))); // First gem socket enchant
            data << uint32(item->GetUInt32Value(ITEM_FIELD_DURABILITY)); // Current Durability
            data << uint32(0);
            data << uint8(0); // If 1, then the item wont display any sockets, even if it has them
            data << uint64(0);
            data << uint32(0);
            data << uint8(i);   // trade slot number
            data << uint32(item->GetUInt32Value(ITEM_FIELD_MAXDURABILITY)); // Max durability
            data << uint32(item->GetCount()); // Stack count
            data << uint32(0);
            data << uint32(item->GetEnchantmentId(TEMP_ENCHANTMENT_SLOT)); // Temporal enchantment
            data << uint32(item->GetEnchantmentId(EnchantmentSlot(SOCK_ENCHANTMENT_SLOT+2))); // Second socket gem
            data << uint32(item->GetEnchantmentId(EnchantmentSlot(SOCK_ENCHANTMENT_SLOT+3))); // Third socket gem
            data << uint32(0);
        }
        else
        {
            data << uint32(0);
            data << uint64(0);
            data << uint32(0);
            data << uint32(id);
            data << uint32(0);
            data << uint32(0);
            data << uint32(0);
            data << uint8(0);
            data << uint64(0);
            data << uint32(0);
            data << uint8(i);   // trade slot number
            data << uint32(0);
            data << uint32(0);
            data << uint32(0);
            data << uint32(0);
            data << uint32(0);
            data << uint32(0);
            data << uint32(0);
        }
    }
    SendPacket(&data);
}
示例#15
0
void WorldSession::SendUpdateTrade(bool trader_data /*= true*/)
{
    TradeData* view_trade = trader_data ? _player->GetTradeData()->GetTraderData() : _player->GetTradeData();

    WorldPacket data(SMSG_TRADE_STATUS_EXTENDED, 1+4+4+4+4+4+7*(1+4+4+4+4+8+4+4+4+4+8+4+4+4+4+4+4));

    data << uint32(0);
    data << uint32(0);
    data << uint8(1);
    data << uint32(0);
    data << uint32(0);
    data << uint32(0);  // trade ID? has to match what we sent in TRADE_STATUS for TRADE_STATUS_OPEN_WINDOW
    data << uint32(TRADE_SLOT_COUNT); // slot count
    data << uint64(view_trade->GetMoney()); // trade money
    data << uint32(0);
    // old structure. meaning of new structure fields has to be researched
    /*data << uint8(trader_data);                             // 1 means traders data, 0 means own
    data << uint32(0);                                      // added in 2.4.0, this value must be equal to value from TRADE_STATUS_OPEN_WINDOW status packet (different value for different players to block multiple trades?)
    data << uint32(TRADE_SLOT_COUNT);                       // trade slots count/number?, = next field in most cases
    data << uint32(TRADE_SLOT_COUNT);                       // trade slots count/number?, = prev field in most cases
    data << uint32(view_trade->GetMoney());                 // trader gold
    data << uint32(view_trade->GetSpell());                 // spell casted on lowest slot item*/

    for (uint8 i = 0; i < TRADE_SLOT_COUNT; ++i)
    {
        uint32 id = 0;
        if (Item* item = view_trade->GetItem(TradeSlots(i)))
        {
            uint32 id = item->GetTemplate()->ItemId;
            data << uint32(0);
            data << uint64(item->GetUInt64Value(ITEM_FIELD_CREATOR)); // Creator GUID
            data << uint32(item->GetEnchantmentId(PERM_ENCHANTMENT_SLOT)); // Permanent Enchantment
            data << uint32(id);
            data << uint32(item->GetEnchantmentId(EnchantmentSlot(SOCK_ENCHANTMENT_SLOT+1))); // First gem socket enchant
            data << uint32(item->GetUInt32Value(ITEM_FIELD_DURABILITY)); // Current Durability
            data << uint32(0);
            data << uint8(0); // If 1, then the item wont display any sockets, even if it has them
            data << uint64(0);
            data << uint32(0);
            data << uint8(i);   // trade slot number
            data << uint32(item->GetUInt32Value(ITEM_FIELD_MAXDURABILITY)); // Max durability
            data << uint32(item->GetCount()); // Stack count
            data << uint32(0);
            data << uint32(item->GetEnchantmentId(TEMP_ENCHANTMENT_SLOT)); // Temporal enchantment
            data << uint32(item->GetEnchantmentId(EnchantmentSlot(SOCK_ENCHANTMENT_SLOT+2))); // Second socket gem
            data << uint32(item->GetEnchantmentId(EnchantmentSlot(SOCK_ENCHANTMENT_SLOT+3))); // Third socket gem
            data << uint32(0);
        } else
            data << uint32(0);
            data << uint64(0);
            data << uint32(0);
            data << uint32(id);
            data << uint32(0);
            data << uint32(0);
            data << uint32(0);
            data << uint8(0);
            data << uint64(0);
            data << uint32(0);
            data << uint8(i);   // trade slot number
            data << uint32(0);
            data << uint32(0);
            data << uint32(0);
            data << uint32(0);
            data << uint32(0);
            data << uint32(0);
            data << uint32(0);

        // old structure
        /*data << uint8(i);                                  // trade slot number, if not specified, then end of packet

        if (Item* item = view_trade->GetItem(TradeSlots(i)))
        {
            data << uint32(item->GetTemplate()->ItemId);       // entry
            data << uint32(item->GetTemplate()->DisplayInfoID);// display id
            data << uint32(item->GetCount());               // stack count
                                                            // wrapped: hide stats but show giftcreator name
            data << uint32(item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_WRAPPED) ? 1 : 0);
            data << uint64(item->GetUInt64Value(ITEM_FIELD_GIFTCREATOR));
                                                            // perm. enchantment and gems
            data << uint32(item->GetEnchantmentId(PERM_ENCHANTMENT_SLOT));
            for (uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+MAX_GEM_SOCKETS; ++enchant_slot)
                data << uint32(item->GetEnchantmentId(EnchantmentSlot(enchant_slot)));
                                                            // creator
            data << uint64(item->GetUInt64Value(ITEM_FIELD_CREATOR));
            data << uint32(item->GetSpellCharges());        // charges
            data << uint32(item->GetItemSuffixFactor());    // SuffixFactor
            data << uint32(item->GetItemRandomPropertyId());// random properties id
            data << uint32(item->GetTemplate()->LockID);       // lock id
                                                            // max durability
            data << uint32(item->GetUInt32Value(ITEM_FIELD_MAXDURABILITY));
                                                            // durability
            data << uint32(item->GetUInt32Value(ITEM_FIELD_DURABILITY));
        }
        else
        {
            for (uint8 j = 0; j < 18; ++j)
                data << uint32(0);
        }*/
    }
    SendPacket(&data);
}
示例#16
0
void WorldSession::SendUpdateTrade()
{
    Item *item = NULL;

    if( !_player || !_player->pTrader )
        return;

    // reset trade status
    if (_player->acceptTrade)
    {
        _player->acceptTrade = false;
        SendTradeStatus(TRADE_STATUS_BACK_TO_TRADE);
    }

    if (_player->pTrader->acceptTrade)
    {
        _player->pTrader->acceptTrade = false;
        _player->pTrader->GetSession()->SendTradeStatus(TRADE_STATUS_BACK_TO_TRADE);
    }

    WorldPacket data(SMSG_TRADE_STATUS_EXTENDED, (100));    // guess size
    data << (uint8 ) 1;                                     // can be different (only seen 0 and 1)
    data << (uint32) 0;                                     // added in 2.4.0, this value must be equal to value from TRADE_STATUS_OPEN_WINDOW status packet (different value for different players to block multiple trades?)
    data << (uint32) TRADE_SLOT_COUNT;                      // trade slots count/number?, = next field in most cases
    data << (uint32) TRADE_SLOT_COUNT;                      // trade slots count/number?, = prev field in most cases
    data << (uint32) _player->pTrader->tradeGold;           // trader gold
    data << (uint32) 0;                                     // spell casted on lowest slot item

    for(uint8 i = 0; i < TRADE_SLOT_COUNT; ++i)
    {
        item = (_player->pTrader->tradeItems[i] != NULL_SLOT ? _player->pTrader->GetItemByPos( _player->pTrader->tradeItems[i] ) : NULL);

        data << (uint8) i;                                  // trade slot number, if not specified, then end of packet

        if(item)
        {
            data << (uint32) item->GetProto()->ItemId;      // entry
                                                            // display id
            data << (uint32) item->GetProto()->DisplayInfoID;
                                                            // stack count
            data << (uint32) item->GetUInt32Value(ITEM_FIELD_STACK_COUNT);
            data << (uint32) 0;                             // probably gift=1, created_by=0?
                                                            // gift creator
            data << (uint64) item->GetUInt64Value(ITEM_FIELD_GIFTCREATOR);
            data << (uint32) item->GetEnchantmentId(PERM_ENCHANTMENT_SLOT);
            for(uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+MAX_GEM_SOCKETS; ++enchant_slot)
                data << (uint32) item->GetEnchantmentId(EnchantmentSlot(enchant_slot));
                                                            // creator
            data << (uint64) item->GetUInt64Value(ITEM_FIELD_CREATOR);
            data << (uint32) item->GetSpellCharges();       // charges
            data << (uint32) item->GetItemSuffixFactor();   // SuffixFactor
                                                            // random properties id
            data << (uint32) item->GetItemRandomPropertyId();
            data << (uint32) item->GetProto()->LockID;      // lock id
                                                            // max durability
            data << (uint32) item->GetUInt32Value(ITEM_FIELD_MAXDURABILITY);
                                                            // durability
            data << (uint32) item->GetUInt32Value(ITEM_FIELD_DURABILITY);
        }
        else
        {
            for(uint8 j = 0; j < 18; j++)
                data << uint32(0);
        }
    }
    SendPacket(&data);
}
示例#17
0
void WorldSession::HandleSocketOpcode(WorldPacket& recvData)
{
    sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_SOCKET_GEMS");

    uint64 item_guid;
    uint64 gem_guids[MAX_GEM_SOCKETS];

    recvData >> item_guid;
    if (!item_guid)
        return;

    for (int i = 0; i < MAX_GEM_SOCKETS; ++i)
        recvData >> gem_guids[i];

    //cheat -> tried to socket same gem multiple times
    if ((gem_guids[0] && (gem_guids[0] == gem_guids[1] || gem_guids[0] == gem_guids[2])) ||
        (gem_guids[1] && (gem_guids[1] == gem_guids[2])))
        return;

    Item* itemTarget = _player->GetItemByGuid(item_guid);
    if (!itemTarget)                                         //missing item to socket
        return;

    ItemTemplate const* itemProto = itemTarget->GetTemplate();
    if (!itemProto)
        return;

    //this slot is excepted when applying / removing meta gem bonus
    uint8 slot = itemTarget->IsEquipped() ? itemTarget->GetSlot() : uint8(NULL_SLOT);

    Item* Gems[MAX_GEM_SOCKETS];
    for (int i = 0; i < MAX_GEM_SOCKETS; ++i)
        Gems[i] = gem_guids[i] ? _player->GetItemByGuid(gem_guids[i]) : NULL;

    GemPropertiesEntry const* GemProps[MAX_GEM_SOCKETS];
    for (int i = 0; i < MAX_GEM_SOCKETS; ++i)                //get geminfo from dbc storage
        GemProps[i] = (Gems[i]) ? sGemPropertiesStore.LookupEntry(Gems[i]->GetTemplate()->GemProperties) : NULL;

    for (int i = 0; i < MAX_GEM_SOCKETS; ++i)                //check for hack maybe
    {
        if (!GemProps[i])
            continue;

        // tried to put gem in socket where no socket exists (take care about prismatic sockets)
        if (!itemProto->Socket[i].Color)
        {
            // no prismatic socket
            if (!itemTarget->GetEnchantmentId(PRISMATIC_ENCHANTMENT_SLOT))
                return;

            // not first not-colored (not normaly used) socket
            if (i != 0 && !itemProto->Socket[i-1].Color && (i+1 >= MAX_GEM_SOCKETS || itemProto->Socket[i+1].Color))
                return;

            // ok, this is first not colored socket for item with prismatic socket
        }

        // tried to put normal gem in meta socket
        if (itemProto->Socket[i].Color == SOCKET_COLOR_META && GemProps[i]->color != SOCKET_COLOR_META)
            return;

        // tried to put meta gem in normal socket
        if (itemProto->Socket[i].Color != SOCKET_COLOR_META && GemProps[i]->color == SOCKET_COLOR_META)
            return;
    }

    uint32 GemEnchants[MAX_GEM_SOCKETS];
    uint32 OldEnchants[MAX_GEM_SOCKETS];
    for (int i = 0; i < MAX_GEM_SOCKETS; ++i)                //get new and old enchantments
    {
        GemEnchants[i] = (GemProps[i]) ? GemProps[i]->spellitemenchantement : 0;
        OldEnchants[i] = itemTarget->GetEnchantmentId(EnchantmentSlot(SOCK_ENCHANTMENT_SLOT+i));
    }

    // check unique-equipped conditions
    for (int i = 0; i < MAX_GEM_SOCKETS; ++i)
    {
        if (!Gems[i])
            continue;

        // continue check for case when attempt add 2 similar unique equipped gems in one item.
        ItemTemplate const* iGemProto = Gems[i]->GetTemplate();

        // unique item (for new and already placed bit removed enchantments
        if (iGemProto->Flags & ITEM_PROTO_FLAG_UNIQUE_EQUIPPED)
        {
            for (int j = 0; j < MAX_GEM_SOCKETS; ++j)
            {
                if (i == j)                                    // skip self
                    continue;

                if (Gems[j])
                {
                    if (iGemProto->ItemId == Gems[j]->GetEntry())
                    {
                        _player->SendEquipError(EQUIP_ERR_ITEM_UNIQUE_EQUIPPABLE_SOCKETED, itemTarget, NULL);
                        return;
                    }
                }
                else if (OldEnchants[j])
                {
                    if (SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(OldEnchants[j]))
                    {
                        if (iGemProto->ItemId == enchantEntry->GemID)
                        {
                            _player->SendEquipError(EQUIP_ERR_ITEM_UNIQUE_EQUIPPABLE_SOCKETED, itemTarget, NULL);
                            return;
                        }
                    }
                }
            }
        }

        // unique limit type item
        int32 limit_newcount = 0;
        if (iGemProto->ItemLimitCategory)
        {
            if (ItemLimitCategoryEntry const* limitEntry = sItemLimitCategoryStore.LookupEntry(iGemProto->ItemLimitCategory))
            {
                // NOTE: limitEntry->mode is not checked because if item has limit then it is applied in equip case
                for (int j = 0; j < MAX_GEM_SOCKETS; ++j)
                {
                    if (Gems[j])
                    {
                        // new gem
                        if (iGemProto->ItemLimitCategory == Gems[j]->GetTemplate()->ItemLimitCategory)
                            ++limit_newcount;
                    }
                    else if (OldEnchants[j])
                    {
                        // existing gem
                        if (SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(OldEnchants[j]))
                            if (ItemTemplate const* jProto = sObjectMgr->GetItemTemplate(enchantEntry->GemID))
                                if (iGemProto->ItemLimitCategory == jProto->ItemLimitCategory)
                                    ++limit_newcount;
                    }
                }

                if (limit_newcount > 0 && uint32(limit_newcount) > limitEntry->maxCount)
                {
                    _player->SendEquipError(EQUIP_ERR_ITEM_UNIQUE_EQUIPPABLE_SOCKETED, itemTarget, NULL);
                    return;
                }
            }
        }

        // for equipped item check all equipment for duplicate equipped gems
        if (itemTarget->IsEquipped())
        {
            if (InventoryResult res = _player->CanEquipUniqueItem(Gems[i], slot, std::max(limit_newcount, 0)))
            {
                _player->SendEquipError(res, itemTarget, NULL);
                return;
            }
        }
    }

    bool 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 + MAX_GEM_SOCKETS; ++enchant_slot)
        _player->ApplyEnchantment(itemTarget, EnchantmentSlot(enchant_slot), false);

    for (int i = 0; i < MAX_GEM_SOCKETS; ++i)
    {
        if (GemEnchants[i])
        {
            itemTarget->SetEnchantment(EnchantmentSlot(SOCK_ENCHANTMENT_SLOT+i), GemEnchants[i], 0, 0);
            if (Item* guidItem = _player->GetItemByGuid(gem_guids[i]))
                _player->DestroyItem(guidItem->GetBagSlot(), guidItem->GetSlot(), true);
        }
    }

    for (uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+MAX_GEM_SOCKETS; ++enchant_slot)
        _player->ApplyEnchantment(itemTarget, EnchantmentSlot(enchant_slot), true);

    bool SocketBonusToBeActivated = itemTarget->GemsFitSockets();//current socketbonus state
    if (SocketBonusActivated ^ SocketBonusToBeActivated)     //if there was a change...
    {
        _player->ApplyEnchantment(itemTarget, BONUS_ENCHANTMENT_SLOT, false);
        itemTarget->SetEnchantment(BONUS_ENCHANTMENT_SLOT, (SocketBonusToBeActivated ? itemTarget->GetTemplate()->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)

    _player->RemoveTradeableItem(itemTarget);
    itemTarget->ClearSoulboundTradeable(_player);           // clear tradeable flag
}
示例#18
0
void Item::SaveToDB()
{
    uint32 guid = GetGUIDLow();
    switch (uState)
    {
        case ITEM_NEW:
        {
            std::string text = m_text;
            CharacterDatabase.escape_string(text);
            std::ostringstream ss;
            ss << "REPLACE INTO item_instance (guid,owner_guid,creatorGuid,giftCreatorGuid,count,duration,charges,flags,enchantments,randomPropertyId,durability,playedTime,text) VALUES (";
            ss << guid << ",";
            ss << GUID_LOPART(GetOwnerGUID()) << ",";
            ss << GUID_LOPART(GetUInt64Value(ITEM_FIELD_CREATOR)) << ",";
            ss << GUID_LOPART(GetUInt64Value(ITEM_FIELD_GIFTCREATOR)) << ",";
            ss << GetCount() << ",";
            ss << GetUInt32Value(ITEM_FIELD_DURATION) << ",'";
            for (uint8 i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
                ss << GetSpellCharges(i) << " ";

            ss << "'," << GetUInt32Value(ITEM_FIELD_FLAGS) << ",'";
            for (uint8 i = 0; i < MAX_ENCHANTMENT_SLOT; ++i)
            {
                ss << GetEnchantmentId(EnchantmentSlot(i)) << " ";
                ss << GetEnchantmentDuration(EnchantmentSlot(i)) << " ";
                ss << GetEnchantmentCharges(EnchantmentSlot(i)) << " ";
            }

            ss << "'," << GetItemRandomPropertyId() << ",";
            ss << GetUInt32Value(ITEM_FIELD_DURABILITY) << ",";
            ss << GetUInt32Value(ITEM_FIELD_CREATE_PLAYED_TIME) << ",'";
            ss << text << "')";

            CharacterDatabase.Execute(ss.str().c_str());
        }break;
        case ITEM_CHANGED:
        {
            std::string text = m_text;
            CharacterDatabase.escape_string(text);
            std::ostringstream ss;
            ss << "UPDATE item_instance SET owner_guid = " << GUID_LOPART(GetOwnerGUID());
            ss << ", creatorGuid = " << GUID_LOPART(GetUInt64Value(ITEM_FIELD_CREATOR));
            ss << ", giftCreatorGuid = " << GUID_LOPART(GetUInt64Value(ITEM_FIELD_GIFTCREATOR));
            ss << ", count = " << GetCount();
            ss << ", duration = " << GetUInt32Value(ITEM_FIELD_DURATION);
            ss << ", charges = '";
            for (uint8 i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
                ss << GetSpellCharges(i) << " ";

            ss << "', flags = " << GetUInt32Value(ITEM_FIELD_FLAGS);
            ss << ", enchantments = '";
            for (uint8 i = 0; i < MAX_ENCHANTMENT_SLOT; ++i)
            {
                ss << GetEnchantmentId(EnchantmentSlot(i)) << " ";
                ss << GetEnchantmentDuration(EnchantmentSlot(i)) << " ";
                ss << GetEnchantmentCharges(EnchantmentSlot(i)) << " ";
            }

            ss << "', randomPropertyId = " << GetItemRandomPropertyId();
            ss << ", durability = " << GetUInt32Value(ITEM_FIELD_DURABILITY);
            ss << ", playedTime = " << GetUInt32Value(ITEM_FIELD_CREATE_PLAYED_TIME);
            ss << ", text = '" << text << "' WHERE guid = " << guid;

            CharacterDatabase.Execute(ss.str().c_str());

            if (HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_WRAPPED))
                CharacterDatabase.PExecute("UPDATE character_gifts SET guid = '%u' WHERE item_guid = '%u'", GUID_LOPART(GetOwnerGUID()),GetGUIDLow());
        }break;
        case ITEM_REMOVED:
        {
            CharacterDatabase.PExecute("DELETE FROM item_instance WHERE guid = '%u'", guid);
            if (HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_WRAPPED))
                CharacterDatabase.PExecute("DELETE FROM character_gifts WHERE item_guid = '%u'", GetGUIDLow());
            delete this;
            return;
        }
        case ITEM_UNCHANGED:
            break;
    }
    SetState(ITEM_UNCHANGED);
}