Search in sources :

Example 31 with FluidTank

use of net.minecraftforge.fluids.capability.templates.FluidTank in project Create by Creators-of-Create.

the class FluidTankConnectivityHandler method tryToFormNewTankOfWidth.

private static int tryToFormNewTankOfWidth(FluidTankTileEntity te, int width, TankSearchCache cache, boolean simulate) {
    int amount = 0;
    int height = 0;
    BlockEntityType<?> type = te.getType();
    Level world = te.getLevel();
    BlockPos origin = te.getBlockPos();
    LazyOptional<IFluidHandler> capability = te.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY);
    FluidTank teTank = (FluidTank) capability.orElse(null);
    FluidStack fluid = capability.map(ifh -> ifh.getFluidInTank(0)).orElse(FluidStack.EMPTY);
    Search: for (int yOffset = 0; yOffset < FluidTankTileEntity.getMaxHeight(); yOffset++) {
        for (int xOffset = 0; xOffset < width; xOffset++) {
            for (int zOffset = 0; zOffset < width; zOffset++) {
                BlockPos pos = origin.offset(xOffset, yOffset, zOffset);
                Optional<FluidTankTileEntity> tank = cache.getOrCache(type, world, pos);
                if (!tank.isPresent())
                    break Search;
                FluidTankTileEntity controller = tank.get();
                int otherWidth = controller.width;
                if (otherWidth > width)
                    break Search;
                BlockPos controllerPos = controller.getBlockPos();
                if (!controllerPos.equals(origin)) {
                    if (controllerPos.getX() < origin.getX())
                        break Search;
                    if (controllerPos.getZ() < origin.getZ())
                        break Search;
                    if (controllerPos.getX() + otherWidth > origin.getX() + width)
                        break Search;
                    if (controllerPos.getZ() + otherWidth > origin.getZ() + width)
                        break Search;
                }
                FluidStack otherFluid = controller.getTankInventory().getFluid();
                if (!fluid.isEmpty() && !otherFluid.isEmpty() && !fluid.isFluidEqual(otherFluid))
                    break Search;
            }
        }
        amount += width * width;
        height++;
    }
    if (simulate)
        return amount;
    boolean opaque = false;
    for (int yOffset = 0; yOffset < height; yOffset++) {
        for (int xOffset = 0; xOffset < width; xOffset++) {
            for (int zOffset = 0; zOffset < width; zOffset++) {
                BlockPos pos = origin.offset(xOffset, yOffset, zOffset);
                FluidTankTileEntity tank = tankAt(type, world, pos);
                if (tank == te)
                    continue;
                opaque |= !tank.window;
                FluidTank tankTank = tank.tankInventory;
                FluidStack fluidInTank = tankTank.getFluid();
                if (!fluidInTank.isEmpty()) {
                    if (teTank.isEmpty() && teTank instanceof CreativeSmartFluidTank)
                        ((CreativeSmartFluidTank) teTank).setContainedFluid(fluidInTank);
                    teTank.fill(fluidInTank, FluidAction.EXECUTE);
                }
                tankTank.setFluid(FluidStack.EMPTY);
                splitTankAndInvalidate(tank, cache, false);
                tank.setController(origin);
                tank.updateConnectivity = false;
                cache.put(pos, te);
                BlockState state = world.getBlockState(pos);
                if (!FluidTankBlock.isTank(state))
                    continue;
                state = state.setValue(FluidTankBlock.BOTTOM, yOffset == 0);
                state = state.setValue(FluidTankBlock.TOP, yOffset == height - 1);
                world.setBlock(pos, state, 22);
            }
        }
    }
    te.setWindows(!opaque);
    return amount;
}
Also used : PriorityQueue(java.util.PriorityQueue) Direction(net.minecraft.core.Direction) FluidAction(net.minecraftforge.fluids.capability.IFluidHandler.FluidAction) BlockState(net.minecraft.world.level.block.state.BlockState) HashMap(java.util.HashMap) FluidTank(net.minecraftforge.fluids.capability.templates.FluidTank) ArrayList(java.util.ArrayList) CreativeSmartFluidTank(com.simibubi.create.content.contraptions.fluids.tank.CreativeFluidTankTileEntity.CreativeSmartFluidTank) LazyOptional(net.minecraftforge.common.util.LazyOptional) HashSet(java.util.HashSet) Axis(net.minecraft.core.Direction.Axis) AxisDirection(net.minecraft.core.Direction.AxisDirection) BlockGetter(net.minecraft.world.level.BlockGetter) Pair(org.apache.commons.lang3.tuple.Pair) Map(java.util.Map) Nullable(javax.annotation.Nullable) IFluidHandler(net.minecraftforge.fluids.capability.IFluidHandler) Iterate(com.simibubi.create.foundation.utility.Iterate) CapabilityFluidHandler(net.minecraftforge.fluids.capability.CapabilityFluidHandler) Set(java.util.Set) BlockEntity(net.minecraft.world.level.block.entity.BlockEntity) List(java.util.List) BlockPos(net.minecraft.core.BlockPos) BlockEntityType(net.minecraft.world.level.block.entity.BlockEntityType) Optional(java.util.Optional) FluidStack(net.minecraftforge.fluids.FluidStack) Comparator(java.util.Comparator) Level(net.minecraft.world.level.Level) LazyOptional(net.minecraftforge.common.util.LazyOptional) Optional(java.util.Optional) CreativeSmartFluidTank(com.simibubi.create.content.contraptions.fluids.tank.CreativeFluidTankTileEntity.CreativeSmartFluidTank) FluidStack(net.minecraftforge.fluids.FluidStack) IFluidHandler(net.minecraftforge.fluids.capability.IFluidHandler) FluidTank(net.minecraftforge.fluids.capability.templates.FluidTank) CreativeSmartFluidTank(com.simibubi.create.content.contraptions.fluids.tank.CreativeFluidTankTileEntity.CreativeSmartFluidTank) BlockState(net.minecraft.world.level.block.state.BlockState) Level(net.minecraft.world.level.Level) BlockPos(net.minecraft.core.BlockPos)

