protected override void ActivateSlotRightClick(ItemSlot sourceSlot, ref ItemStackMoveOperation op)
        {
            ItemSlotLiquidOnly liquidSlot = inventory[1] as ItemSlotLiquidOnly;
            IWorldAccessor     world      = inventory.Api.World;

            if (sourceSlot?.Itemstack?.Collectible is ILiquidSink sink && !liquidSlot.Empty && sink.AllowHeldLiquidTransfer)
            {
                ItemStack liqSlotStack         = liquidSlot.Itemstack;
                var       curTargetLiquidStack = sink.GetContent(sourceSlot.Itemstack);

                bool liquidstackable = curTargetLiquidStack == null || liqSlotStack.Equals(world, curTargetLiquidStack, GlobalConstants.IgnoredStackAttributes);

                if (liquidstackable)
                {
                    var lprops = BlockLiquidContainerBase.GetContainableProps(liqSlotStack);

                    float curSourceLitres = liqSlotStack.StackSize / lprops.ItemsPerLitre;
                    float curTargetLitres = sink.GetCurrentLitres(sourceSlot.Itemstack);

                    float toMoveLitres = op.CtrlDown ? sink.TransferSizeLitres : (sink.CapacityLitres - curTargetLitres);

                    toMoveLitres *= sourceSlot.StackSize;
                    toMoveLitres  = Math.Min(curSourceLitres, toMoveLitres);

                    if (toMoveLitres > 0)
                    {
                        op.MovedQuantity = sink.TryPutLiquid(sourceSlot.Itemstack, liqSlotStack, toMoveLitres / sourceSlot.StackSize);

                        liquidSlot.Itemstack.StackSize -= op.MovedQuantity * sourceSlot.StackSize;
                        if (liquidSlot.Itemstack.StackSize <= 0)
                        {
                            liquidSlot.Itemstack = null;
                        }
                        liquidSlot.MarkDirty();
                        sourceSlot.MarkDirty();

                        var pos = op.ActingPlayer?.Entity?.Pos;
                        if (pos != null)
                        {
                            op.World.PlaySoundAt(lprops.PourSound, pos.X, pos.Y, pos.Z);
                        }
                    }
                }

                return;
            }

            base.ActivateSlotRightClick(sourceSlot, ref op);
        }
