//precondition: lock is already taken
        public bool PackItems()
        {
            TEStorageUnit unitWithSpace = null;

            foreach (TEAbstractStorageUnit abstractStorageUnit in GetStorageUnits())
            {
                if (!(abstractStorageUnit is TEStorageUnit))
                {
                    continue;
                }
                TEStorageUnit storageUnit = (TEStorageUnit)abstractStorageUnit;
                if (unitWithSpace == null && !storageUnit.IsFull && !storageUnit.Inactive)
                {
                    unitWithSpace = storageUnit;
                }
                else if (unitWithSpace != null && !storageUnit.IsEmpty)
                {
                    NetHelper.StartUpdateQueue();
                    while (!unitWithSpace.IsFull && !storageUnit.IsEmpty)
                    {
                        Item item = storageUnit.WithdrawStack();
                        unitWithSpace.DepositItem(item, true);
                        if (!item.IsAir)
                        {
                            storageUnit.DepositItem(item, true);
                        }
                    }
                    NetHelper.ProcessUpdateQueue();
                    NetHelper.SendRefreshNetworkItems(ID);
                    return(true);
                }
            }
            compactStage++;
            return(false);
        }
        //precondition: lock is already taken
        public bool Defragment()
        {
            TEStorageUnit emptyUnit = null;

            foreach (TEAbstractStorageUnit abstractStorageUnit in GetStorageUnits())
            {
                if (!(abstractStorageUnit is TEStorageUnit))
                {
                    continue;
                }
                TEStorageUnit storageUnit = (TEStorageUnit)abstractStorageUnit;
                if (emptyUnit == null && storageUnit.IsEmpty && !storageUnit.Inactive)
                {
                    emptyUnit = storageUnit;
                }
                else if (emptyUnit != null && !storageUnit.IsEmpty && storageUnit.NumItems <= emptyUnit.Capacity)
                {
                    TEStorageUnit.SwapItems(emptyUnit, storageUnit);
                    NetHelper.SendRefreshNetworkItems(ID);
                    return(true);
                }
            }
            compactStage++;
            return(false);
        }
 protected override void SendData(BinaryWriter writer, TEStorageUnit unit)
 {
     writer.Write(unit.items.Count);
     foreach (Item item in unit.items)
     {
         ItemIO.Send(item, writer, true, false);
     }
 }
            public static bool Receive(BinaryReader reader, TEStorageUnit unit)
            {
                byte id = reader.ReadByte();

                if (id >= 0 && id < types.Count)
                {
                    return(types[id].ReceiveData(reader, unit));
                }
                return(false);
            }
            protected override bool ReceiveData(BinaryReader reader, TEStorageUnit unit)
            {
                unit.ClearItemsData();
                int count = reader.ReadInt32();

                for (int k = 0; k < count; k++)
                {
                    Item item = ItemIO.Receive(reader, true, false);
                    unit.items.Add(item);
                    ItemData data = new ItemData(item);
                    if (item.stack < item.maxStack)
                    {
                        unit.hasSpaceInStack.Add(data);
                    }
                    unit.hasItem.Add(data);
                }
                return(false);
            }
        public override void NetReceive(BinaryReader trueReader, bool lightReceive)
        {
            /* Reads the buffer off the network */
            MemoryStream buffer       = new MemoryStream(65536);
            BinaryWriter bufferWriter = new BinaryWriter(buffer);

            bufferWriter.Write(trueReader.ReadBytes(trueReader.ReadUInt16()));
            buffer.Position = 0;

            /* Recreate the BinaryReader reader */
            DeflateStream decompressor = new DeflateStream(buffer, CompressionMode.Decompress, true);
            BinaryReader  reader       = new BinaryReader(decompressor);

            /* Original code */
            base.NetReceive(reader, lightReceive);
            if (TileEntity.ByPosition.ContainsKey(Position) && TileEntity.ByPosition[Position] is TEStorageUnit)
            {
                TEStorageUnit other = (TEStorageUnit)TileEntity.ByPosition[Position];
                items           = other.items;
                hasSpaceInStack = other.hasSpaceInStack;
                hasItem         = other.hasItem;
            }
            receiving = true;
            int  count = reader.ReadUInt16();
            bool flag  = false;

            for (int k = 0; k < count; k++)
            {
                if (UnitOperation.Receive(reader, this))
                {
                    flag = true;
                }
            }
            if (flag)
            {
                RepairMetadata();
            }
            receiving = false;

            /* Dispose all objects */
            reader.Dispose(); decompressor.Dispose(); bufferWriter.Dispose(); buffer.Dispose();
        }
        //precondition: lock is already taken
        internal static void SwapItems(TEStorageUnit unit1, TEStorageUnit unit2)
        {
            IList <Item> items = unit1.items;

            unit1.items = unit2.items;
            unit2.items = items;
            HashSet <ItemData> dict = unit1.hasSpaceInStack;

            unit1.hasSpaceInStack = unit2.hasSpaceInStack;
            unit2.hasSpaceInStack = dict;
            dict          = unit1.hasItem;
            unit1.hasItem = unit2.hasItem;
            unit2.hasItem = dict;
            if (Main.netMode == 2)
            {
                unit1.netQueue.Clear();
                unit2.netQueue.Clear();
                unit1.netQueue.Enqueue(UnitOperation.FullSync.Create());
                unit2.netQueue.Enqueue(UnitOperation.FullSync.Create());
            }
            unit1.PostChangeContents();
            unit2.PostChangeContents();
        }
        public override void RightClick(int i, int j)
        {
            if (Main.tile[i, j].frameX % 36 == 18)
            {
                i--;
            }
            if (Main.tile[i, j].frameY % 36 == 18)
            {
                j--;
            }
            if (TryUpgrade(i, j))
            {
                Main.player[Main.myPlayer].tileInteractionHappened = true;
                return;
            }
            TEStorageUnit storageUnit = (TEStorageUnit)TileEntity.ByPosition[new Point16(i, j)];

            Main.player[Main.myPlayer].tileInteractionHappened = true;
            string activeString   = storageUnit.Inactive ? "Inactive" : "Active";
            string fullnessString = storageUnit.NumItems + " / " + storageUnit.Capacity + " Items";

            Main.NewText(activeString + ", " + fullnessString);
        }
 protected override bool ReceiveData(BinaryReader reader, TEStorageUnit unit)
 {
     unit.TryWithdraw(ItemIO.Receive(reader, true, false));
     return(true);
 }
 protected override void SendData(BinaryWriter writer, TEStorageUnit unit)
 {
     ItemIO.Send(data, writer, true, false);
 }
 protected abstract bool ReceiveData(BinaryReader reader, TEStorageUnit unit);
 public void Send(BinaryWriter writer, TEStorageUnit unit)
 {
     writer.Write(id);
     SendData(writer, unit);
 }
        private bool TryUpgrade(int i, int j)
        {
            Player player  = Main.player[Main.myPlayer];
            Item   item    = player.inventory[player.selectedItem];
            int    style   = Main.tile[i, j].frameY / 36;
            bool   success = false;

            if (style == 0 && item.type == mod.ItemType("UpgradeDemonite"))
            {
                SetStyle(i, j, 1);
                success = true;
            }
            else if (style == 0 && item.type == mod.ItemType("UpgradeCrimtane"))
            {
                SetStyle(i, j, 2);
                success = true;
            }
            else if ((style == 1 || style == 2) && item.type == mod.ItemType("UpgradeHellstone"))
            {
                SetStyle(i, j, 3);
                success = true;
            }
            else if (style == 3 && item.type == mod.ItemType("UpgradeHallowed"))
            {
                SetStyle(i, j, 4);
                success = true;
            }
            else if (style == 4 && item.type == mod.ItemType("UpgradeBlueChlorophyte"))
            {
                SetStyle(i, j, 5);
                success = true;
            }
            else if (style == 5 && item.type == mod.ItemType("UpgradeLuminite"))
            {
                SetStyle(i, j, 6);
                success = true;
            }
            else if (style == 6 && item.type == mod.ItemType("UpgradeTerra"))
            {
                SetStyle(i, j, 7);
                success = true;
            }
            if (success)
            {
                TEStorageUnit storageUnit = (TEStorageUnit)TileEntity.ByPosition[new Point16(i, j)];
                storageUnit.UpdateTileFrame();
                NetMessage.SendTileRange(Main.myPlayer, i, j, 2, 2);
                TEStorageHeart heart = storageUnit.GetHeart();
                if (heart != null)
                {
                    if (Main.netMode == 0)
                    {
                        heart.ResetCompactStage();
                    }
                    else if (Main.netMode == 1)
                    {
                        NetHelper.SendResetCompactStage(heart.ID);
                    }
                }
                item.stack--;
                if (item.stack <= 0)
                {
                    item.SetDefaults(0);
                }
                if (player.selectedItem == 58)
                {
                    Main.mouseItem = item.Clone();
                }
            }
            return(success);
        }
 protected override void SendData(BinaryWriter writer, TEStorageUnit unit)
 {
 }
 protected abstract void SendData(BinaryWriter writer, TEStorageUnit unit);
 protected override bool ReceiveData(BinaryReader reader, TEStorageUnit unit)
 {
     unit.WithdrawStack();
     return(true);
 }
        //precondition: lock is already taken
        public bool EmptyInactive()
        {
            TEStorageUnit inactiveUnit = null;

            foreach (TEAbstractStorageUnit abstractStorageUnit in GetStorageUnits())
            {
                if (!(abstractStorageUnit is TEStorageUnit))
                {
                    continue;
                }
                TEStorageUnit storageUnit = (TEStorageUnit)abstractStorageUnit;
                if (storageUnit.Inactive && !storageUnit.IsEmpty)
                {
                    inactiveUnit = storageUnit;
                }
            }
            if (inactiveUnit == null)
            {
                compactStage++;
                return(false);
            }
            foreach (TEAbstractStorageUnit abstractStorageUnit in GetStorageUnits())
            {
                if (!(abstractStorageUnit is TEStorageUnit) || abstractStorageUnit.Inactive)
                {
                    continue;
                }
                TEStorageUnit storageUnit = (TEStorageUnit)abstractStorageUnit;
                if (storageUnit.IsEmpty && inactiveUnit.NumItems <= storageUnit.Capacity)
                {
                    TEStorageUnit.SwapItems(inactiveUnit, storageUnit);
                    NetHelper.SendRefreshNetworkItems(ID);
                    return(true);
                }
            }
            bool hasChange = false;

            NetHelper.StartUpdateQueue();
            Item tryMove = inactiveUnit.WithdrawStack();

            foreach (TEAbstractStorageUnit abstractStorageUnit in GetStorageUnits())
            {
                if (!(abstractStorageUnit is TEStorageUnit) || abstractStorageUnit.Inactive)
                {
                    continue;
                }
                TEStorageUnit storageUnit = (TEStorageUnit)abstractStorageUnit;
                while (storageUnit.HasSpaceFor(tryMove, true) && !tryMove.IsAir)
                {
                    storageUnit.DepositItem(tryMove, true);
                    if (tryMove.IsAir && !inactiveUnit.IsEmpty)
                    {
                        tryMove = inactiveUnit.WithdrawStack();
                    }
                    hasChange = true;
                }
            }
            if (!tryMove.IsAir)
            {
                inactiveUnit.DepositItem(tryMove, true);
            }
            NetHelper.ProcessUpdateQueue();
            if (hasChange)
            {
                NetHelper.SendRefreshNetworkItems(ID);
            }
            else
            {
                compactStage++;
            }
            return(hasChange);
        }