• 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.66
/src/main/java/org/cyclops/integrateddynamics/blockentity/BlockEntityMechanicalDryingBasin.java
1
package org.cyclops.integrateddynamics.blockentity;
2

3
import net.minecraft.core.BlockPos;
4
import net.minecraft.core.Direction;
5
import net.minecraft.core.NonNullList;
6
import net.minecraft.network.chat.Component;
7
import net.minecraft.world.MenuProvider;
8
import net.minecraft.world.entity.player.Inventory;
9
import net.minecraft.world.entity.player.Player;
10
import net.minecraft.world.inventory.AbstractContainerMenu;
11
import net.minecraft.world.item.ItemStack;
12
import net.minecraft.world.item.crafting.RecipeHolder;
13
import net.minecraft.world.item.crafting.RecipeType;
14
import net.minecraft.world.level.block.entity.BlockEntityType;
15
import net.minecraft.world.level.block.state.BlockState;
16
import net.minecraft.world.level.storage.ValueInput;
17
import net.minecraft.world.level.storage.ValueOutput;
18
import net.neoforged.neoforge.fluids.FluidStack;
19
import net.neoforged.neoforge.transfer.fluid.FluidResource;
20
import net.neoforged.neoforge.transfer.transaction.Transaction;
21
import org.apache.commons.lang3.tuple.Pair;
22
import org.cyclops.cyclopscore.datastructure.SingleCache;
23
import org.cyclops.cyclopscore.fluid.SingleUseTank;
24
import org.cyclops.cyclopscore.helper.IModHelpers;
25
import org.cyclops.cyclopscore.helper.IModHelpersNeoForge;
26
import org.cyclops.cyclopscore.recipe.type.IInventoryFluid;
27
import org.cyclops.cyclopscore.recipe.type.InventoryFluid;
28
import org.cyclops.integrateddynamics.RegistryEntries;
29
import org.cyclops.integrateddynamics.block.BlockMechanicalDryingBasin;
30
import org.cyclops.integrateddynamics.block.BlockMechanicalDryingBasinConfig;
31
import org.cyclops.integrateddynamics.core.blockentity.BlockEntityMechanicalMachine;
32
import org.cyclops.integrateddynamics.core.recipe.handler.RecipeHandlerDryingBasin;
33
import org.cyclops.integrateddynamics.core.recipe.type.RecipeMechanicalDryingBasin;
34
import org.cyclops.integrateddynamics.inventory.container.ContainerMechanicalDryingBasin;
35

36
import javax.annotation.Nullable;
37
import java.util.Optional;
38
import java.util.function.Supplier;
39

40
/**
41
 * A part entity for the mechanical drying basin.
42
 * @author rubensworks
43
 */
