internal void OnMachineRemoved(AugmentedTile Tile)
        {
            if (Tile.Location != this)
            {
                throw new InvalidOperationException("Object instance mismatch in AugmentedLocation.OnMachineRemoved.");
            }

            Tiles.Remove(EncodeTileToString(Tile.Position));

            if (!Context.IsMultiplayer || Context.IsMainPlayer)
            {
                //  Now that the managed machine has been removed, refund the player with the augmentors that were placed there
                //  by spawning them on the ground
                foreach (KeyValuePair <AugmentorType, int> KVP in Tile.Quantities)
                {
                    int Quantity = KVP.Value;
                    if (Quantity > 0)
                    {
                        Augmentor Refund         = Augmentor.CreateInstance(KVP.Key, Quantity);
                        int       SpawnDirection = Augmentor.Randomizer.Next(4);
                        Game1.createItemDebris(Refund, new Vector2(Tile.Position.X * Game1.tileSize, Tile.Position.Y * Game1.tileSize), SpawnDirection, Location, -1);
                    }
                }
            }
        }
        internal void OnMachineRemoved(AugmentedTile Tile)
        {
            if (Tile.Location != this)
            {
                throw new InvalidOperationException("Object instance mismatch in AugmentedLocation.OnMachineRemoved.");
            }

            Tiles.Remove(EncodeTileToString(Tile.Position));

            if (!Context.IsMultiplayer || Context.IsMainPlayer)
            {
                //  Now that the managed machine has been removed, refund the player with the augmentors that were placed there
                //  by spawning them on the ground
                foreach (KeyValuePair <AugmentorType, int> KVP in Tile.Quantities)
                {
                    int Quantity = KVP.Value;
                    if (Quantity > 0)
                    {
                        Augmentor Refund = Augmentor.CreateInstance(KVP.Key, Quantity);
                        int       SpawnDirection;
                        //  When spawning items at the edge of the map, sometimes it seems to move them off the map. Mostly only happens when removing augmentors from incubators in coops,
                        //  so as a temporary workaround, spawn the items in the direction of the player when handling indestructible machines like incubators.
                        if (!MachineInfo.IsDestructible(Tile.Machine))
                        {
                            SpawnDirection = Game1.MasterPlayer.getGeneralDirectionTowards(Tile.VectorPosition, 0, true);
                        }
                        else
                        {
                            SpawnDirection = Augmentor.Randomizer.Next(4);
                        }
                        Game1.createItemDebris(Refund, new Vector2(Tile.Position.X * Game1.tileSize, Tile.Position.Y * Game1.tileSize), SpawnDirection, Location, -1);
                    }
                }
            }
        }
        /// <param name="RemoveFromInventory">True if the given <paramref name="Qty"/> should be removed from the player's inventory.</param>
        /// <param name="Instance">If <paramref name="RemoveFromInventory"/>=true, this Instance's Stack will be reduced. If not specified, the first instance found in the player's inventory will be reduced.</param>
        internal void OnAugmentorPlaced(AugmentorType Type, int Qty, bool RemoveFromInventory, Augmentor Instance = null)
        {
            int MaxQuantity = MachineAugmentorsMod.UserConfig.GetConfig(Type).MaxAttachmentsPerMachine;
            int CurrentQty  = 0;

            Quantities.TryGetValue(Type, out CurrentQty);
            int ActualQtyPlaced = Math.Max(0, Math.Min(MaxQuantity - CurrentQty, Qty));

            if (ActualQtyPlaced <= 0)
            {
                return;
            }

            if (Quantities.ContainsKey(Type))
            {
                Quantities[Type] += ActualQtyPlaced;
            }
            else
            {
                Quantities.Add(Type, ActualQtyPlaced);
            }

            if (RemoveFromInventory)
            {
                int PendingRemoval = ActualQtyPlaced;
                if (Instance != null && Game1.player.Items.Contains(Instance))
                {
                    int Amt = Math.Min(Instance.Stack, PendingRemoval);
                    if (Amt == Instance.Stack)
                    {
                        Game1.player.Items[Game1.player.Items.IndexOf(Instance)] = null;
                    }
                    else
                    {
                        Instance.Stack -= Amt;
                    }
                }
                else
                {
                    for (int i = 0; i < Game1.player.Items.Count; i++)
                    {
                        Item Item = Game1.player.Items[i];
                        if (Item != null && Item is Augmentor Augmentor && Augmentor.AugmentorType == Type)
                        {
                            int Amt = Math.Min(Augmentor.Stack, PendingRemoval);
                            if (Amt == Augmentor.Stack)
                            {
                                Game1.player.Items[i] = null;
                            }
                            else
                            {
                                Item.Stack -= Amt;
                            }

                            PendingRemoval -= Amt;
                            if (PendingRemoval <= 0)
                            {
                                break;
                            }
                        }
                    }
                }
            }
        }
        internal void OnAugmentorPlaced(AugmentorType Type, int Qty, bool RemoveFromInventory, int TileX, int TileY, Augmentor Instance = null)
        {
            string Key = EncodeTileToString(TileX, TileY);

            if (!Tiles.TryGetValue(Key, out AugmentedTile Tile))
            {
                Tile = new AugmentedTile(this, TileX, TileY);
                Tiles.Add(Key, Tile);
            }

            Tile.OnAugmentorPlaced(Type, Qty, RemoveFromInventory, Instance);
        }
 internal void OnAugmentorPlaced(AugmentorType Type, int Qty, bool RemoveFromInventory, Vector2 Tile, Augmentor Instance = null)
 {
     OnAugmentorPlaced(Type, Qty, RemoveFromInventory, (int)Tile.X, (int)Tile.Y, Instance);
 }
        public void OnAugmentorPlaced(string UniqueLocationName, AugmentorType Type, int Qty, bool RemoveFromInventory, int TileX, int TileY, Augmentor Instance = null)
        {
            if (!Locations.TryGetValue(UniqueLocationName, out AugmentedLocation Location))
            {
                Location = new AugmentedLocation(this, UniqueLocationName);
                Locations.Add(UniqueLocationName, Location);
            }

            Location.OnAugmentorPlaced(Type, Qty, RemoveFromInventory, TileX, TileY, Instance);
        }
 public void OnAugmentorPlaced(string UniqueLocationName, AugmentorType Type, int Qty, bool RemoveFromInventory, Vector2 Tile, Augmentor Instance = null)
 {
     OnAugmentorPlaced(UniqueLocationName, Type, Qty, RemoveFromInventory, (int)Tile.X, (int)Tile.Y, Instance);
 }