/* * Copyright (C) 2012-2018 CypherCore * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ using Framework.Constants; using Framework.Database; namespace Game.Entities { public class Bag : Item { public Bag() { objectTypeMask |= TypeMask.Container; objectTypeId = TypeId.Container; valuesCount = (int)ContainerFields.End; _dynamicValuesCount = (int)ItemDynamicFields.End; } public override void Dispose() { for (byte i = 0; i < ItemConst.MaxBagSize; ++i) { Item item = m_bagslot[i]; if (item) { if (item.IsInWorld) { Log.outFatal(LogFilter.PlayerItems, "Item {0} (slot {1}, bag slot {2}) in bag {3} (slot {4}, bag slot {5}, m_bagslot {6}) is to be deleted but is still in world.", item.GetEntry(), item.GetSlot(), item.GetBagSlot(), GetEntry(), GetSlot(), GetBagSlot(), i); item.RemoveFromWorld(); } m_bagslot[i].Dispose(); } } base.Dispose(); } public override void AddToWorld() { base.AddToWorld(); for (uint i = 0; i < GetBagSize(); ++i) if (m_bagslot[i] != null) m_bagslot[i].AddToWorld(); } public override void RemoveFromWorld() { for (uint i = 0; i < GetBagSize(); ++i) if (m_bagslot[i] != null) m_bagslot[i].RemoveFromWorld(); base.RemoveFromWorld(); } public override bool Create(ulong guidlow, uint itemid, Player owner) { var itemProto = Global.ObjectMgr.GetItemTemplate(itemid); if (itemProto == null || itemProto.GetContainerSlots() > ItemConst.MaxBagSize) return false; _Create(ObjectGuid.Create(HighGuid.Item, guidlow)); _bonusData = new BonusData(itemProto); SetEntry(itemid); SetObjectScale(1.0f); if (owner) { SetGuidValue(ItemFields.Owner, owner.GetGUID()); SetGuidValue(ItemFields.Contained, owner.GetGUID()); } SetUInt32Value(ItemFields.MaxDurability, itemProto.MaxDurability); SetUInt32Value(ItemFields.Durability, itemProto.MaxDurability); SetUInt32Value(ItemFields.StackCount, 1); // Setting the number of Slots the Container has SetUInt32Value(ContainerFields.NumSlots, itemProto.GetContainerSlots()); // Cleaning 20 slots for (byte i = 0; i < ItemConst.MaxBagSize; ++i) SetGuidValue(ContainerFields.Slot1 + (i * 4), ObjectGuid.Empty); m_bagslot = new Item[ItemConst.MaxBagSize]; return true; } public override void SaveToDB(SQLTransaction trans) { base.SaveToDB(trans); } public override bool LoadFromDB(ulong guid, ObjectGuid owner_guid, SQLFields fields, uint entry) { if (!base.LoadFromDB(guid, owner_guid, fields, entry)) return false; ItemTemplate itemProto = GetTemplate(); // checked in Item.LoadFromDB SetUInt32Value(ContainerFields.NumSlots, itemProto.GetContainerSlots()); // cleanup bag content related item value fields (its will be filled correctly from `character_inventory`) for (byte i = 0; i < ItemConst.MaxBagSize; ++i) { SetGuidValue(ContainerFields.Slot1 + (i * 4), ObjectGuid.Empty); m_bagslot[i] = null; } return true; } public override void DeleteFromDB(SQLTransaction trans) { for (byte i = 0; i < ItemConst.MaxBagSize; ++i) if (m_bagslot[i] != null) m_bagslot[i].DeleteFromDB(trans); base.DeleteFromDB(trans); } public uint GetFreeSlots() { uint slots = 0; for (uint i = 0; i < GetBagSize(); ++i) if (m_bagslot[i] == null) ++slots; return slots; } public void RemoveItem(byte slot, bool update) { if (m_bagslot[slot] != null) m_bagslot[slot].SetContainer(null); m_bagslot[slot] = null; SetGuidValue(ContainerFields.Slot1 + (slot * 4), ObjectGuid.Empty); } public void StoreItem(byte slot, Item pItem, bool update) { if (pItem != null && pItem.GetGUID() != GetGUID()) { m_bagslot[slot] = pItem; SetGuidValue(ContainerFields.Slot1 + (slot * 4), pItem.GetGUID()); pItem.SetGuidValue(ItemFields.Contained, GetGUID()); pItem.SetGuidValue(ItemFields.Owner, GetOwnerGUID()); pItem.SetContainer(this); pItem.SetSlot(slot); } } public override void BuildCreateUpdateBlockForPlayer(UpdateData data, Player target) { base.BuildCreateUpdateBlockForPlayer(data, target); for (int i = 0; i < GetBagSize(); ++i) if (m_bagslot[i] != null) m_bagslot[i].BuildCreateUpdateBlockForPlayer(data, target); } public bool IsEmpty() { for (var i = 0; i < GetBagSize(); ++i) if (m_bagslot[i] != null) return false; return true; } public uint GetItemCount(uint item, Item eItem) { Item pItem; uint count = 0; for (var i = 0; i < GetBagSize(); ++i) { pItem = m_bagslot[i]; if (pItem != null && pItem != eItem && pItem.GetEntry() == item) count += pItem.GetCount(); } if (eItem != null && eItem.GetTemplate().GetGemProperties() != 0) { for (var i = 0; i < GetBagSize(); ++i) { pItem = m_bagslot[i]; if (pItem != null && pItem != eItem && pItem.GetSocketColor(0) != 0) count += pItem.GetGemCountWithID(item); } } return count; } public uint GetItemCountWithLimitCategory(uint limitCategory, Item skipItem) { uint count = 0; for (uint i = 0; i < GetBagSize(); ++i) { Item pItem = m_bagslot[i]; if (pItem != null) { if (pItem != skipItem) { ItemTemplate pProto = pItem.GetTemplate(); if (pProto != null) if (pProto.GetItemLimitCategory() == limitCategory) count += m_bagslot[i].GetCount(); } } } return count; } byte GetSlotByItemGUID(ObjectGuid guid) { for (byte i = 0; i < GetBagSize(); ++i) if (m_bagslot[i] != null) if (m_bagslot[i].GetGUID() == guid) return i; return ItemConst.NullSlot; } public Item GetItemByPos(byte slot) { if (slot < GetBagSize()) return m_bagslot[slot]; return null; } public uint GetBagSize() { return GetUInt32Value(ContainerFields.NumSlots); } public static Item NewItemOrBag(ItemTemplate proto) { return (proto.GetInventoryType() == InventoryType.Bag) ? new Bag() : new Item(); } Item[] m_bagslot = new Item[36]; } }