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