public void ServeIntoBowl(Block selectedBlock, BlockPos pos, ItemSlot potslot, IWorldAccessor world)
        {
            if (world.Side == EnumAppSide.Client)
            {
                return;
            }

            string code      = selectedBlock.Attributes["mealBlockCode"].AsString();
            Block  mealblock = api.World.GetBlock(new AssetLocation(code));

            world.BlockAccessor.SetBlock(mealblock.BlockId, pos);

            IBlockEntityMealContainer bemeal = api.World.BlockAccessor.GetBlockEntity(pos) as IBlockEntityMealContainer;

            if (bemeal == null)
            {
                return;
            }

            if (tryMergeServingsIntoBE(bemeal, potslot))
            {
                return;
            }

            bemeal.RecipeCode = GetRecipeCode(world, potslot.Itemstack);

            ItemStack[] myStacks = GetNonEmptyContents(api.World, potslot.Itemstack);
            for (int i = 0; i < myStacks.Length; i++)
            {
                bemeal.inventory[i].Itemstack = myStacks[i].Clone();
            }

            float quantityServings   = GetServings(world, potslot.Itemstack);
            float servingsToTransfer = Math.Min(quantityServings, selectedBlock.Attributes["servingCapacity"].AsFloat(1));

            bemeal.QuantityServings = servingsToTransfer;


            SetServings(world, potslot.Itemstack, quantityServings - servingsToTransfer);

            if (quantityServings - servingsToTransfer <= 0)
            {
                string loc = potslot.Itemstack.Collectible.Attributes["emptiedBlockCode"].AsString();
                if (loc != null)
                {
                    Block emptyPotBlock = world.GetBlock(new AssetLocation(loc));
                    potslot.Itemstack = new ItemStack(emptyPotBlock);
                }
                else
                {
                    SetRecipeCode(api.World, potslot.Itemstack, null);
                }
            }

            potslot.MarkDirty();
            bemeal.MarkDirty(true);
        }
        private bool tryMergeServingsIntoBE(IBlockEntityMealContainer bemeal, ItemSlot potslot)
        {
            ItemStack[] myStacks = GetNonEmptyContents(api.World, potslot.Itemstack);

            string hisRecipeCode = bemeal.RecipeCode;

            ItemStack[] hisStacks   = bemeal.GetNonEmptyContentStacks();
            float       hisServings = bemeal.QuantityServings;

            string ownRecipeCode   = GetRecipeCode(api.World, potslot.Itemstack);
            float  servingCapacity = (bemeal as BlockEntity).Block.Attributes["servingCapacity"].AsFloat(1);

            // Empty
            if (hisStacks == null || hisServings == 0)
            {
                return(false);
            }
            // Different ingredient quantity
            if (myStacks.Length != hisStacks.Length)
            {
                return(true);
            }
            // Different recipe
            if (ownRecipeCode != hisRecipeCode)
            {
                return(true);
            }
            // No more empty space
            float remainingPlaceableServings = servingCapacity - hisServings;

            if (remainingPlaceableServings <= 0)
            {
                return(true);
            }
            // Different ingredients
            for (int i = 0; i < myStacks.Length; i++)
            {
                if (!myStacks[i].Equals(api.World, hisStacks[i], GlobalConstants.IgnoredStackAttributes))
                {
                    return(true);
                }
            }


            // Ok merge transition states
            for (int i = 0; i < hisStacks.Length; i++)
            {
                ItemStackMergeOperation op = new ItemStackMergeOperation(api.World, EnumMouseButton.Left, 0, EnumMergePriority.ConfirmedMerge, myStacks[i].StackSize);
                op.SourceSlot = new DummySlot(myStacks[i]);
                op.SinkSlot   = new DummySlot(hisStacks[i]);
                hisStacks[i].Collectible.TryMergeStacks(op);
            }

            // Now increase serving siize
            float quantityServings = GetServings(api.World, potslot.Itemstack);
            float movedservings    = Math.Min(remainingPlaceableServings, quantityServings);

            bemeal.QuantityServings = hisServings + movedservings;

            SetServings(api.World, potslot.Itemstack, quantityServings - movedservings);
            if (quantityServings - movedservings <= 0)
            {
                string loc = Attributes["emptiedBlockCode"].AsString();
                if (loc != null)
                {
                    Block emptyPotBlock = api.World.GetBlock(new AssetLocation(loc));
                    potslot.Itemstack = new ItemStack(emptyPotBlock);
                }
                else
                {
                    SetRecipeCode(api.World, potslot.Itemstack, null);
                }
            }

            potslot.MarkDirty();
            bemeal.MarkDirty(true);

            return(true);
        }