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

CyclopsMC / IntegratedDynamics / 20210191346

14 Dec 2025 03:32PM UTC coverage: 19.514% (-33.5%) from 53.061%
20210191346

push

github

rubensworks
Remove deprecations

663 of 8728 branches covered (7.6%)

Branch coverage included in aggregate %.

6786 of 29445 relevant lines covered (23.05%)

1.09 hits per line

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

5.36
/src/main/java/org/cyclops/integrateddynamics/blockentity/BlockEntityMechanicalSqueezer.java
1
package org.cyclops.integrateddynamics.blockentity;
2

3
import com.google.common.collect.Lists;
4
import net.minecraft.core.BlockPos;
5
import net.minecraft.core.Direction;
6
import net.minecraft.core.NonNullList;
7
import net.minecraft.network.chat.Component;
8
import net.minecraft.world.MenuProvider;
9
import net.minecraft.world.entity.player.Inventory;
10
import net.minecraft.world.entity.player.Player;
11
import net.minecraft.world.inventory.AbstractContainerMenu;
12
import net.minecraft.world.item.ItemStack;
13
import net.minecraft.world.item.crafting.CraftingInput;
14
import net.minecraft.world.item.crafting.RecipeHolder;
15
import net.minecraft.world.item.crafting.RecipeType;
16
import net.minecraft.world.level.Level;
17
import net.minecraft.world.level.block.entity.BlockEntityType;
18
import net.minecraft.world.level.block.state.BlockState;
19
import net.minecraft.world.level.storage.ValueInput;
20
import net.minecraft.world.level.storage.ValueOutput;
21
import net.neoforged.neoforge.fluids.FluidStack;
22
import net.neoforged.neoforge.transfer.ResourceHandler;
23
import net.neoforged.neoforge.transfer.ResourceHandlerUtil;
24
import net.neoforged.neoforge.transfer.fluid.FluidResource;
25
import net.neoforged.neoforge.transfer.transaction.Transaction;
26
import org.cyclops.cyclopscore.datastructure.SingleCache;
27
import org.cyclops.cyclopscore.fluid.SingleUseTank;
28
import org.cyclops.cyclopscore.helper.IModHelpers;
29
import org.cyclops.cyclopscore.helper.IModHelpersNeoForge;
30
import org.cyclops.cyclopscore.persist.nbt.NBTPersist;
31
import org.cyclops.integrateddynamics.RegistryEntries;
32
import org.cyclops.integrateddynamics.block.BlockMechanicalSqueezer;
33
import org.cyclops.integrateddynamics.block.BlockMechanicalSqueezerConfig;
34
import org.cyclops.integrateddynamics.core.blockentity.BlockEntityMechanicalMachine;
35
import org.cyclops.integrateddynamics.core.recipe.handler.RecipeHandlerSqueezer;
36
import org.cyclops.integrateddynamics.core.recipe.type.RecipeMechanicalSqueezer;
37
import org.cyclops.integrateddynamics.core.recipe.type.RecipeSqueezer;
38
import org.cyclops.integrateddynamics.inventory.container.ContainerMechanicalSqueezer;
39

40
import javax.annotation.Nullable;
41
import java.util.Optional;
42
import java.util.function.Supplier;
43

44
/**
45
 * A part entity for the mechanical squeezer.
46
 * @author rubensworks
47
 */