44
public class BlockEntityMechanicalDryingBasin extends BlockEntityMechanicalMachine<Pair<ItemStack, FluidStack>, RecipeMechanicalDryingBasin>
45
        implements MenuProvider {
46

47
    public static final int INVENTORY_SIZE = 5;
48

49
    private static final int SLOT_INPUT = 0;
50
    private static final int[] SLOTS_OUTPUT = {1, 2, 3, 4};
×
51

52
    private final SingleUseTank tankIn = new SingleUseTank(IModHelpersNeoForge.get().getFluidHelpers().getBucketVolume() * 10);
×
53
    private final SingleUseTank tankOut = new SingleUseTank(IModHelpersNeoForge.get().getFluidHelpers().getBucketVolume() * 100);
×
54

55
    public BlockEntityMechanicalDryingBasin(BlockPos blockPos, BlockState blockState) {
56
        super(RegistryEntries.BLOCK_ENTITY_MECHANICAL_DRYING_BASIN.get(), blockPos, blockState, INVENTORY_SIZE);
×
57

58
        // Add tank update listeners
59
        tankIn.addDirtyMarkListener(this::onTankChanged);
×
60
        tankOut.addDirtyMarkListener(this::onTankChanged);
×
61
    }
×
62

63
    public static class CapabilityRegistrar extends BlockEntityMechanicalMachine.CapabilityRegistrar<BlockEntityMechanicalDryingBasin> {
64
        public CapabilityRegistrar(Supplier<BlockEntityType<? extends BlockEntityMechanicalDryingBasin>> blockEntityType) {
65
            super(blockEntityType);
3✔
66
        }
1✔
67

68
        @Override
69
        public void populate() {
70
            super.populate();
2✔
71

72
            add(
4✔
73
                    net.neoforged.neoforge.capabilities.Capabilities.Fluid.BLOCK,
74
                    (blockEntity, direction) -> direction == Direction.DOWN ? blockEntity.getTankOutput() : blockEntity.getTankInput()
×
75
            );
76
            add(
4✔
77
                    org.cyclops.commoncapabilities.api.capability.Capabilities.RecipeHandler.BLOCK,
78
                    (blockEntity, direction) -> new RecipeHandlerDryingBasin<>(blockEntity::getLevel, RegistryEntries.RECIPETYPE_MECHANICAL_DRYING_BASIN.get())
×
79
            );
80
        }
1✔
81
    }
82

83
    @Override
84
    protected SingleCache.ICacheUpdater<Pair<ItemStack, FluidStack>, Optional<RecipeHolder<RecipeMechanicalDryingBasin>>> createCacheUpdater() {
85
        return new SingleCache.ICacheUpdater<Pair<ItemStack, FluidStack>, Optional<RecipeHolder<RecipeMechanicalDryingBasin>>>() {
×
86
            @Override
87
            public Optional<RecipeHolder<RecipeMechanicalDryingBasin>> getNewValue(Pair<ItemStack, FluidStack> key) {
88
                IInventoryFluid recipeInput = new InventoryFluid(
×
89
                        NonNullList.of(ItemStack.EMPTY, key.getLeft()),
×
90
                        NonNullList.of(FluidStack.EMPTY, key.getRight()));
×
91
                return IModHelpers.get().getCraftingHelpers().findRecipe(getRecipeRegistry(), recipeInput, getLevel());
×
92
            }
93

94
            @Override
95
            public boolean isKeyEqual(Pair<ItemStack, FluidStack> cacheKey, Pair<ItemStack, FluidStack> newKey) {
96
                return cacheKey == null || newKey == null ||
×
97
                        (ItemStack.matches(cacheKey.getLeft(), newKey.getLeft()) &&
×
98
                                FluidStack.matches(cacheKey.getRight(), newKey.getRight()));
×
99
            }
100
        };
101
    }
102

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

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

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

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

124
    public SingleUseTank getTankInput() {
125
        return tankIn;
×
126
    }
127

128
    public SingleUseTank getTankOutput() {
129
        return tankOut;
×
130
    }
131

132
    @Override
133
    public void read(ValueInput input) {
134
        super.read(input);
×
135
        getTankInput().deserialize(input, "tankIn");
×
136
        getTankOutput().deserialize(input, "tankOut");
×
137
    }
×
138

139
    @Override
140
    public void saveAdditional(ValueOutput output) {
141
        getTankInput().serialize(output, "tankIn");
×
142
        getTankOutput().serialize(output, "tankOut");
×
143
        super.saveAdditional(output);
×
144
    }
×
145

146
    @Override
147
    protected RecipeType<RecipeMechanicalDryingBasin> getRecipeRegistry() {
148
        return RegistryEntries.RECIPETYPE_MECHANICAL_DRYING_BASIN.get();
×
149
    }
150

151
    @Override
152
    protected Pair<ItemStack, FluidStack> getCurrentRecipeCacheKey() {
153
        return Pair.of(getInventory().getItem(SLOT_INPUT).copy(), IModHelpersNeoForge.get().getFluidHelpers().copy(getTankInput().getFluid()));
×
154
    }
155

156
    @Override
157
    public int getRecipeDuration(RecipeHolder<RecipeMechanicalDryingBasin> recipe) {
158
        return recipe.value().getDuration();
×
159
    }
160

161
    @Override
162
    protected boolean finalizeRecipe(RecipeMechanicalDryingBasin recipe, boolean simulate) {
163
        // Output items
164
        ItemStack outputStack = recipe.getOutputItemFirst().orElse(ItemStack.EMPTY).copy();
×
165
        if (!outputStack.isEmpty()) {
×
166
            if (!IModHelpers.get().getInventoryHelpers().addToInventory(getInventory(), SLOTS_OUTPUT, NonNullList.withSize(1, outputStack), simulate).isEmpty()) {
×
167
                return false;
×
168
            }
169
        }
170

171
        // Output fluid
172
        Optional<FluidStack> outputFluid = recipe.getOutputFluid();
×
173
        if (outputFluid.isPresent()) {
×
174
            try (var tx = Transaction.openRoot()) {
×
175
                int inserted = getTankOutput().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
            if (!recipe.getInputIngredient().isEmpty()) {
×
188
                getInventory().removeItem(SLOT_INPUT, 1);
×
189
            }
190
        }
191

192
        // Consume fluid
193
        Optional<FluidStack> inputFluid = recipe.getInputFluid();
×
194
        if (inputFluid.isPresent()) {
×
195
            try (var tx = Transaction.openRoot()) {
×
196
                int extracted = getTankInput().extract(FluidResource.of(inputFluid.get()), inputFluid.get().getAmount(), tx);
×
197
                if (!simulate) {
×
198
                    tx.commit();
×
199
                }
200
                if (extracted != inputFluid.get().getAmount()) {
×
201
                    return false;
×
202
                }
203
            }
×
204
        }
205

206
        return true;
×
207
    }
208

209
    @Override
210
    public int getEnergyConsumptionRate() {
211
        return BlockMechanicalDryingBasinConfig.consumptionRate;
×
212
    }
213

214
    @Override
215
    public int getMaxEnergyStored() {
216
        return BlockMechanicalDryingBasinConfig.capacity;
×
217
    }
218

219
    @Nullable
220
    @Override
221
    public AbstractContainerMenu createMenu(int id, Inventory playerInventory, Player playerEntity) {
222
        return new ContainerMechanicalDryingBasin(id, playerInventory, this.getInventory(), Optional.of(this));
×
223
    }
224

225
    @Override
226
    public Component getDisplayName() {
227
        return Component.translatable("block.integrateddynamics.mechanical_drying_basin");
×
228
    }
229
}
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