Example 32 with FluidTank

use of net.minecraftforge.fluids.capability.templates.FluidTank in project Create by Creators-of-Create.

the class Contraption method readNBT.

public void readNBT(Level world, CompoundTag nbt, boolean spawnData) {
    blocks.clear();
    presentTileEntities.clear();
    specialRenderedTileEntities.clear();
    Tag blocks = nbt.get("Blocks");
    // used to differentiate between the 'old' and the paletted serialization
    boolean usePalettedDeserialization = blocks != null && blocks.getId() == 10 && ((CompoundTag) blocks).contains("Palette");
    readBlocksCompound(blocks, world, usePalettedDeserialization);
    actors.clear();
    nbt.getList("Actors", 10).forEach(c -> {
        CompoundTag comp = (CompoundTag) c;
        StructureBlockInfo info = this.blocks.get(NbtUtils.readBlockPos(comp.getCompound("Pos")));
        MovementContext context = MovementContext.readNBT(world, info, comp, this);
        getActors().add(MutablePair.of(info, context));
    });
    superglue.clear();
    NBTHelper.iterateCompoundList(nbt.getList("Superglue", Tag.TAG_COMPOUND), c -> superglue.add(Pair.of(NbtUtils.readBlockPos(c.getCompound("Pos")), Direction.from3DDataValue(c.getByte("Direction")))));
    seats.clear();
    NBTHelper.iterateCompoundList(nbt.getList("Seats", Tag.TAG_COMPOUND), c -> seats.add(NbtUtils.readBlockPos(c)));
    seatMapping.clear();
    NBTHelper.iterateCompoundList(nbt.getList("Passengers", Tag.TAG_COMPOUND), c -> seatMapping.put(NbtUtils.loadUUID(NBTHelper.getINBT(c, "Id")), c.getInt("Seat")));
    stabilizedSubContraptions.clear();
    NBTHelper.iterateCompoundList(nbt.getList("SubContraptions", Tag.TAG_COMPOUND), c -> stabilizedSubContraptions.put(c.getUUID("Id"), BlockFace.fromNBT(c.getCompound("Location"))));
    storage.clear();
    NBTHelper.iterateCompoundList(nbt.getList("Storage", Tag.TAG_COMPOUND), c -> storage.put(NbtUtils.readBlockPos(c.getCompound("Pos")), MountedStorage.deserialize(c.getCompound("Data"))));
    fluidStorage.clear();
    NBTHelper.iterateCompoundList(nbt.getList("FluidStorage", Tag.TAG_COMPOUND), c -> fluidStorage.put(NbtUtils.readBlockPos(c.getCompound("Pos")), MountedFluidStorage.deserialize(c.getCompound("Data"))));
    interactors.clear();
    NBTHelper.iterateCompoundList(nbt.getList("Interactors", Tag.TAG_COMPOUND), c -> {
        BlockPos pos = NbtUtils.readBlockPos(c.getCompound("Pos"));
        MovingInteractionBehaviour behaviour = AllInteractionBehaviours.of(getBlocks().get(pos).state.getBlock());
        if (behaviour != null)
            interactors.put(pos, behaviour);
    });
    if (spawnData)
        fluidStorage.forEach((pos, mfs) -> {
            BlockEntity tileEntity = presentTileEntities.get(pos);
            if (!(tileEntity instanceof FluidTankTileEntity))
                return;
            FluidTankTileEntity tank = (FluidTankTileEntity) tileEntity;
            IFluidTank tankInventory = tank.getTankInventory();
            if (tankInventory instanceof FluidTank)
                ((FluidTank) tankInventory).setFluid(mfs.tank.getFluid());
            tank.getFluidLevel().start(tank.getFillState());
            mfs.assignTileEntity(tank);
        });
    IItemHandlerModifiable[] handlers = new IItemHandlerModifiable[storage.size()];
    int index = 0;
    for (MountedStorage mountedStorage : storage.values()) handlers[index++] = mountedStorage.getItemHandler();
    IFluidHandler[] fluidHandlers = new IFluidHandler[fluidStorage.size()];
    index = 0;
    for (MountedFluidStorage mountedStorage : fluidStorage.values()) fluidHandlers[index++] = mountedStorage.getFluidHandler();
    inventory = new ContraptionInvWrapper(handlers);
    fluidInventory = new CombinedTankWrapper(fluidHandlers);
    if (nbt.contains("BoundsFront"))
        bounds = NBTHelper.readAABB(nbt.getList("BoundsFront", 5));
    stalled = nbt.getBoolean("Stalled");
    hasUniversalCreativeCrate = nbt.getBoolean("BottomlessSupply");
    anchor = NbtUtils.readBlockPos(nbt.getCompound("Anchor"));
}
Also used : BeltBlock(com.simibubi.create.content.contraptions.relays.belt.BeltBlock) Arrays(java.util.Arrays) AABB(net.minecraft.world.phys.AABB) SeatBlock(com.simibubi.create.content.contraptions.components.actors.SeatBlock) DebugPackets(net.minecraft.network.protocol.game.DebugPackets) Dist(net.minecraftforge.api.distmarker.Dist) Pair(org.apache.commons.lang3.tuple.Pair) Map(java.util.Map) IItemHandlerModifiable(net.minecraftforge.items.IItemHandlerModifiable) CombinedInvWrapper(net.minecraftforge.items.wrapper.CombinedInvWrapper) NbtUtils(net.minecraft.nbt.NbtUtils) ChestBlock(net.minecraft.world.level.block.ChestBlock) SimpleWaterloggedBlock(net.minecraft.world.level.block.SimpleWaterloggedBlock) Set(java.util.Set) PoiType(net.minecraft.world.entity.ai.village.poi.PoiType) BooleanOp(net.minecraft.world.phys.shapes.BooleanOp) BlockEntity(net.minecraft.world.level.block.entity.BlockEntity) AllInteractionBehaviours(com.simibubi.create.AllInteractionBehaviours) WindmillBearingBlock(com.simibubi.create.content.contraptions.components.structureMovement.bearing.WindmillBearingBlock) MechanicalPistonHeadBlock(com.simibubi.create.content.contraptions.components.structureMovement.piston.MechanicalPistonHeadBlock) FluidState(net.minecraft.world.level.material.FluidState) PulleyBlock(com.simibubi.create.content.contraptions.components.structureMovement.pulley.PulleyBlock) FluidStack(net.minecraftforge.fluids.FluidStack) ItemStack(net.minecraft.world.item.ItemStack) VoxelShape(net.minecraft.world.phys.shapes.VoxelShape) GantryShaftBlock(com.simibubi.create.content.contraptions.relays.advanced.GantryShaftBlock) ICoordinate(com.simibubi.create.foundation.utility.ICoordinate) OnlyIn(net.minecraftforge.api.distmarker.OnlyIn) BlockState(net.minecraft.world.level.block.state.BlockState) CreativeCrateTileEntity(com.simibubi.create.content.logistics.block.inventories.CreativeCrateTileEntity) FilteringBehaviour(com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringBehaviour) ArrayList(java.util.ArrayList) StickerBlock(com.simibubi.create.content.contraptions.components.structureMovement.chassis.StickerBlock) BiConsumer(java.util.function.BiConsumer) BlockFace(com.simibubi.create.foundation.utility.BlockFace) StructureBlockInfo(net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate.StructureBlockInfo) Nullable(javax.annotation.Nullable) SeatEntity(com.simibubi.create.content.contraptions.components.actors.SeatEntity) IFluidHandler(net.minecraftforge.fluids.capability.IFluidHandler) Iterate(com.simibubi.create.foundation.utility.Iterate) AllMovementBehaviours(com.simibubi.create.AllMovementBehaviours) MechanicalBearingBlock(com.simibubi.create.content.contraptions.components.structureMovement.bearing.MechanicalBearingBlock) CombinedTankWrapper(com.simibubi.create.foundation.fluid.CombinedTankWrapper) NBTHelper(com.simibubi.create.foundation.utility.NBTHelper) FluidTankTileEntity(com.simibubi.create.content.contraptions.fluids.tank.FluidTankTileEntity) ListTag(net.minecraft.nbt.ListTag) SuperGlueEntity(com.simibubi.create.content.contraptions.components.structureMovement.glue.SuperGlueEntity) EmptyLighter(com.simibubi.create.content.contraptions.components.structureMovement.render.EmptyLighter) IMultiTileContainer(com.simibubi.create.foundation.tileEntity.IMultiTileContainer) Direction(net.minecraft.core.Direction) RedstoneContactBlock(com.simibubi.create.content.logistics.block.redstone.RedstoneContactBlock) PressurePlateBlock(net.minecraft.world.level.block.PressurePlateBlock) FluidTank(net.minecraftforge.fluids.capability.templates.FluidTank) GantryCarriageBlock(com.simibubi.create.content.contraptions.components.structureMovement.gantry.GantryCarriageBlock) Rotation(net.minecraft.world.level.block.Rotation) MutablePair(org.apache.commons.lang3.tuple.MutablePair) GameData(net.minecraftforge.registries.GameData) RopeBlock(com.simibubi.create.content.contraptions.components.structureMovement.pulley.PulleyBlock.RopeBlock) MechanicalPistonBlock(com.simibubi.create.content.contraptions.components.structureMovement.piston.MechanicalPistonBlock) AllConfigs(com.simibubi.create.foundation.config.AllConfigs) PulleyTileEntity(com.simibubi.create.content.contraptions.components.structureMovement.pulley.PulleyTileEntity) UniqueLinkedList(com.simibubi.create.foundation.utility.UniqueLinkedList) BlockStateProperties(net.minecraft.world.level.block.state.properties.BlockStateProperties) NBTProcessors(com.simibubi.create.foundation.utility.NBTProcessors) UUID(java.util.UUID) StabilizedContraption(com.simibubi.create.content.contraptions.components.structureMovement.bearing.StabilizedContraption) MagnetBlock(com.simibubi.create.content.contraptions.components.structureMovement.pulley.PulleyBlock.MagnetBlock) Collectors(java.util.stream.Collectors) Blocks(net.minecraft.world.level.block.Blocks) Objects(java.util.Objects) AbstractChassisBlock(com.simibubi.create.content.contraptions.components.structureMovement.chassis.AbstractChassisBlock) PistonExtensionPoleBlock(com.simibubi.create.content.contraptions.components.structureMovement.piston.PistonExtensionPoleBlock) List(java.util.List) CompoundTag(net.minecraft.nbt.CompoundTag) BlockPos(net.minecraft.core.BlockPos) HashMapPalette(net.minecraft.world.level.chunk.HashMapPalette) Entry(java.util.Map.Entry) Optional(java.util.Optional) LevelAccessor(net.minecraft.world.level.LevelAccessor) IFluidTank(net.minecraftforge.fluids.IFluidTank) Queue(java.util.Queue) Shapes(net.minecraft.world.phys.shapes.Shapes) Level(net.minecraft.world.level.Level) Tag(net.minecraft.nbt.Tag) PistonType(net.minecraft.world.level.block.state.properties.PistonType) KineticTileEntity(com.simibubi.create.content.contraptions.base.KineticTileEntity) FluidAction(net.minecraftforge.fluids.capability.IFluidHandler.FluidAction) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) ServerLevel(net.minecraft.server.level.ServerLevel) HashSet(java.util.HashSet) ItemVaultTileEntity(com.simibubi.create.content.logistics.block.vault.ItemVaultTileEntity) Axis(net.minecraft.core.Direction.Axis) IRotate(com.simibubi.create.content.contraptions.base.IRotate) PushReaction(net.minecraft.world.level.material.PushReaction) ButtonBlock(net.minecraft.world.level.block.ButtonBlock) Fluids(net.minecraft.world.level.material.Fluids) AllBlocks(com.simibubi.create.AllBlocks) ChestType(net.minecraft.world.level.block.state.properties.ChestType) Iterator(java.util.Iterator) SuperGlueHandler(com.simibubi.create.content.contraptions.components.structureMovement.glue.SuperGlueHandler) MechanicalPistonBlock.isPistonHead(com.simibubi.create.content.contraptions.components.structureMovement.piston.MechanicalPistonBlock.isPistonHead) PistonState(com.simibubi.create.content.contraptions.components.structureMovement.piston.MechanicalPistonBlock.PistonState) Entity(net.minecraft.world.entity.Entity) MechanicalPistonBlock.isExtensionPole(com.simibubi.create.content.contraptions.components.structureMovement.piston.MechanicalPistonBlock.isExtensionPole) ChassisTileEntity(com.simibubi.create.content.contraptions.components.structureMovement.chassis.ChassisTileEntity) Vec3(net.minecraft.world.phys.Vec3) Block(net.minecraft.world.level.block.Block) FluidTankTileEntity(com.simibubi.create.content.contraptions.fluids.tank.FluidTankTileEntity) IFluidHandler(net.minecraftforge.fluids.capability.IFluidHandler) FluidTank(net.minecraftforge.fluids.capability.templates.FluidTank) IFluidTank(net.minecraftforge.fluids.IFluidTank) IItemHandlerModifiable(net.minecraftforge.items.IItemHandlerModifiable) BlockPos(net.minecraft.core.BlockPos) ListTag(net.minecraft.nbt.ListTag) CompoundTag(net.minecraft.nbt.CompoundTag) Tag(net.minecraft.nbt.Tag) StructureBlockInfo(net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate.StructureBlockInfo) CompoundTag(net.minecraft.nbt.CompoundTag) IFluidTank(net.minecraftforge.fluids.IFluidTank) CombinedTankWrapper(com.simibubi.create.foundation.fluid.CombinedTankWrapper) BlockEntity(net.minecraft.world.level.block.entity.BlockEntity)

Example 33 with FluidTank

use of net.minecraftforge.fluids.capability.templates.FluidTank in project Magma-1.16.x by magmafoundation.

the class CapabilityFluidHandler method register.

public static void register() {
    CapabilityManager.INSTANCE.register(IFluidHandler.class, new DefaultFluidHandlerStorage<>(), () -> new FluidTank(FluidAttributes.BUCKET_VOLUME));
    CapabilityManager.INSTANCE.register(IFluidHandlerItem.class, new DefaultFluidHandlerStorage<>(), () -> new FluidHandlerItemStack(new ItemStack(Items.BUCKET), FluidAttributes.BUCKET_VOLUME));
}
Also used : FluidTank(net.minecraftforge.fluids.capability.templates.FluidTank) FluidHandlerItemStack(net.minecraftforge.fluids.capability.templates.FluidHandlerItemStack) ItemStack(net.minecraft.item.ItemStack) FluidHandlerItemStack(net.minecraftforge.fluids.capability.templates.FluidHandlerItemStack)

Example 34 with FluidTank

use of net.minecraftforge.fluids.capability.templates.FluidTank in project LoliServer by Loli-Server.

the class CapabilityFluidHandler method register.

public static void register() {
    CapabilityManager.INSTANCE.register(IFluidHandler.class, new DefaultFluidHandlerStorage<>(), () -> new FluidTank(FluidAttributes.BUCKET_VOLUME));
    CapabilityManager.INSTANCE.register(IFluidHandlerItem.class, new DefaultFluidHandlerStorage<>(), () -> new FluidHandlerItemStack(new ItemStack(Items.BUCKET), FluidAttributes.BUCKET_VOLUME));
}
Also used : FluidTank(net.minecraftforge.fluids.capability.templates.FluidTank) FluidHandlerItemStack(net.minecraftforge.fluids.capability.templates.FluidHandlerItemStack) ItemStack(net.minecraft.item.ItemStack) FluidHandlerItemStack(net.minecraftforge.fluids.capability.templates.FluidHandlerItemStack)