Пример #2
0
        public override void OnItemSlotModified(ItemStack stack)
        {
            base.OnItemSlotModified(stack);

            if (itemstack == null)
            {
                return;
            }

            ItemSlotLiquidOnly liquidSlot = inventory[1] as ItemSlotLiquidOnly;

            bool stackable = !liquidSlot.Empty && liquidSlot.Itemstack.Equals(inventory.Api.World, itemstack, GlobalConstants.IgnoredStackAttributes);

            if (stackable)
            {
                int remaining = liquidSlot.Itemstack.Collectible.MaxStackSize - liquidSlot.Itemstack.StackSize;

                WaterTightContainableProps props = BlockLiquidContainerBase.GetInContainerProps(liquidSlot.Itemstack);
                if (props != null)
                {
                    int max         = (int)(liquidSlot.CapacityLitres * props.ItemsPerLitre);
                    int maxOverride = props.MaxStackSize;  //allows 64 rot to be placed in barrel
                    remaining = Math.Max(max, maxOverride) - liquidSlot.Itemstack.StackSize;
                }

                int moved = GameMath.Clamp(itemstack.StackSize, 0, remaining);
                liquidSlot.Itemstack.StackSize += moved;

                itemstack.StackSize -= moved;
                if (itemstack.StackSize <= 0)
                {
                    itemstack = null;
                }

                liquidSlot.MarkDirty();
                MarkDirty();
                return;
            }

            if (itemstack.Collectible.Attributes?.IsTrue("barrelMoveToLiquidSlot") == true || itemstack.Collectible.Attributes?["waterTightContainerProps"].Exists == true)
            {
                if (stackable)
                {
                    int remainingspace = itemstack.Collectible.MaxStackSize - liquidSlot.StackSize;
                    int movableq       = Math.Min(itemstack.StackSize, remainingspace);

                    liquidSlot.Itemstack.StackSize += movableq;
                    this.itemstack.StackSize       -= movableq;
                    if (StackSize <= 0)
                    {
                        itemstack = null;
                    }

                    MarkDirty();
                    liquidSlot.MarkDirty();
                    return;
                }
                if (liquidSlot.Empty)
                {
                    liquidSlot.Itemstack = this.itemstack.Clone();
                    this.itemstack       = null;
                    MarkDirty();
                    liquidSlot.MarkDirty();
                }
            }

            return;
        }
        protected override void ActivateSlotLeftClick(ItemSlot sourceSlot, ref ItemStackMoveOperation op)
        {
            if (sourceSlot.Empty)
            {
                base.ActivateSlotLeftClick(sourceSlot, ref op);
                return;
            }

            IWorldAccessor world = inventory.Api.World;

            if (sourceSlot.Itemstack.Collectible is ILiquidSource source && source.AllowHeldLiquidTransfer)
            {
                ItemSlotLiquidOnly liquidSlot = inventory[1] as ItemSlotLiquidOnly;

                ItemStack bucketContents = source.GetContent(sourceSlot.Itemstack);
                bool      stackable      = !liquidSlot.Empty && liquidSlot.Itemstack.Equals(world, bucketContents, GlobalConstants.IgnoredStackAttributes);

                if ((liquidSlot.Empty || stackable) && bucketContents != null)
                {
                    ItemStack bucketStack = sourceSlot.Itemstack;

                    var lprops = BlockLiquidContainerBase.GetContainableProps(bucketContents);

                    float toMoveLitres    = op.CtrlDown ? source.TransferSizeLitres : source.CapacityLitres;
                    float curSourceLitres = bucketContents.StackSize / lprops.ItemsPerLitre * bucketStack.StackSize;
                    float curDestLitres   = liquidSlot.StackSize / lprops.ItemsPerLitre;

                    // Cap by source amount
                    toMoveLitres = Math.Min(toMoveLitres, curSourceLitres);
                    // Cap by target capacity
                    toMoveLitres = Math.Min(toMoveLitres, liquidSlot.CapacityLitres - curDestLitres);

                    if (toMoveLitres > 0)
                    {
                        int       moveQuantity      = (int)(toMoveLitres * lprops.ItemsPerLitre);
                        ItemStack takenContentStack = source.TryTakeContent(bucketStack, moveQuantity / bucketStack.StackSize);

                        takenContentStack.StackSize *= bucketStack.StackSize;
                        takenContentStack.StackSize += liquidSlot.StackSize;

                        liquidSlot.Itemstack = takenContentStack;
                        liquidSlot.MarkDirty();
                        op.MovedQuantity = moveQuantity;

                        var pos = op.ActingPlayer?.Entity?.Pos;
                        if (pos != null)
                        {
                            op.World.PlaySoundAt(lprops.FillSound, pos.X, pos.Y, pos.Z);
                        }
                    }

                    return;
                }

                return;
            }



            string contentItemCode = sourceSlot.Itemstack?.ItemAttributes?["contentItemCode"].AsString();

            if (contentItemCode != null)
            {
                ItemSlot liquidSlot = inventory[1];

                ItemStack contentStack = new ItemStack(world.GetItem(new AssetLocation(contentItemCode)));
                bool      stackable    = !liquidSlot.Empty && liquidSlot.Itemstack.Equals(world, contentStack, GlobalConstants.IgnoredStackAttributes);

                if ((liquidSlot.Empty || stackable) && contentStack != null)
                {
                    if (stackable)
                    {
                        liquidSlot.Itemstack.StackSize++;
                    }
                    else
                    {
                        liquidSlot.Itemstack = contentStack;
                    }

                    liquidSlot.MarkDirty();

                    ItemStack bowlStack = new ItemStack(world.GetBlock(new AssetLocation(sourceSlot.Itemstack.ItemAttributes["emptiedBlockCode"].AsString())));
                    if (sourceSlot.StackSize == 1)
                    {
                        sourceSlot.Itemstack = bowlStack;
                    }
                    else
                    {
                        sourceSlot.Itemstack.StackSize--;
                        if (!op.ActingPlayer.InventoryManager.TryGiveItemstack(bowlStack))
                        {
                            world.SpawnItemEntity(bowlStack, op.ActingPlayer.Entity.Pos.XYZ);
                        }
                    }
                    sourceSlot.MarkDirty();
                }

                return;
            }

            base.ActivateSlotLeftClick(sourceSlot, ref op);
        }