48
public class BlockEntityMechanicalSqueezer extends BlockEntityMechanicalMachine<ItemStack, RecipeMechanicalSqueezer>
49
        implements MenuProvider {
50

51
    public static final int INVENTORY_SIZE = 5;
52

53
    private static final int SLOT_INPUT = 0;
54
    private static final int[] SLOTS_OUTPUT = {1, 2, 3, 4};
×
55
    private static final int TANK_SIZE = IModHelpersNeoForge.get().getFluidHelpers().getBucketVolume() * 100;
×
56

57
    @NBTPersist
×
58
    private boolean autoEjectFluids = false;
59

60
    private final SingleUseTank tank = new SingleUseTank(TANK_SIZE);
×
61

62
    public BlockEntityMechanicalSqueezer(BlockPos blockPos, BlockState blockState) {
63
        super(RegistryEntries.BLOCK_ENTITY_MECHANICAL_SQUEEZER.get(), blockPos, blockState, INVENTORY_SIZE);
×
64

65
        // Add tank update listeners
66
        tank.addDirtyMarkListener(this::onTankChanged);
×
67
    }
×
68

69
    public static class CapabilityRegistrar extends BlockEntityMechanicalMachine.CapabilityRegistrar<BlockEntityMechanicalSqueezer> {
70
        public CapabilityRegistrar(Supplier<BlockEntityType<? extends BlockEntityMechanicalSqueezer>> blockEntityType) {
71
            super(blockEntityType);
3✔
72
        }
1✔
73

74
        @Override
75
        public void populate() {
76
            super.populate();
2✔
77

78
            add(
4✔
79
                    net.neoforged.neoforge.capabilities.Capabilities.Fluid.BLOCK,
80
                    (blockEntity, direction) -> blockEntity.getTank()
×
81
            );
82
            add(
4✔
83
                    org.cyclops.commoncapabilities.api.capability.Capabilities.RecipeHandler.BLOCK,
84
                    (blockEntity, direction) -> new RecipeHandlerSqueezer<>(blockEntity::getLevel, RegistryEntries.RECIPETYPE_MECHANICAL_SQUEEZER.get())
×
85
            );
86
        }
1✔
87
    }
88

89
    @Override
90
    protected SingleCache.ICacheUpdater<ItemStack, Optional<RecipeHolder<RecipeMechanicalSqueezer>>> createCacheUpdater() {
91
        return new SingleCache.ICacheUpdater<ItemStack, Optional<RecipeHolder<RecipeMechanicalSqueezer>>>() {
×
92
            @Override
93
            public Optional<RecipeHolder<RecipeMechanicalSqueezer>> getNewValue(ItemStack key) {
94
                return IModHelpers.get().getCraftingHelpers().findRecipe(getRecipeRegistry(), CraftingInput.of(1, 1, Lists.newArrayList(key)), getLevel());
×
95
            }
96

97
            @Override
98
            public boolean isKeyEqual(ItemStack cacheKey, ItemStack newKey) {
99
                return ItemStack.matches(cacheKey, newKey);
×
100
            }
101
        };
102
    }
103

104
    @Override
105
    public int[] getInputSlots() {
106
        return new int[]{SLOT_INPUT};
×
107
    }
108

109
    @Override
110
    public int[] getOutputSlots() {
111
        return SLOTS_OUTPUT;
×
112
    }
113

114
    @Override
115
    public boolean wasWorking() {
116
        return getLevel().getBlockState(getBlockPos()).getValue(BlockMechanicalSqueezer.LIT);
×
117
    }
118

119
    @Override
120
    public void setWorking(boolean working) {
121
        getLevel().setBlockAndUpdate(getBlockPos(), getLevel().getBlockState(getBlockPos())
×
122
                .setValue(BlockMechanicalSqueezer.LIT, working));
×
123
    }
×
124

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

129
    @Override
130
    public void read(ValueInput input) {
131
        super.read(input);
×
132
        getTank().deserialize(input, "tank");
×
133
    }
×
134

135
    @Override
136
    public void saveAdditional(ValueOutput output) {
137
        getTank().serialize(output, "tank");
×
138
        super.saveAdditional(output);
×
139
    }
×
140

141
    @Override
142
    protected RecipeType<RecipeMechanicalSqueezer> getRecipeRegistry() {
143
        return RegistryEntries.RECIPETYPE_MECHANICAL_SQUEEZER.get();
×
144
    }
145

146
    @Override
147
    protected ItemStack getCurrentRecipeCacheKey() {
148
        return getInventory().getItem(SLOT_INPUT).copy();
×
149
    }
150

151
    @Override
152
    public int getRecipeDuration(RecipeHolder<RecipeMechanicalSqueezer> recipe) {
153
        return recipe.value().getDuration();
×
154
    }
155

156
    @Override
157
    protected boolean finalizeRecipe(RecipeMechanicalSqueezer recipe, boolean simulate) {
158
        // Output items
159
        NonNullList<ItemStack> outputStacks = NonNullList.create();
×
160
        for (RecipeSqueezer.IngredientChance itemStackChance : recipe.getOutputItems()) {
×
161
            ItemStack outputStack = itemStackChance.getIngredientFirst().copy();
×
162
            if (!outputStack.isEmpty() && (simulate || itemStackChance.getChance() == 1.0F
×
163
                    || itemStackChance.getChance() >= getLevel().random.nextFloat())) {
×
164
                IModHelpers.get().getInventoryHelpers().addStackToList(outputStacks, outputStack);
×
165
            }
166
        }
×
167
        if (!IModHelpers.get().getInventoryHelpers().addToInventory(getInventory(), SLOTS_OUTPUT, outputStacks, simulate).isEmpty()) {
×
168
            return false;
×
169
        }
170

171
        // Output fluid
172
        Optional<FluidStack> outputFluid = recipe.getOutputFluid();
×
173
        if (outputFluid.isPresent()) {
×
174
            try (var tx = Transaction.openRoot()) {
×
175
                int inserted = getTank().insert(FluidResource.of(outputFluid.get()), outputFluid.get().getAmount(), tx);
×
176
                if (!simulate) {
×
177
                    tx.commit();
×
178
                }
179
                if (inserted != outputFluid.get().getAmount()) {
×
180
                    return false;
×
181
                }
182
            }
×
183
        }
184

185
        // Only consume items if we are not simulating
186
        if (!simulate) {
×
187
            getInventory().removeItem(SLOT_INPUT, 1);
×
188
        }
189

190
        return true;
×
191
    }
192

193
    @Override
194
    public int getEnergyConsumptionRate() {
195
        return BlockMechanicalSqueezerConfig.consumptionRate;
×
196
    }
197

198
    @Override
199
    public int getMaxEnergyStored() {
200
        return BlockMechanicalSqueezerConfig.capacity;
×
201
    }
202

203
    public boolean isAutoEjectFluids() {
204
        return autoEjectFluids;
×
205
    }
206

207
    public void setAutoEjectFluids(boolean autoEjectFluids) {
208
        this.autoEjectFluids = autoEjectFluids;
×
209
        sendUpdate();
×
210
    }
×
211

212
    @Nullable
213
    @Override
214
    public AbstractContainerMenu createMenu(int id, Inventory playerInventory, Player playerEntity) {
215
        return new ContainerMechanicalSqueezer(id, playerInventory, this.getInventory(), Optional.of(this));
×
216
    }
217

218
    @Override
219
    public Component getDisplayName() {
220
        return Component.translatable("block.integrateddynamics.mechanical_squeezer");
×
221
    }
222

223
    public static class Ticker extends BlockEntityMechanicalMachine.Ticker<ItemStack, RecipeMechanicalSqueezer, BlockEntityMechanicalSqueezer> {
×
224
        @Override
225
        protected void update(Level level, BlockPos pos, BlockState blockState, BlockEntityMechanicalSqueezer blockEntity) {
226
            super.update(level, pos, blockState, blockEntity);
×
227

228
            // Auto-eject fluid
229
            if (blockEntity.isAutoEjectFluids() && !blockEntity.getTank().isEmpty()) {
×
230
                for (Direction side : Direction.values()) {
×
231
                    ResourceHandler<FluidResource> handler = IModHelpersNeoForge.get().getCapabilityHelpers().getCapability(level, pos.relative(side),
×
232
                            side.getOpposite(), net.neoforged.neoforge.capabilities.Capabilities.Fluid.BLOCK).orElse(null);
×
233
                    if(handler != null) {
×
234
                        FluidStack fluidStack = blockEntity.getTank().getFluid().copy();
×
235
                        fluidStack.setAmount(Math.min(BlockMechanicalSqueezerConfig.autoEjectFluidRate, fluidStack.getAmount()));
×
236
                        try (var tx = Transaction.openRoot()) {
×
237
                            int moved = ResourceHandlerUtil.move(blockEntity.getTank(), handler, null, BlockMechanicalSqueezerConfig.autoEjectFluidRate, tx);
×
238
                            tx.commit();
×
239
                            if (moved > 0) {
×
240
                                break;
241
                            }
242
                        }
×
243
                    }
244
                }
245
            }
246
        }
×
247
    }
248
}
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