Example 35 with FluidTank

use of net.minecraftforge.fluids.capability.templates.FluidTank in project EvilCraft by CyclopsMC.

the class BlockTankHelpers method itemStackDataToTile.

/**
 * Convert fluid capabilities of item to tile.
 * @param itemStack The itemstack.
 * @param tile The tile that has already been removed from the world.
 */
public static void itemStackDataToTile(ItemStack itemStack, BlockEntity tile) {
    IFluidHandler fluidHandlerTile = tile.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY).orElse(null);
    if (fluidHandlerTile != null) {
        IFluidHandlerItemCapacity fluidHandlerItemCapacity = itemStack.getCapability(Capabilities.FLUID_HANDLER_ITEM_CAPACITY).orElse(null);
        if (fluidHandlerItemCapacity != null) {
            if (fluidHandlerTile instanceof FluidTank) {
                FluidTank fluidTank = (FluidTank) fluidHandlerTile;
                fluidTank.setCapacity(fluidHandlerItemCapacity.getCapacity());
            }
        }
        IFluidHandlerItem fluidHandlerItem = itemStack.getCapability(CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY).orElse(null);
        if (fluidHandlerItem != null) {
            FluidUtil.tryEmptyContainer(itemStack, fluidHandlerTile, Integer.MAX_VALUE, null, true);
        }
    }
}
Also used : FluidTank(net.minecraftforge.fluids.capability.templates.FluidTank) IFluidTank(net.minecraftforge.fluids.IFluidTank) IFluidHandlerItem(net.minecraftforge.fluids.capability.IFluidHandlerItem) IFluidHandlerItemCapacity(org.cyclops.cyclopscore.capability.fluid.IFluidHandlerItemCapacity) IFluidHandler(net.minecraftforge.fluids.capability.IFluidHandler)

