• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

CyclopsMC / IntegratedDynamics / 20634822687

01 Jan 2026 07:38AM UTC coverage: 45.043% (-0.2%) from 45.223%
20634822687

push

github

web-flow
Add translations through Crowdin (#1581)

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>

2614 of 8582 branches covered (30.46%)

Branch coverage included in aggregate %.

11869 of 23572 relevant lines covered (50.35%)

2.39 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

45.3
/src/main/java/org/cyclops/integrateddynamics/blockentity/BlockEntitySqueezer.java
1
package org.cyclops.integrateddynamics.blockentity;
2

3
import com.google.common.collect.Lists;
4
import lombok.Getter;
5
import net.minecraft.core.BlockPos;
6
import net.minecraft.core.Direction;
7
import net.minecraft.core.HolderLookup;
8
import net.minecraft.nbt.CompoundTag;
9
import net.minecraft.world.item.ItemStack;
10
import net.minecraft.world.item.crafting.CraftingInput;
11
import net.minecraft.world.item.crafting.RecipeHolder;
12
import net.minecraft.world.item.crafting.RecipeType;
13
import net.minecraft.world.level.Level;
14
import net.minecraft.world.level.block.entity.BlockEntityType;
15
import net.minecraft.world.level.block.state.BlockState;
16
import net.neoforged.neoforge.fluids.FluidStack;
17
import net.neoforged.neoforge.fluids.capability.IFluidHandler;
18
import net.neoforged.neoforge.items.IItemHandler;
19
import net.neoforged.neoforge.items.ItemHandlerHelper;
20
import org.cyclops.cyclopscore.blockentity.BlockEntityTickerDelayed;
21
import org.cyclops.cyclopscore.blockentity.CyclopsBlockEntity;
22
import org.cyclops.cyclopscore.capability.registrar.BlockEntityCapabilityRegistrar;
23
import org.cyclops.cyclopscore.datastructure.SingleCache;
24
import org.cyclops.cyclopscore.fluid.SingleUseTank;
25
import org.cyclops.cyclopscore.helper.BlockEntityHelpers;
26
import org.cyclops.cyclopscore.helper.CraftingHelpers;
27
import org.cyclops.cyclopscore.helper.FluidHelpers;
28
import org.cyclops.cyclopscore.helper.ItemStackHelpers;
29
import org.cyclops.cyclopscore.inventory.SimpleInventory;
30
import org.cyclops.cyclopscore.inventory.SimpleInventoryState;
31
import org.cyclops.cyclopscore.persist.nbt.NBTPersist;
32
import org.cyclops.integrateddynamics.RegistryEntries;
33
import org.cyclops.integrateddynamics.block.BlockSqueezer;
34
import org.cyclops.integrateddynamics.core.recipe.handler.RecipeHandlerSqueezer;
35
import org.cyclops.integrateddynamics.core.recipe.type.RecipeSqueezer;
36

37
import java.util.Arrays;
38
import java.util.Optional;
39
import java.util.function.Supplier;
40

41
/**
42
 * A part entity for squeezing stuff.
43
 * @author rubensworks
44
 */
45
public class BlockEntitySqueezer extends CyclopsBlockEntity {
46

47
    private final SimpleInventory inventory;
48
    private final SingleUseTank tank;
49

50
    @NBTPersist
3✔
51
    @Getter
3✔
52
    private int itemHeight = 1;
53

54
    private SingleCache<ItemStack, Optional<RecipeHolder<RecipeSqueezer>>> recipeCache;
55

56
    public BlockEntitySqueezer(BlockPos blockPos, BlockState blockState) {
57
        super(RegistryEntries.BLOCK_ENTITY_SQUEEZER.get(), blockPos, blockState);
7✔
58

59
        // Create inventory and tank
60
        this.inventory = new SimpleInventory(1, 1) {
16✔
61
            @Override
62
            public boolean canPlaceItem(int slot, ItemStack itemStack) {
63
                return getLevel().getBlockState(getBlockPos()).getValue(BlockSqueezer.HEIGHT) == 1
×
64
                        && getItem(0).isEmpty() && super.canPlaceItem(slot, itemStack);
×
65
            }
66

67
            @Override
68
            public void setItem(int slotId, ItemStack itemstack) {
69
                super.setItem(slotId, itemstack);
4✔
70
                itemHeight = 1;
4✔
71
                sendUpdate();
3✔
72
            }
1✔
73
        };
74
        this.tank = new SingleUseTank(FluidHelpers.BUCKET_VOLUME);
6✔
75

76
        // Add dirty mark listeners to inventory and tank
77
        this.inventory.addDirtyMarkListener(this::sendUpdate);
5✔
78
        this.tank.addDirtyMarkListener(this.inventory::setChanged);
9✔
79

80
        // Efficient cache to retrieve the current craftable recipe.
81
        recipeCache = new SingleCache<>(
9✔
82
                new SingleCache.ICacheUpdater<ItemStack, Optional<RecipeHolder<RecipeSqueezer>>>() {
6✔
83
                    @Override
84
                    public Optional<RecipeHolder<RecipeSqueezer>> getNewValue(ItemStack key) {
85
                        return CraftingHelpers.findServerRecipe(getRegistry(), CraftingInput.of(1, 1, Lists.newArrayList(key)), getLevel());
18✔
86
                    }
87

88
                    @Override
89
                    public boolean isKeyEqual(ItemStack cacheKey, ItemStack newKey) {
90
                        return ItemStack.matches(cacheKey, newKey);
×
91
                    }
92
                });
93
    }
1✔
94

95
    public static class CapabilityRegistrar extends BlockEntityCapabilityRegistrar<BlockEntitySqueezer> {
96
        public CapabilityRegistrar(Supplier<BlockEntityType<? extends BlockEntitySqueezer>> blockEntityType) {
97
            super(blockEntityType);
3✔
98
        }
1✔
99

100
        @Override
101
        public void populate() {
102
            add(
4✔
103
                    net.neoforged.neoforge.capabilities.Capabilities.ItemHandler.BLOCK,
104
                    (blockEntity, direction) -> blockEntity.getInventory().getItemHandler()
×
105
            );
106
            add(
4✔
107
                    org.cyclops.commoncapabilities.api.capability.Capabilities.InventoryState.BLOCK,
108
                    (blockEntity, direction) -> new SimpleInventoryState(blockEntity.getInventory())
×
109
            );
110
            add(
4✔
111
                    net.neoforged.neoforge.capabilities.Capabilities.FluidHandler.BLOCK,
112
                    (blockEntity, direction) -> blockEntity.getTank()
×
113
            );
114
            add(
4✔
115
                    org.cyclops.commoncapabilities.api.capability.Capabilities.RecipeHandler.BLOCK,
116
                    (blockEntity, direction) -> new RecipeHandlerSqueezer<>(blockEntity::getLevel, RegistryEntries.RECIPETYPE_SQUEEZER.get())
×
117
            );
118
        }
1✔
119
    }
120

121
    public SimpleInventory getInventory() {
122
        return inventory;
3✔
123
    }
124

125
    public SingleUseTank getTank() {
126
        return tank;
3✔
127
    }
128

129
    @Override
130
    public void read(CompoundTag tag, HolderLookup.Provider provider) {
131
        inventory.readFromNBT(provider, tag, "inventory");
×
132
        tank.readFromNBT(provider, tag, "tank");
×
133
        super.read(tag, provider);
×
134
    }
×
135

136
    @Override
137
    public void saveAdditional(CompoundTag tag, HolderLookup.Provider provider) {
138
        inventory.writeToNBT(provider, tag, "inventory");
6✔
139
        tank.writeToNBT(provider, tag, "tank");
7✔
140
        super.saveAdditional(tag, provider);
4✔
141
    }
1✔
142

143
    protected RecipeType<RecipeSqueezer> getRegistry() {
144
        return RegistryEntries.RECIPETYPE_SQUEEZER.get();
4✔
145
    }
146

147
    public Optional<RecipeHolder<RecipeSqueezer>> getCurrentRecipe() {
148
        return recipeCache.get(getInventory().getItem(0).copy());
10✔
149
    }
150

151
    public void setItemHeight(int itemHeight) {
152
        this.itemHeight = itemHeight;
3✔
153
        sendUpdate();
2✔
154
        getInventory().setChanged();
3✔
155
    }
1✔
156

157
    public static class Ticker extends BlockEntityTickerDelayed<BlockEntitySqueezer> {
3✔
158
        @Override
159
        protected void update(Level level, BlockPos pos, BlockState blockState, BlockEntitySqueezer blockEntity) {
160
            super.update(level, pos, blockState, blockEntity);
6✔
161

162
            if(!blockEntity.getTank().isEmpty()) {
4!
163
                Direction.Axis axis = blockState.getValue(BlockSqueezer.AXIS);
×
164
                Arrays.stream(Direction.AxisDirection.values())
×
165
                        .map(axisDirection -> Direction.get(axisDirection, axis))
×
166
                        .forEach(side -> {
×
167
                            if (!blockEntity.getTank().isEmpty()) {
×
168
                                BlockEntityHelpers.getCapability(level, pos.relative(side), side.getOpposite(), net.neoforged.neoforge.capabilities.Capabilities.FluidHandler.BLOCK)
×
169
                                        .ifPresent(handler -> {
×
170
                                            FluidStack fluidStack = new FluidStack(blockEntity.getTank().getFluid().getFluid(),
×
171
                                                    Math.min(100, blockEntity.getTank().getFluidAmount()));
×
172
                                            if (handler.fill(fluidStack, IFluidHandler.FluidAction.SIMULATE) > 0) {
×
173
                                                int filled = handler.fill(fluidStack, IFluidHandler.FluidAction.EXECUTE);
×
174
                                                blockEntity.getTank().drain(filled, IFluidHandler.FluidAction.EXECUTE);
×
175
                                            }
176
                                        });
×
177
                            }
178
                        });
×
179
            } else {
×
180
                if (blockEntity.itemHeight == 7) {
4✔
181
                    Optional<RecipeHolder<RecipeSqueezer>> recipeOptional = blockEntity.getCurrentRecipe();
3✔
182
                    if (recipeOptional.isPresent()) {
3!
183
                        RecipeSqueezer recipe = recipeOptional.get().value();
6✔
184
                        ItemStack oldItem = blockEntity.getInventory().getItem(0);
5✔
185
                        blockEntity.getInventory().setItem(0, ItemStack.EMPTY);
5✔
186
                        for (RecipeSqueezer.IngredientChance itemStackChance : recipe.assemble(oldItem)) {
8!
187
                            if (itemStackChance.getChance() == 1.0F || itemStackChance.getChance() >= level.random.nextFloat()) {
×
188
                                ItemStack resultStack = itemStackChance.getIngredientFirst().copy();
×
189
                                for (Direction side : Direction.values()) {
×
190
                                    if (!resultStack.isEmpty() && side != Direction.UP) {
×
191
                                        IItemHandler itemHandler = BlockEntityHelpers.getCapability(level, pos.relative(side), side.getOpposite(), net.neoforged.neoforge.capabilities.Capabilities.ItemHandler.BLOCK).orElse(null);
×
192
                                        if (itemHandler != null) {
×
193
                                            resultStack = ItemHandlerHelper.insertItem(itemHandler, resultStack, false);
×
194
                                        }
195
                                    }
196
                                }
197
                                if (!resultStack.isEmpty()) {
×
198
                                    ItemStackHelpers.spawnItemStack(level, pos, resultStack);
×
199
                                }
200
                            }
201
                        }
×
202
                        if (recipe.getOutputFluid().isPresent()) {
4!
203
                            blockEntity.getTank().fill(recipe.getOutputFluid().get(), IFluidHandler.FluidAction.EXECUTE);
9✔
204
                        }
205
                    }
206
                }
207
            }
208
        }
1✔
209
    }
210
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc