Exemple #1
0
        void HandleAutoEquipItem(AutoEquipItem autoEquipItem)
        {
            if (autoEquipItem.Inv.Items.Count != 1)
            {
                Log.outError(LogFilter.Network, "WORLD: HandleAutoEquipItem - Invalid itemCount ({0})", autoEquipItem.Inv.Items.Count);
                return;
            }

            var  pl      = GetPlayer();
            Item srcItem = pl.GetItemByPos(autoEquipItem.PackSlot, autoEquipItem.Slot);

            if (srcItem == null)
            {
                return;                                             // only at cheat
            }
            ushort          dest;
            InventoryResult msg = pl.CanEquipItem(ItemConst.NullSlot, out dest, srcItem, !srcItem.IsBag());

            if (msg != InventoryResult.Ok)
            {
                pl.SendEquipError(msg, srcItem);
                return;
            }

            ushort src = srcItem.GetPos();

            if (dest == src)                                           // prevent equip in same slot, only at cheat
            {
                return;
            }

            Item dstItem = pl.GetItemByPos(dest);

            if (dstItem == null)                                         // empty slot, simple case
            {
                if (!srcItem.GetChildItem().IsEmpty())
                {
                    InventoryResult childEquipResult = _player.CanEquipChildItem(srcItem);
                    if (childEquipResult != InventoryResult.Ok)
                    {
                        _player.SendEquipError(msg, srcItem);
                        return;
                    }
                }

                pl.RemoveItem(autoEquipItem.PackSlot, autoEquipItem.Slot, true);
                pl.EquipItem(dest, srcItem, true);
                if (!srcItem.GetChildItem().IsEmpty())
                {
                    _player.EquipChildItem(autoEquipItem.PackSlot, autoEquipItem.Slot, srcItem);
                }

                pl.AutoUnequipOffhandIfNeed();
            }
            else                                                    // have currently equipped item, not simple case
            {
                byte dstbag  = dstItem.GetBagSlot();
                byte dstslot = dstItem.GetSlot();

                msg = pl.CanUnequipItem(dest, !srcItem.IsBag());
                if (msg != InventoryResult.Ok)
                {
                    pl.SendEquipError(msg, dstItem);
                    return;
                }

                if (!dstItem.HasItemFlag(ItemFieldFlags.Child))
                {
                    // check dest.src move possibility
                    List <ItemPosCount> sSrc = new();
                    ushort eSrc = 0;
                    if (pl.IsInventoryPos(src))
                    {
                        msg = pl.CanStoreItem(autoEquipItem.PackSlot, autoEquipItem.Slot, sSrc, dstItem, true);
                        if (msg != InventoryResult.Ok)
                        {
                            msg = pl.CanStoreItem(autoEquipItem.PackSlot, ItemConst.NullSlot, sSrc, dstItem, true);
                        }
                        if (msg != InventoryResult.Ok)
                        {
                            msg = pl.CanStoreItem(ItemConst.NullBag, ItemConst.NullSlot, sSrc, dstItem, true);
                        }
                    }
                    else if (Player.IsBankPos(src))
                    {
                        msg = pl.CanBankItem(autoEquipItem.PackSlot, autoEquipItem.Slot, sSrc, dstItem, true);
                        if (msg != InventoryResult.Ok)
                        {
                            msg = pl.CanBankItem(autoEquipItem.PackSlot, ItemConst.NullSlot, sSrc, dstItem, true);
                        }
                        if (msg != InventoryResult.Ok)
                        {
                            msg = pl.CanBankItem(ItemConst.NullBag, ItemConst.NullSlot, sSrc, dstItem, true);
                        }
                    }
                    else if (Player.IsEquipmentPos(src))
                    {
                        msg = pl.CanEquipItem(autoEquipItem.Slot, out eSrc, dstItem, true);
                        if (msg == InventoryResult.Ok)
                        {
                            msg = pl.CanUnequipItem(eSrc, true);
                        }
                    }

                    if (msg == InventoryResult.Ok && Player.IsEquipmentPos(dest) && !srcItem.GetChildItem().IsEmpty())
                    {
                        msg = _player.CanEquipChildItem(srcItem);
                    }

                    if (msg != InventoryResult.Ok)
                    {
                        pl.SendEquipError(msg, dstItem, srcItem);
                        return;
                    }

                    // now do moves, remove...
                    pl.RemoveItem(dstbag, dstslot, false);
                    pl.RemoveItem(autoEquipItem.PackSlot, autoEquipItem.Slot, false);

                    // add to dest
                    pl.EquipItem(dest, srcItem, true);

                    // add to src
                    if (pl.IsInventoryPos(src))
                    {
                        pl.StoreItem(sSrc, dstItem, true);
                    }
                    else if (Player.IsBankPos(src))
                    {
                        pl.BankItem(sSrc, dstItem, true);
                    }
                    else if (Player.IsEquipmentPos(src))
                    {
                        pl.EquipItem(eSrc, dstItem, true);
                    }

                    if (Player.IsEquipmentPos(dest) && !srcItem.GetChildItem().IsEmpty())
                    {
                        _player.EquipChildItem(autoEquipItem.PackSlot, autoEquipItem.Slot, srcItem);
                    }
                }
                else
                {
                    Item parentItem = _player.GetItemByGuid(dstItem.GetCreator());
                    if (parentItem)
                    {
                        if (Player.IsEquipmentPos(dest))
                        {
                            _player.AutoUnequipChildItem(parentItem);
                            // dest is now empty
                            _player.SwapItem(src, dest);
                            // src is now empty
                            _player.SwapItem(parentItem.GetPos(), src);
                        }
                    }
                }

                pl.AutoUnequipOffhandIfNeed();

                // if inventory item was moved, check if we can remove dependent auras, because they were not removed in Player::RemoveItem (update was set to false)
                // do this after swaps are done, we pass nullptr because both weapons could be swapped and none of them should be ignored
                if ((autoEquipItem.PackSlot == InventorySlots.Bag0 && autoEquipItem.Slot < InventorySlots.BagEnd) || (dstbag == InventorySlots.Bag0 && dstslot < InventorySlots.BagEnd))
                {
                    pl.ApplyItemDependentAuras(null, false);
                }
            }
        }
Exemple #2
0
        void HandleSocketGems(SocketGems socketGems)
        {
            if (socketGems.ItemGuid.IsEmpty())
            {
                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 = GetPlayer().GetItemByGuid(socketGems.ItemGuid);

            if (!itemTarget)                                         //missing item to socket
            {
                return;
            }

            ItemTemplate itemProto = itemTarget.GetTemplate();

            if (itemProto == null)
            {
                return;
            }

            //this slot is excepted when applying / removing meta gem bonus
            byte slot = itemTarget.IsEquipped() ? itemTarget.GetSlot() : ItemConst.NullSlot;

            Item[] gems = new Item[ItemConst.MaxGemSockets];
            ItemDynamicFieldGems[] gemData       = new ItemDynamicFieldGems[ItemConst.MaxGemSockets];
            GemPropertiesRecord[]  gemProperties = new GemPropertiesRecord[ItemConst.MaxGemSockets];
            SocketedGem[]          oldGemData    = new SocketedGem[ItemConst.MaxGemSockets];


            for (int i = 0; i < ItemConst.MaxGemSockets; ++i)
            {
                Item gem = _player.GetItemByGuid(socketGems.GemItem[i]);
                if (gem)
                {
                    gems[i]            = gem;
                    gemData[i].ItemId  = gem.GetEntry();
                    gemData[i].Context = (byte)gem.m_itemData.Context;
                    for (int b = 0; b < ((List <uint>)gem.m_itemData.BonusListIDs).Count && b < 16; ++b)
                    {
                        gemData[i].BonusListIDs[b] = (ushort)((List <uint>)gem.m_itemData.BonusListIDs)[b];
                    }

                    gemProperties[i] = CliDB.GemPropertiesStorage.LookupByKey(gem.GetTemplate().GetGemProperties());
                }

                oldGemData[i] = itemTarget.GetGem((ushort)i);
            }

            // Find first prismatic socket
            uint firstPrismatic = 0;

            while (firstPrismatic < ItemConst.MaxGemSockets && itemTarget.GetSocketColor(firstPrismatic) != 0)
            {
                ++firstPrismatic;
            }

            for (uint i = 0; i < ItemConst.MaxGemSockets; ++i)                //check for hack maybe
            {
                if (gemProperties[i] == null)
                {
                    continue;
                }

                // tried to put gem in socket where no socket exists (take care about prismatic sockets)
                if (itemTarget.GetSocketColor(i) == 0)
                {
                    // no prismatic socket
                    if (itemTarget.GetEnchantmentId(EnchantmentSlot.Prismatic) == 0)
                    {
                        return;
                    }

                    if (i != firstPrismatic)
                    {
                        return;
                    }
                }

                // Gem must match socket color
                if (ItemConst.SocketColorToGemTypeMask[(int)itemTarget.GetSocketColor(i)] != gemProperties[i].Type)
                {
                    // unless its red, blue, yellow or prismatic
                    if (!ItemConst.SocketColorToGemTypeMask[(int)itemTarget.GetSocketColor(i)].HasAnyFlag(SocketColor.Prismatic) || !gemProperties[i].Type.HasAnyFlag(SocketColor.Prismatic))
                    {
                        return;
                    }
                }
            }

            // check unique-equipped conditions
            for (int i = 0; i < ItemConst.MaxGemSockets; ++i)
            {
                if (!gems[i])
                {
                    continue;
                }

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

                // unique item (for new and already placed bit removed enchantments
                if (iGemProto.HasFlag(ItemFlags.UniqueEquippable))
                {
                    for (int j = 0; j < ItemConst.MaxGemSockets; ++j)
                    {
                        if (i == j)                                    // skip self
                        {
                            continue;
                        }

                        if (gems[j])
                        {
                            if (iGemProto.GetId() == gems[j].GetEntry())
                            {
                                GetPlayer().SendEquipError(InventoryResult.ItemUniqueEquippableSocketed, itemTarget);
                                return;
                            }
                        }
                        else if (oldGemData[j] != null)
                        {
                            if (iGemProto.GetId() == oldGemData[j].ItemId)
                            {
                                GetPlayer().SendEquipError(InventoryResult.ItemUniqueEquippableSocketed, itemTarget);
                                return;
                            }
                        }
                    }
                }

                // unique limit type item
                int limit_newcount = 0;
                if (iGemProto.GetItemLimitCategory() != 0)
                {
                    ItemLimitCategoryRecord limitEntry = CliDB.ItemLimitCategoryStorage.LookupByKey(iGemProto.GetItemLimitCategory());
                    if (limitEntry != null)
                    {
                        // NOTE: limitEntry.mode is not checked because if item has limit then it is applied in equip case
                        for (int j = 0; j < ItemConst.MaxGemSockets; ++j)
                        {
                            if (gems[j])
                            {
                                // new gem
                                if (iGemProto.GetItemLimitCategory() == gems[j].GetTemplate().GetItemLimitCategory())
                                {
                                    ++limit_newcount;
                                }
                            }
                            else if (oldGemData[j] != null)
                            {
                                // existing gem
                                ItemTemplate jProto = Global.ObjectMgr.GetItemTemplate(oldGemData[j].ItemId);
                                if (jProto != null)
                                {
                                    if (iGemProto.GetItemLimitCategory() == jProto.GetItemLimitCategory())
                                    {
                                        ++limit_newcount;
                                    }
                                }
                            }
                        }

                        if (limit_newcount > 0 && limit_newcount > _player.GetItemLimitCategoryQuantity(limitEntry))
                        {
                            GetPlayer().SendEquipError(InventoryResult.ItemUniqueEquippableSocketed, itemTarget);
                            return;
                        }
                    }
                }

                // for equipped item check all equipment for duplicate equipped gems
                if (itemTarget.IsEquipped())
                {
                    InventoryResult res = GetPlayer().CanEquipUniqueItem(gems[i], slot, (uint)Math.Max(limit_newcount, 0));
                    if (res != 0)
                    {
                        GetPlayer().SendEquipError(res, itemTarget);
                        return;
                    }
                }
            }

            bool SocketBonusActivated = itemTarget.GemsFitSockets();   //save state of socketbonus

            GetPlayer().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 (ushort i = 0; i < ItemConst.MaxGemSockets; ++i)
            {
                if (gems[i])
                {
                    uint gemScalingLevel = _player.GetLevel();
                    uint fixedLevel      = gems[i].GetModifier(ItemModifier.TimewalkerLevel);
                    if (fixedLevel != 0)
                    {
                        gemScalingLevel = fixedLevel;
                    }

                    itemTarget.SetGem(i, gemData[i], gemScalingLevel);

                    if (gemProperties[i] != null && gemProperties[i].EnchantId != 0)
                    {
                        itemTarget.SetEnchantment(EnchantmentSlot.Sock1 + i, gemProperties[i].EnchantId, 0, 0, GetPlayer().GetGUID());
                    }

                    uint gemCount = 1;
                    GetPlayer().DestroyItemCount(gems[i], ref gemCount, true);
                }
            }

            if (itemTarget.IsEquipped())
            {
                _player._ApplyItemMods(itemTarget, itemTarget.GetSlot(), true);
            }

            Item childItem = _player.GetChildItemByGuid(itemTarget.GetChildItem());

            if (childItem)
            {
                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...
            {
                GetPlayer().ApplyEnchantment(itemTarget, EnchantmentSlot.Bonus, false);
                itemTarget.SetEnchantment(EnchantmentSlot.Bonus, SocketBonusToBeActivated ? itemTarget.GetTemplate().GetSocketBonus() : 0, 0, 0, GetPlayer().GetGUID());
                GetPlayer().ApplyEnchantment(itemTarget, EnchantmentSlot.Bonus, true);
                //it is not displayed, client has an inbuilt system to determine if the bonus is activated
            }

            GetPlayer().ToggleMetaGemsActive(slot, true);              //turn on all metagems (except for target item)

            GetPlayer().RemoveTradeableItem(itemTarget);
            itemTarget.ClearSoulboundTradeable(GetPlayer());           // clear tradeable flag

            itemTarget.SendUpdateSockets();
        }
Exemple #3
0
        void HandleArtifactSetAppearance(ArtifactSetAppearance artifactSetAppearance)
        {
            if (!_player.GetGameObjectIfCanInteractWith(artifactSetAppearance.ForgeGUID, GameObjectTypes.ItemForge))
            {
                return;
            }

            ArtifactAppearanceRecord artifactAppearance = CliDB.ArtifactAppearanceStorage.LookupByKey(artifactSetAppearance.ArtifactAppearanceID);

            if (artifactAppearance == null)
            {
                return;
            }

            Item artifact = _player.GetItemByGuid(artifactSetAppearance.ArtifactGUID);

            if (!artifact)
            {
                return;
            }

            ArtifactAppearanceSetRecord artifactAppearanceSet = CliDB.ArtifactAppearanceSetStorage.LookupByKey(artifactAppearance.ArtifactAppearanceSetID);

            if (artifactAppearanceSet == null || artifactAppearanceSet.ArtifactID != artifact.GetTemplate().GetArtifactID())
            {
                return;
            }

            PlayerConditionRecord playerCondition = CliDB.PlayerConditionStorage.LookupByKey(artifactAppearance.UnlockPlayerConditionID);

            if (playerCondition != null)
            {
                if (!ConditionManager.IsPlayerMeetingCondition(_player, playerCondition))
                {
                    return;
                }
            }

            artifact.SetAppearanceModId(artifactAppearance.ItemAppearanceModifierID);
            artifact.SetModifier(ItemModifier.ArtifactAppearanceId, artifactAppearance.Id);
            artifact.SetState(ItemUpdateState.Changed, _player);
            Item childItem = _player.GetChildItemByGuid(artifact.GetChildItem());

            if (childItem)
            {
                childItem.SetAppearanceModId(artifactAppearance.ItemAppearanceModifierID);
                childItem.SetState(ItemUpdateState.Changed, _player);
            }

            if (artifact.IsEquipped())
            {
                // change weapon appearance
                _player.SetVisibleItemSlot(artifact.GetSlot(), artifact);
                if (childItem)
                {
                    _player.SetVisibleItemSlot(childItem.GetSlot(), childItem);
                }

                // change druid form appearance
                if (artifactAppearance.OverrideShapeshiftDisplayID != 0 && artifactAppearance.OverrideShapeshiftFormID != 0 && _player.GetShapeshiftForm() == (ShapeShiftForm)artifactAppearance.OverrideShapeshiftFormID)
                {
                    _player.RestoreDisplayId(_player.IsMounted());
                }
            }
        }