Aggregations

FluidTank (net.minecraftforge.fluids.capability.templates.FluidTank)35 FluidStack (net.minecraftforge.fluids.FluidStack)20 IFluidHandler (net.minecraftforge.fluids.capability.IFluidHandler)8 ItemStack (net.minecraft.world.item.ItemStack)7 BlockPos (net.minecraft.core.BlockPos)6 Direction (net.minecraft.core.Direction)6 ComponentInventory (electrodynamics.prefab.tile.components.type.ComponentInventory)5 CompoundTag (net.minecraft.nbt.CompoundTag)5 ArrayList (java.util.ArrayList)4 BucketItem (net.minecraft.world.item.BucketItem)4 Level (net.minecraft.world.level.Level)4 BlockEntity (net.minecraft.world.level.block.entity.BlockEntity)4 ComponentDirection (electrodynamics.prefab.tile.components.type.ComponentDirection)3 Nonnull (javax.annotation.Nonnull)3 Nullable (javax.annotation.Nullable)3 ItemStack (net.minecraft.item.ItemStack)3 BlockState (net.minecraft.world.level.block.state.BlockState)3 AABB (net.minecraft.world.phys.AABB)3 VertexConsumer (com.mojang.blaze3d.vertex.VertexConsumer)2 Iterate (com.simibubi.create.foundation.utility.Iterate)2