private void UpdateDisplayedMapItemName()
        {
            var mi = _parentMapRenderer.GetMapItemAt(_gridX, _gridY);

            if (mi != null)
            {
                _cursorSourceRect.Location = new Point(2 * (_mouseCursor.Width / 5), 0);

                string itemName = OldEOInventoryItem.GetNameString(mi.ItemID, mi.Amount);
                if (_itemHoverName.Text != itemName)
                {
                    _itemHoverName.Visible = true;
                    _itemHoverName.Text    = OldEOInventoryItem.GetNameString(mi.ItemID, mi.Amount);
                    _itemHoverName.ResizeBasedOnText();
                    _itemHoverName.ForeColor = OldEOInventoryItem.GetItemTextColor(mi.ItemID);
                }
                _itemHoverName.DrawLocation = new Vector2(
                    _cursorPos.X + 32 - _itemHoverName.ActualWidth / 2f,
                    _cursorPos.Y - _itemHoverName.ActualHeight - 4);
            }
            else if (_itemHoverName.Visible)
            {
                _itemHoverName.Visible = false;
                _itemHoverName.Text    = " ";
            }

            if (_itemHoverName.Text.Length > 0 && !_game.Components.Contains(_itemHoverName))
            {
                _game.Components.Add(_itemHoverName);
            }
        }
        private void _removeItemFromSlot(int slot, int count = 1)
        {
            OldEOInventoryItem control = m_childItems.Find(_control => _control.Slot == slot);

            if (control == null || slot < 0)
            {
                return;
            }

            int numLeft = control.Inventory.Amount - count;

            if (numLeft <= 0 && control.Inventory.ItemID != 1)
            {
                ItemSize sz = control.ItemData.Size;
                _unmarkItemSlots(m_filledSlots, _getTakenSlots(control.Slot, sz));

                m_inventoryKey.SetValue($"item{slot}", 0, RegistryValueKind.String);
                m_childItems.Remove(control);
                control.Visible = false;
                control.Close();
            }
            else
            {
                control.Inventory = new InventoryItem(amount: numLeft, itemID: control.Inventory.ItemID);
                control.UpdateItemLabel();
            }
        }
        /// <summary>
        /// Checks if a list of Item IDs will fit in the inventory based on their item record sizes. Does not modify current inventory.
        /// </summary>
        /// <param name="newItems">List of Items to check</param>
        /// <param name="oldItems">Optional list of items to remove from filled slots before checking new IDs (ie items that will be traded)</param>
        /// <returns>True if everything fits, false otherwise.</returns>
        public bool ItemsFit(List <InventoryItem> newItems, List <InventoryItem> oldItems = null)
        {
            bool[,] tempFilledSlots = new bool[4, INVENTORY_ROW_LENGTH];
            for (int row = 0; row < 4; ++row)
            {
                for (int col = 0; col < INVENTORY_ROW_LENGTH; ++col)
                {
                    tempFilledSlots[row, col] = m_filledSlots[row, col];
                }
            }

            if (oldItems != null)
            {
                foreach (InventoryItem item in oldItems)
                {
                    OldEOInventoryItem control = m_childItems.Find(_item => _item.ItemData.ID == item.ItemID);
                    if (control != null && control.Inventory.Amount - item.Amount <= 0)
                    {
                        _unmarkItemSlots(tempFilledSlots, _getTakenSlots(control.Slot, control.ItemData.Size));
                    }
                }
            }

            foreach (InventoryItem item in newItems)
            {
                if (oldItems != null && oldItems.FindIndex(_itm => _itm.ItemID == item.ItemID) < 0)
                {
                    if (item.ItemID == 1 || m_childItems.Find(_item => _item.ItemData.ID == item.ItemID) != null)
                    {
                        continue; //already in inventory: skip, since it isn't a new item
                    }
                }

                var rec = OldWorld.Instance.EIF[item.ItemID];

                int nextSlot = _getNextOpenSlot(tempFilledSlots, rec.Size);
                List <Tuple <int, int> > points;
                if (nextSlot < 0 || !_fitsInSlot(tempFilledSlots, nextSlot, rec.Size, out points))
                {
                    return(false);
                }

                foreach (var pt in points)
                {
                    tempFilledSlots[pt.Item1, pt.Item2] = true;
                }
            }
            return(true);
        }
        public bool MoveItem(OldEOInventoryItem childItem, int newSlot)
        {
            if (childItem.Slot == newSlot)
            {
                return(true);                           // We did it, Reddit!
            }
            List <Tuple <int, int> > oldPoints = _getTakenSlots(childItem.Slot, childItem.ItemData.Size);
            List <Tuple <int, int> > points;

            if (!_fitsInSlot(newSlot, childItem.ItemData.Size, out points, oldPoints))
            {
                return(false);
            }

            oldPoints.ForEach(_p => m_filledSlots[_p.Item1, _p.Item2] = false);
            points.ForEach(_p => m_filledSlots[_p.Item1, _p.Item2]    = true);

            m_inventoryKey.SetValue($"item{childItem.Slot}", 0, RegistryValueKind.String);
            m_inventoryKey.SetValue($"item{newSlot}", childItem.ItemData.ID, RegistryValueKind.String);

            childItem.DrawOrder = (int)ControlDrawLayer.DialogLayer - (2 + childItem.Slot % INVENTORY_ROW_LENGTH);

            return(true);
        }