Ejemplo n.º 1
0
        private void TryPullFrom(BlockFacing inputFace)
        {
            BlockPos InputPosition = Pos.AddCopy(inputFace);

            if (Api.World.BlockAccessor.GetBlockEntity(InputPosition) is BlockEntityContainer beContainer)
            {
                //do not both push and pull across the same chute-chute connection
                if (beContainer.Block is BlockChute chute)
                {
                    string[] pushFaces = chute.Attributes["pushFaces"].AsArray <string>(null);
                    if (pushFaces?.Contains(inputFace.Opposite.Code) == true)
                    {
                        return;
                    }
                }

                ItemSlot            sourceSlot = beContainer.Inventory.GetAutoPullFromSlot(inputFace.Opposite);
                ItemSlot            targetSlot = sourceSlot == null ? null : inventory.GetBestSuitedSlot(sourceSlot).slot;
                BlockEntityItemFlow beFlow     = beContainer as BlockEntityItemFlow;

                if (sourceSlot != null && targetSlot != null && (beFlow == null || targetSlot.Empty))
                {
                    ItemStackMoveOperation op = new ItemStackMoveOperation(Api.World, EnumMouseButton.Left, 0, EnumMergePriority.DirectMerge, (int)itemFlowAccum);

                    int horTravelled = sourceSlot.Itemstack.Attributes.GetInt("chuteQHTravelled");
                    if (horTravelled < 2)
                    {
                        int qmoved = sourceSlot.TryPutInto(targetSlot, ref op);
                        if (qmoved > 0)
                        {
                            if (beFlow != null)
                            {
                                targetSlot.Itemstack.Attributes.SetInt("chuteQHTravelled", inputFace.IsHorizontal ? (horTravelled + 1): 0);
                                targetSlot.Itemstack.Attributes.SetInt("chuteDir", inputFace.Opposite.Index);
                            }
                            else
                            {
                                targetSlot.Itemstack.Attributes.RemoveAttribute("chuteQHTravelled");
                                targetSlot.Itemstack.Attributes.RemoveAttribute("chuteDir");
                            }

                            sourceSlot.MarkDirty();
                            targetSlot.MarkDirty();
                            MarkDirty(false);
                            beFlow?.MarkDirty();
                        }

                        if (qmoved > 0 && Api.World.Rand.NextDouble() < 0.2)
                        {
                            Api.World.PlaySoundAt(hopperTumble, Pos.X + 0.5, Pos.Y + 0.5, Pos.Z + 0.5, null, true, 8, 0.5f);

                            itemFlowAccum -= qmoved;
                        }
                    }
                }
            }
        }
Ejemplo n.º 2
0
        private bool TryPushInto(BlockFacing outputFace)
        {
            BlockPos OutputPosition = Pos.AddCopy(outputFace);

            if (Api.World.BlockAccessor.GetBlockEntity(OutputPosition) is BlockEntityContainer beContainer)
            {
                ItemSlot sourceSlot = inventory.FirstOrDefault(slot => !slot.Empty);
                if ((sourceSlot?.Itemstack?.StackSize ?? 0) == 0)
                {
                    return(false);                                               //seems FirstOrDefault() method can sometimes give a slot with stacksize == 0, weird
                }
                int horTravelled = sourceSlot.Itemstack.Attributes.GetInt("chuteQHTravelled");
                int chuteDir     = sourceSlot.Itemstack.Attributes.GetInt("chuteDir");
                sourceSlot.Itemstack.Attributes.RemoveAttribute("chuteQHTravelled");
                sourceSlot.Itemstack.Attributes.RemoveAttribute("chuteDir");

                if (horTravelled >= 2)
                {
                    return(false);                    //chutes can't move items more than 1 block horizontally without a drop
                }
                ItemSlot            targetSlot = beContainer.Inventory.GetAutoPushIntoSlot(outputFace.Opposite, sourceSlot);
                BlockEntityItemFlow beFlow     = beContainer as BlockEntityItemFlow;

                if (targetSlot != null && (beFlow == null || targetSlot.Empty))
                {
                    int quantity = (int)itemFlowAccum;
                    ItemStackMoveOperation op = new ItemStackMoveOperation(Api.World, EnumMouseButton.Left, 0, EnumMergePriority.DirectMerge, quantity);

                    int qmoved = sourceSlot.TryPutInto(targetSlot, ref op);

                    if (qmoved > 0)
                    {
                        if (Api.World.Rand.NextDouble() < 0.2)
                        {
                            Api.World.PlaySoundAt(hopperTumble, Pos.X + 0.5, Pos.Y + 0.5, Pos.Z + 0.5, null, true, 8, 0.5f);
                        }

                        if (beFlow != null)
                        {
                            targetSlot.Itemstack.Attributes.SetInt("chuteQHTravelled", outputFace.IsHorizontal ? (horTravelled + 1) : 0);
                            targetSlot.Itemstack.Attributes.SetInt("chuteDir", outputFace.Index);
                        }
                        else
                        {
                            targetSlot.Itemstack.Attributes.RemoveAttribute("chuteQHTravelled");
                            targetSlot.Itemstack.Attributes.RemoveAttribute("chuteDir");
                        }

                        sourceSlot.MarkDirty();
                        targetSlot.MarkDirty();
                        MarkDirty(false);
                        beFlow?.MarkDirty(false);

                        itemFlowAccum -= qmoved;

                        return(true);
                    }
                    else
                    {
                        //If the push failed, re-apply original chuteDir so that the itemStack still has it for next push attempt
                        sourceSlot.Itemstack.Attributes.SetInt("chuteDir", chuteDir);
                    }
                }
            }

            return(false);
        }