private ItemSlot GetAutoPullFromSlot(BlockFacing atBlockFace) { if (atBlockFace == BlockFacing.DOWN) { return(inventory.FirstOrDefault(slot => !slot.Empty)); } return(null); }
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); }