From ed14e696c65b0b08eb5c93aa88884cba641f1c08 Mon Sep 17 00:00:00 2001 From: M-W-K Date: Sat, 6 Jul 2024 13:19:20 -0600 Subject: [PATCH 1/4] Improve DT hatch logic --- .../impl/DistillationTowerLogicHandler.java | 184 ++++++++++++++++++ .../MetaTileEntityDistillationTower.java | 153 +++------------ 2 files changed, 212 insertions(+), 125 deletions(-) create mode 100644 src/main/java/gregtech/api/capability/impl/DistillationTowerLogicHandler.java diff --git a/src/main/java/gregtech/api/capability/impl/DistillationTowerLogicHandler.java b/src/main/java/gregtech/api/capability/impl/DistillationTowerLogicHandler.java new file mode 100644 index 00000000000..a3b46515457 --- /dev/null +++ b/src/main/java/gregtech/api/capability/impl/DistillationTowerLogicHandler.java @@ -0,0 +1,184 @@ +package gregtech.api.capability.impl; + +import gregtech.api.capability.IMultipleTankHandler; +import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; +import gregtech.api.metatileentity.multiblock.IMultiblockPart; +import gregtech.api.metatileentity.multiblock.MultiblockAbility; +import gregtech.api.pattern.BlockPattern; +import gregtech.api.recipes.Recipe; +import gregtech.api.util.GTLog; +import gregtech.api.util.GTTransferUtils; +import gregtech.common.metatileentities.multi.multiblockpart.MetaTileEntityMultiblockPart; + +import net.minecraft.util.math.BlockPos; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.IFluidTank; +import net.minecraftforge.fluids.capability.IFluidHandler; +import net.minecraftforge.fluids.capability.IFluidTankProperties; +import net.minecraftforge.items.IItemHandlerModifiable; + +import com.cleanroommc.modularui.utils.FluidTankHandler; +import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import org.jetbrains.annotations.NotNull; + +import java.util.List; +import java.util.stream.Collectors; + +public class DistillationTowerLogicHandler { + + protected final AbstractRecipeLogic workable; + protected final IDistillationTower tower; + + public int layerCount; + public List orderedFluidOutputs; + + public DistillationTowerLogicHandler(IDistillationTower tower, AbstractRecipeLogic workable) { + this.tower = tower; + this.workable = workable; + } + + protected boolean applyFluidToOutputs(List fluids, boolean doFill) { + boolean valid = true; + for (int i = 0; i < fluids.size(); i++) { + IFluidHandler handler = orderedFluidOutputs.get(i); + int accepted = handler.fill(fluids.get(i), doFill); + if (accepted != fluids.get(i).amount) valid = false; + if (!doFill && !valid) break; + } + return valid; + } + + public void outputRecipeOutputs() { + GTTransferUtils.addItemsToItemHandler(workable.getOutputInventory(), false, workable.itemOutputs); + this.applyFluidToOutputs(workable.fluidOutputs, true); + } + + public boolean setupAndConsumeRecipeInputs(@NotNull Recipe recipe, + @NotNull IItemHandlerModifiable importInventory, + @NotNull IMultipleTankHandler importFluids) { + workable.overclockResults = workable.calculateOverclock(recipe); + + workable.modifyOverclockPost(workable.overclockResults, recipe.getRecipePropertyStorage()); + + if (!workable.hasEnoughPower(workable.overclockResults)) { + return false; + } + + IItemHandlerModifiable exportInventory = workable.getOutputInventory(); + + // We have already trimmed outputs and chanced outputs at this time + // Attempt to merge all outputs + chanced outputs into the output bus, to prevent voiding chanced outputs + if (!workable.getMetaTileEntity().canVoidRecipeItemOutputs() && + !GTTransferUtils.addItemsToItemHandler(exportInventory, true, recipe.getAllItemOutputs())) { + workable.isOutputsFull = true; + return false; + } + + // Perform layerwise fluid checks + if (!workable.getMetaTileEntity().canVoidRecipeFluidOutputs() && + !this.applyFluidToOutputs(recipe.getAllFluidOutputs(), false)) { + workable.isOutputsFull = true; + + return false; + } + + workable.isOutputsFull = false; + if (recipe.matches(true, importInventory, importFluids)) { + workable.getMetaTileEntity().addNotifiedInput(importInventory); + return true; + } + return false; + } + + /** + * Needs to be overriden for multiblocks that have different assemblies than the standard distillation tower. + * + * @param structurePattern the structure pattern + */ + public void determineLayerCount(@NotNull BlockPattern structurePattern) { + this.layerCount = structurePattern.formedRepetitionCount[1] + 1; + } + + /** + * Needs to be overriden for multiblocks that have different assemblies than the standard distillation tower. + */ + public void determineOrderedFluidOutputs() { + // noinspection SimplifyStreamApiCallChains + List fluidExportParts = tower.getMultiblockParts().stream() + .filter(iMultiblockPart -> iMultiblockPart instanceof IMultiblockAbilityPartabilityPart && + abilityPart.getAbility() == MultiblockAbility.EXPORT_FLUIDS && + abilityPart instanceof MetaTileEntityMultiblockPart) + .map(iMultiblockPart -> (MetaTileEntityMultiblockPart) iMultiblockPart) + .collect(Collectors.toList()); + // the fluidExportParts should come sorted in smallest Y first, largest Y last. + List orderedHandlerList = new ObjectArrayList<>(); + int firstY = tower.getPos().getY() + 1; + int exportIndex = 0; + for (int y = firstY; y < firstY + this.layerCount; y++) { + if (fluidExportParts.size() <= exportIndex) { + orderedHandlerList.add(null); + continue; + } + MetaTileEntityMultiblockPart part = fluidExportParts.get(exportIndex); + if (part.getPos().getY() == y) { + List hatchTanks = new ObjectArrayList<>(); + // noinspection unchecked + ((IMultiblockAbilityPart) part).registerAbilities(hatchTanks); + if (hatchTanks.size() == 1) + orderedHandlerList.add(FluidTankHandler.getTankFluidHandler(hatchTanks.get(0))); + else orderedHandlerList.add(new FluidTankList(false, hatchTanks)); + exportIndex++; + } else if (part.getPos().getY() > y) { + orderedHandlerList.add(FakeFluidHandler.INSTANCE); + } else { + GTLog.logger.error("The Distillation Tower at " + tower.getPos() + + " had a fluid export hatch with an unexpected Y position."); + tower.invalidateStructure(); + this.orderedFluidOutputs = new ObjectArrayList<>(); + } + } + this.orderedFluidOutputs = orderedHandlerList; + } + + public void invalidate() { + this.layerCount = 0; + this.orderedFluidOutputs = null; + } + + public interface IDistillationTower { + + List getMultiblockParts(); + + BlockPos getPos(); + + void invalidateStructure(); + } + + // an endless void devouring any fluid sent to it + protected static class FakeFluidHandler implements IFluidHandler { + + protected static final FakeFluidHandler INSTANCE = new FakeFluidHandler(); + + private static final IFluidTankProperties[] ARRAY = new IFluidTankProperties[0]; + + @Override + public IFluidTankProperties[] getTankProperties() { + return ARRAY; + } + + @Override + public int fill(FluidStack resource, boolean doFill) { + return resource.amount; + } + + @Override + public FluidStack drain(FluidStack resource, boolean doDrain) { + return null; + } + + @Override + public FluidStack drain(int maxDrain, boolean doDrain) { + return null; + } + } +} diff --git a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityDistillationTower.java b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityDistillationTower.java index 41e1da2ea88..3dec51d880d 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityDistillationTower.java +++ b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityDistillationTower.java @@ -1,11 +1,10 @@ package gregtech.common.metatileentities.multi.electric; import gregtech.api.capability.IMultipleTankHandler; -import gregtech.api.capability.impl.FluidTankList; +import gregtech.api.capability.impl.DistillationTowerLogicHandler; import gregtech.api.capability.impl.MultiblockRecipeLogic; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; -import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; import gregtech.api.metatileentity.multiblock.IMultiblockPart; import gregtech.api.metatileentity.multiblock.MultiblockAbility; import gregtech.api.metatileentity.multiblock.RecipeMapMultiblockController; @@ -14,8 +13,6 @@ import gregtech.api.pattern.PatternMatchContext; import gregtech.api.recipes.Recipe; import gregtech.api.recipes.RecipeMaps; -import gregtech.api.util.GTLog; -import gregtech.api.util.GTTransferUtils; import gregtech.api.util.GTUtility; import gregtech.api.util.RelativeDirection; import gregtech.api.util.TextComponentUtil; @@ -23,7 +20,6 @@ import gregtech.client.renderer.texture.Textures; import gregtech.common.blocks.BlockMetalCasing.MetalCasingType; import gregtech.common.blocks.MetaBlocks; -import gregtech.common.metatileentities.multi.multiblockpart.MetaTileEntityMultiblockPart; import gregtech.core.sound.GTSoundEvents; import net.minecraft.block.state.IBlockState; @@ -33,46 +29,48 @@ import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.TextFormatting; import net.minecraftforge.fluids.FluidStack; -import net.minecraftforge.fluids.IFluidTank; -import net.minecraftforge.fluids.capability.IFluidHandler; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; import net.minecraftforge.items.IItemHandlerModifiable; -import com.cleanroommc.modularui.utils.FluidTankHandler; -import it.unimi.dsi.fastutil.objects.ObjectArrayList; import org.jetbrains.annotations.NotNull; import java.util.List; import java.util.function.Function; -import java.util.stream.Collectors; import static gregtech.api.util.RelativeDirection.*; -public class MetaTileEntityDistillationTower extends RecipeMapMultiblockController { +public class MetaTileEntityDistillationTower extends RecipeMapMultiblockController + implements DistillationTowerLogicHandler.IDistillationTower { - private final boolean useAdvHatchLogic; - - protected int layerCount; - protected List orderedFluidOutputs; + protected DistillationTowerLogicHandler handler; + @SuppressWarnings("unused") // backwards compatibility public MetaTileEntityDistillationTower(ResourceLocation metaTileEntityId) { this(metaTileEntityId, false); } public MetaTileEntityDistillationTower(ResourceLocation metaTileEntityId, boolean useAdvHatchLogic) { super(metaTileEntityId, RecipeMaps.DISTILLATION_RECIPES); - this.useAdvHatchLogic = useAdvHatchLogic; if (useAdvHatchLogic) { - this.recipeMapWorkable = new DistillationTowerRecipeLogic(this); - } + DistillationTowerRecipeLogic logic = new DistillationTowerRecipeLogic(this); + this.recipeMapWorkable = logic; + this.handler = new DistillationTowerLogicHandler(this, logic); + } else this.handler = null; } @Override public MetaTileEntity createMetaTileEntity(IGregTechTileEntity tileEntity) { - return new MetaTileEntityDistillationTower(metaTileEntityId, this.useAdvHatchLogic); + return new MetaTileEntityDistillationTower(metaTileEntityId, this.handler != null); } + /** + * Used if MultiblockPart Abilities need to be sorted a certain way, like + * Distillation Tower and Assembly Line.
+ *
+ * There will be consequences if this is changed. Make sure to set the logic handler to one with + * a properly overriden {@link DistillationTowerLogicHandler#determineOrderedFluidOutputs()} + */ @Override protected Function multiblockPartSorter() { return RelativeDirection.UP.getSorter(getFrontFacing(), getUpwardsFacing(), isFlipped()); @@ -80,7 +78,9 @@ protected Function multiblockPartSorter() { /** * Whether this multi can be rotated or face upwards.
- * There will be consequences if this returns true. Go override {@link #determineOrderedFluidOutputs()} + *
+ * There will be consequences if this returns true. Make sure to set the logic handler to one with + * a properly overriden {@link DistillationTowerLogicHandler#determineOrderedFluidOutputs()} */ @Override public boolean allowsExtendedFacing() { @@ -106,68 +106,15 @@ protected void addDisplayText(List textList) { @Override protected void formStructure(PatternMatchContext context) { super.formStructure(context); - if (!useAdvHatchLogic || this.structurePattern == null) return; - this.layerCount = determineLayerCount(this.structurePattern); - this.orderedFluidOutputs = determineOrderedFluidOutputs(); - } - - /** - * Needs to be overriden for multiblocks that have different assemblies than the standard distillation tower. - * - * @param structurePattern the structure pattern - * @return the number of layers that could hold output hatches - */ - protected int determineLayerCount(@NotNull BlockPattern structurePattern) { - return structurePattern.formedRepetitionCount[1] + 1; - } - - /** - * Needs to be overriden for multiblocks that have different assemblies than the standard distillation tower. - * - * @return the fluid hatches of the multiblock, in order, with null entries for layers that do not have hatches. - */ - protected List determineOrderedFluidOutputs() { - List fluidExportParts = this.getMultiblockParts().stream() - .filter(iMultiblockPart -> iMultiblockPart instanceof IMultiblockAbilityPartabilityPart && - abilityPart.getAbility() == MultiblockAbility.EXPORT_FLUIDS && - abilityPart instanceof MetaTileEntityMultiblockPart) - .map(iMultiblockPart -> (MetaTileEntityMultiblockPart) iMultiblockPart) - .collect(Collectors.toList()); - // the fluidExportParts should come sorted in smallest Y first, largest Y last. - List orderedHandlerList = new ObjectArrayList<>(); - int firstY = this.getPos().getY() + 1; - int exportIndex = 0; - for (int y = firstY; y < firstY + this.layerCount; y++) { - if (fluidExportParts.size() <= exportIndex) { - orderedHandlerList.add(null); - continue; - } - MetaTileEntityMultiblockPart part = fluidExportParts.get(exportIndex); - if (part.getPos().getY() == y) { - List hatchTanks = new ObjectArrayList<>(); - // noinspection unchecked - ((IMultiblockAbilityPart) part).registerAbilities(hatchTanks); - if (hatchTanks.size() == 1) - orderedHandlerList.add(FluidTankHandler.getTankFluidHandler(hatchTanks.get(0))); - else orderedHandlerList.add(new FluidTankList(false, hatchTanks)); - exportIndex++; - } else if (part.getPos().getY() > y) { - orderedHandlerList.add(null); - } else { - GTLog.logger.error("The Distillation Tower at " + this.getPos() + - " had a fluid export hatch with an unexpected Y position."); - this.invalidateStructure(); - return new ObjectArrayList<>(); - } - } - return orderedHandlerList; + if (this.handler == null || this.structurePattern == null) return; + handler.determineLayerCount(this.structurePattern); + handler.determineOrderedFluidOutputs(); } @Override public void invalidateStructure() { super.invalidateStructure(); - this.layerCount = 0; - this.orderedFluidOutputs = null; + if (this.handler != null) handler.invalidate(); } @Override @@ -217,7 +164,8 @@ protected ICubeRenderer getFrontOverlay() { @Override public int getFluidOutputLimit() { - return this.layerCount; + if (this.handler != null) return this.handler.layerCount; + else return super.getFluidOutputLimit(); } protected class DistillationTowerRecipeLogic extends MultiblockRecipeLogic { @@ -226,61 +174,16 @@ public DistillationTowerRecipeLogic(MetaTileEntityDistillationTower tileEntity) super(tileEntity); } - protected boolean applyFluidToOutputs(List fluids, boolean doFill) { - boolean valid = true; - for (int i = 0; i < fluids.size(); i++) { - IFluidHandler handler = orderedFluidOutputs.get(i); - // void if no hatch is found on that fluid's layer - // this is considered trimming and thus ignores canVoid - if (handler == null) continue; - int accepted = handler.fill(fluids.get(i), doFill); - if (accepted != fluids.get(i).amount) valid = false; - if (!doFill && !valid) break; - } - return valid; - } - @Override protected void outputRecipeOutputs() { - GTTransferUtils.addItemsToItemHandler(getOutputInventory(), false, itemOutputs); - this.applyFluidToOutputs(fluidOutputs, true); + handler.outputRecipeOutputs(); } @Override protected boolean setupAndConsumeRecipeInputs(@NotNull Recipe recipe, @NotNull IItemHandlerModifiable importInventory, @NotNull IMultipleTankHandler importFluids) { - this.overclockResults = calculateOverclock(recipe); - - modifyOverclockPost(overclockResults, recipe.getRecipePropertyStorage()); - - if (!hasEnoughPower(overclockResults)) { - return false; - } - - IItemHandlerModifiable exportInventory = getOutputInventory(); - - // We have already trimmed outputs and chanced outputs at this time - // Attempt to merge all outputs + chanced outputs into the output bus, to prevent voiding chanced outputs - if (!metaTileEntity.canVoidRecipeItemOutputs() && - !GTTransferUtils.addItemsToItemHandler(exportInventory, true, recipe.getAllItemOutputs())) { - this.isOutputsFull = true; - return false; - } - - // Perform layerwise fluid checks - if (!metaTileEntity.canVoidRecipeFluidOutputs() && - !this.applyFluidToOutputs(recipe.getAllFluidOutputs(), false)) { - this.isOutputsFull = true; - return false; - } - - this.isOutputsFull = false; - if (recipe.matches(true, importInventory, importFluids)) { - this.metaTileEntity.addNotifiedInput(importInventory); - return true; - } - return false; + return handler.setupAndConsumeRecipeInputs(recipe, importInventory, importFluids); } } } From e1c54752eaabead75204e42f8f45bd0cd6960f6d Mon Sep 17 00:00:00 2001 From: M-W-K Date: Sat, 6 Jul 2024 14:11:31 -0600 Subject: [PATCH 2/4] Fix an oversight --- .../impl/DistillationTowerLogicHandler.java | 48 ++++++++++++++++--- .../MetaTileEntityDistillationTower.java | 7 ++- 2 files changed, 47 insertions(+), 8 deletions(-) diff --git a/src/main/java/gregtech/api/capability/impl/DistillationTowerLogicHandler.java b/src/main/java/gregtech/api/capability/impl/DistillationTowerLogicHandler.java index a3b46515457..96a22e5e314 100644 --- a/src/main/java/gregtech/api/capability/impl/DistillationTowerLogicHandler.java +++ b/src/main/java/gregtech/api/capability/impl/DistillationTowerLogicHandler.java @@ -12,7 +12,9 @@ import net.minecraft.util.math.BlockPos; import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.FluidTankInfo; import net.minecraftforge.fluids.IFluidTank; +import net.minecraftforge.fluids.capability.FluidTankProperties; import net.minecraftforge.fluids.capability.IFluidHandler; import net.minecraftforge.fluids.capability.IFluidTankProperties; import net.minecraftforge.items.IItemHandlerModifiable; @@ -31,6 +33,7 @@ public class DistillationTowerLogicHandler { public int layerCount; public List orderedFluidOutputs; + public IMultipleTankHandler fluidTanks; public DistillationTowerLogicHandler(IDistillationTower tower, AbstractRecipeLogic workable) { this.tower = tower; @@ -112,11 +115,13 @@ public void determineOrderedFluidOutputs() { .collect(Collectors.toList()); // the fluidExportParts should come sorted in smallest Y first, largest Y last. List orderedHandlerList = new ObjectArrayList<>(); + List tankList = new ObjectArrayList<>(); int firstY = tower.getPos().getY() + 1; int exportIndex = 0; for (int y = firstY; y < firstY + this.layerCount; y++) { if (fluidExportParts.size() <= exportIndex) { - orderedHandlerList.add(null); + orderedHandlerList.add(FakeTank.INSTANCE); + tankList.add(FakeTank.INSTANCE); continue; } MetaTileEntityMultiblockPart part = fluidExportParts.get(exportIndex); @@ -127,17 +132,21 @@ public void determineOrderedFluidOutputs() { if (hatchTanks.size() == 1) orderedHandlerList.add(FluidTankHandler.getTankFluidHandler(hatchTanks.get(0))); else orderedHandlerList.add(new FluidTankList(false, hatchTanks)); + tankList.addAll(hatchTanks); exportIndex++; } else if (part.getPos().getY() > y) { - orderedHandlerList.add(FakeFluidHandler.INSTANCE); + orderedHandlerList.add(FakeTank.INSTANCE); + tankList.add(FakeTank.INSTANCE); } else { GTLog.logger.error("The Distillation Tower at " + tower.getPos() + " had a fluid export hatch with an unexpected Y position."); tower.invalidateStructure(); this.orderedFluidOutputs = new ObjectArrayList<>(); + this.fluidTanks = new FluidTankList(false); } } this.orderedFluidOutputs = orderedHandlerList; + this.fluidTanks = new FluidTankList(tower.allowSameFluidFillForOutputs(), tankList); } public void invalidate() { @@ -152,18 +161,43 @@ public interface IDistillationTower { BlockPos getPos(); void invalidateStructure(); + + boolean allowSameFluidFillForOutputs(); } // an endless void devouring any fluid sent to it - protected static class FakeFluidHandler implements IFluidHandler { - - protected static final FakeFluidHandler INSTANCE = new FakeFluidHandler(); + protected static class FakeTank implements IFluidHandler, IFluidTank { - private static final IFluidTankProperties[] ARRAY = new IFluidTankProperties[0]; + protected static final FakeTank INSTANCE = new FakeTank(); + public static final FluidTankInfo FAKE_TANK_INFO = new FluidTankInfo(null, Integer.MAX_VALUE); + public static final IFluidTankProperties FAKE_TANK_PROPERTIES = new FluidTankProperties(null, Integer.MAX_VALUE, + true, false); + public static final IFluidTankProperties[] FAKE_TANK_PROPERTIES_ARRAY = new IFluidTankProperties[] { + FAKE_TANK_PROPERTIES }; @Override public IFluidTankProperties[] getTankProperties() { - return ARRAY; + return FAKE_TANK_PROPERTIES_ARRAY; + } + + @Override + public FluidStack getFluid() { + return null; + } + + @Override + public int getFluidAmount() { + return 0; + } + + @Override + public int getCapacity() { + return Integer.MAX_VALUE; + } + + @Override + public FluidTankInfo getInfo() { + return FAKE_TANK_INFO; } @Override diff --git a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityDistillationTower.java b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityDistillationTower.java index 3dec51d880d..490c4107019 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityDistillationTower.java +++ b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityDistillationTower.java @@ -136,7 +136,7 @@ public void invalidateStructure() { } @Override - protected boolean allowSameFluidFillForOutputs() { + public boolean allowSameFluidFillForOutputs() { return false; } @@ -185,5 +185,10 @@ protected boolean setupAndConsumeRecipeInputs(@NotNull Recipe recipe, @NotNull IMultipleTankHandler importFluids) { return handler.setupAndConsumeRecipeInputs(recipe, importInventory, importFluids); } + + @Override + protected IMultipleTankHandler getOutputTank() { + return handler.fluidTanks; + } } } From f5b3ee680b6a6f47a0882efef9baee24f053d563 Mon Sep 17 00:00:00 2001 From: M-W-K Date: Sat, 6 Jul 2024 17:02:31 -0600 Subject: [PATCH 3/4] Improvements --- .../api/capability/IDistillationTower.java | 22 +++ .../impl/DistillationTowerLogicHandler.java | 126 ++++++++---------- .../MetaTileEntityDistillationTower.java | 49 +++++-- 3 files changed, 117 insertions(+), 80 deletions(-) create mode 100644 src/main/java/gregtech/api/capability/IDistillationTower.java diff --git a/src/main/java/gregtech/api/capability/IDistillationTower.java b/src/main/java/gregtech/api/capability/IDistillationTower.java new file mode 100644 index 00000000000..e7bf447518b --- /dev/null +++ b/src/main/java/gregtech/api/capability/IDistillationTower.java @@ -0,0 +1,22 @@ +package gregtech.api.capability; + +import gregtech.api.metatileentity.multiblock.IMultiblockPart; + +import net.minecraft.util.math.BlockPos; + +import java.util.List; + +/** + * intended for use in conjunction with {@link gregtech.api.capability.impl.DistillationTowerLogicHandler} + * use with distillation tower type multiblocks + */ +public interface IDistillationTower { + + List getMultiblockParts(); + + BlockPos getPos(); + + void invalidateStructure(); + + boolean allowSameFluidFillForOutputs(); +} diff --git a/src/main/java/gregtech/api/capability/impl/DistillationTowerLogicHandler.java b/src/main/java/gregtech/api/capability/impl/DistillationTowerLogicHandler.java index 96a22e5e314..1bc2ee49823 100644 --- a/src/main/java/gregtech/api/capability/impl/DistillationTowerLogicHandler.java +++ b/src/main/java/gregtech/api/capability/impl/DistillationTowerLogicHandler.java @@ -1,23 +1,19 @@ package gregtech.api.capability.impl; +import gregtech.api.capability.IDistillationTower; import gregtech.api.capability.IMultipleTankHandler; import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; -import gregtech.api.metatileentity.multiblock.IMultiblockPart; import gregtech.api.metatileentity.multiblock.MultiblockAbility; import gregtech.api.pattern.BlockPattern; -import gregtech.api.recipes.Recipe; import gregtech.api.util.GTLog; -import gregtech.api.util.GTTransferUtils; import gregtech.common.metatileentities.multi.multiblockpart.MetaTileEntityMultiblockPart; -import net.minecraft.util.math.BlockPos; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.FluidTankInfo; import net.minecraftforge.fluids.IFluidTank; import net.minecraftforge.fluids.capability.FluidTankProperties; import net.minecraftforge.fluids.capability.IFluidHandler; import net.minecraftforge.fluids.capability.IFluidTankProperties; -import net.minecraftforge.items.IItemHandlerModifiable; import com.cleanroommc.modularui.utils.FluidTankHandler; import it.unimi.dsi.fastutil.objects.ObjectArrayList; @@ -26,24 +22,33 @@ import java.util.List; import java.util.stream.Collectors; +/** + * Allows hatchscan behavior to be used on fluid outputs. Not a child of {@link AbstractRecipeLogic} + * for compatibility with other children. + */ public class DistillationTowerLogicHandler { - protected final AbstractRecipeLogic workable; protected final IDistillationTower tower; - public int layerCount; - public List orderedFluidOutputs; - public IMultipleTankHandler fluidTanks; + private int layerCount; + private List orderedFluidOutputs; + private IMultipleTankHandler fluidTanks; - public DistillationTowerLogicHandler(IDistillationTower tower, AbstractRecipeLogic workable) { + public DistillationTowerLogicHandler(IDistillationTower tower) { this.tower = tower; - this.workable = workable; } - protected boolean applyFluidToOutputs(List fluids, boolean doFill) { + /** + * Applies fluids to outputs on a sorted one fluid -> one hatch basis + * + * @param fluids the fluids to output. Will be automatically trimmed if there are not enough output hatches. + * @param doFill whether the application should be simulated or not. + * @return whether the fluids were successfully applied to the outputs or not. + */ + public boolean applyFluidToOutputs(List fluids, boolean doFill) { boolean valid = true; - for (int i = 0; i < fluids.size(); i++) { - IFluidHandler handler = orderedFluidOutputs.get(i); + for (int i = 0; i < Math.min(fluids.size(), this.getOrderedFluidOutputs().size()); i++) { + IFluidHandler handler = this.getOrderedFluidOutputs().get(i); int accepted = handler.fill(fluids.get(i), doFill); if (accepted != fluids.get(i).amount) valid = false; if (!doFill && !valid) break; @@ -51,58 +56,20 @@ protected boolean applyFluidToOutputs(List fluids, boolean doFill) { return valid; } - public void outputRecipeOutputs() { - GTTransferUtils.addItemsToItemHandler(workable.getOutputInventory(), false, workable.itemOutputs); - this.applyFluidToOutputs(workable.fluidOutputs, true); - } - - public boolean setupAndConsumeRecipeInputs(@NotNull Recipe recipe, - @NotNull IItemHandlerModifiable importInventory, - @NotNull IMultipleTankHandler importFluids) { - workable.overclockResults = workable.calculateOverclock(recipe); - - workable.modifyOverclockPost(workable.overclockResults, recipe.getRecipePropertyStorage()); - - if (!workable.hasEnoughPower(workable.overclockResults)) { - return false; - } - - IItemHandlerModifiable exportInventory = workable.getOutputInventory(); - - // We have already trimmed outputs and chanced outputs at this time - // Attempt to merge all outputs + chanced outputs into the output bus, to prevent voiding chanced outputs - if (!workable.getMetaTileEntity().canVoidRecipeItemOutputs() && - !GTTransferUtils.addItemsToItemHandler(exportInventory, true, recipe.getAllItemOutputs())) { - workable.isOutputsFull = true; - return false; - } - - // Perform layerwise fluid checks - if (!workable.getMetaTileEntity().canVoidRecipeFluidOutputs() && - !this.applyFluidToOutputs(recipe.getAllFluidOutputs(), false)) { - workable.isOutputsFull = true; - - return false; - } - - workable.isOutputsFull = false; - if (recipe.matches(true, importInventory, importFluids)) { - workable.getMetaTileEntity().addNotifiedInput(importInventory); - return true; - } - return false; - } - /** + * Called on structure formation to determine the number of layers in the distillation tower.
+ *
* Needs to be overriden for multiblocks that have different assemblies than the standard distillation tower. * * @param structurePattern the structure pattern */ public void determineLayerCount(@NotNull BlockPattern structurePattern) { - this.layerCount = structurePattern.formedRepetitionCount[1] + 1; + this.setLayerCount(structurePattern.formedRepetitionCount[1] + 1); } /** + * Called on structure formation to determine the ordered list of fluid handlers in the distillation tower.
+ *
* Needs to be overriden for multiblocks that have different assemblies than the standard distillation tower. */ public void determineOrderedFluidOutputs() { @@ -118,7 +85,7 @@ public void determineOrderedFluidOutputs() { List tankList = new ObjectArrayList<>(); int firstY = tower.getPos().getY() + 1; int exportIndex = 0; - for (int y = firstY; y < firstY + this.layerCount; y++) { + for (int y = firstY; y < firstY + this.getLayerCount(); y++) { if (fluidExportParts.size() <= exportIndex) { orderedHandlerList.add(FakeTank.INSTANCE); tankList.add(FakeTank.INSTANCE); @@ -138,31 +105,48 @@ public void determineOrderedFluidOutputs() { orderedHandlerList.add(FakeTank.INSTANCE); tankList.add(FakeTank.INSTANCE); } else { - GTLog.logger.error("The Distillation Tower at " + tower.getPos() + - " had a fluid export hatch with an unexpected Y position."); + GTLog.logger.error( + "The Distillation Tower at {} had a fluid export hatch with an unexpected Y position.", + tower.getPos()); tower.invalidateStructure(); - this.orderedFluidOutputs = new ObjectArrayList<>(); - this.fluidTanks = new FluidTankList(false); + this.setOrderedFluidOutputs(new ObjectArrayList<>()); + this.setFluidTanks(new FluidTankList(false)); } } - this.orderedFluidOutputs = orderedHandlerList; - this.fluidTanks = new FluidTankList(tower.allowSameFluidFillForOutputs(), tankList); + this.setOrderedFluidOutputs(orderedHandlerList); + this.setFluidTanks(new FluidTankList(tower.allowSameFluidFillForOutputs(), tankList)); } + /** + * Should be called on structure invalidation. + */ public void invalidate() { - this.layerCount = 0; - this.orderedFluidOutputs = null; + this.setLayerCount(0); + this.setOrderedFluidOutputs(null); } - public interface IDistillationTower { + protected void setLayerCount(int layerCount) { + this.layerCount = layerCount; + } + + public int getLayerCount() { + return layerCount; + } - List getMultiblockParts(); + protected void setOrderedFluidOutputs(List orderedFluidOutputs) { + this.orderedFluidOutputs = orderedFluidOutputs; + } - BlockPos getPos(); + public List getOrderedFluidOutputs() { + return orderedFluidOutputs; + } - void invalidateStructure(); + protected void setFluidTanks(IMultipleTankHandler fluidTanks) { + this.fluidTanks = fluidTanks; + } - boolean allowSameFluidFillForOutputs(); + public IMultipleTankHandler getFluidTanks() { + return fluidTanks; } // an endless void devouring any fluid sent to it diff --git a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityDistillationTower.java b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityDistillationTower.java index 490c4107019..8c8ac6f5407 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityDistillationTower.java +++ b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityDistillationTower.java @@ -1,5 +1,6 @@ package gregtech.common.metatileentities.multi.electric; +import gregtech.api.capability.IDistillationTower; import gregtech.api.capability.IMultipleTankHandler; import gregtech.api.capability.impl.DistillationTowerLogicHandler; import gregtech.api.capability.impl.MultiblockRecipeLogic; @@ -13,6 +14,7 @@ import gregtech.api.pattern.PatternMatchContext; import gregtech.api.recipes.Recipe; import gregtech.api.recipes.RecipeMaps; +import gregtech.api.util.GTTransferUtils; import gregtech.api.util.GTUtility; import gregtech.api.util.RelativeDirection; import gregtech.api.util.TextComponentUtil; @@ -40,8 +42,7 @@ import static gregtech.api.util.RelativeDirection.*; -public class MetaTileEntityDistillationTower extends RecipeMapMultiblockController - implements DistillationTowerLogicHandler.IDistillationTower { +public class MetaTileEntityDistillationTower extends RecipeMapMultiblockController implements IDistillationTower { protected DistillationTowerLogicHandler handler; @@ -53,9 +54,8 @@ public MetaTileEntityDistillationTower(ResourceLocation metaTileEntityId) { public MetaTileEntityDistillationTower(ResourceLocation metaTileEntityId, boolean useAdvHatchLogic) { super(metaTileEntityId, RecipeMaps.DISTILLATION_RECIPES); if (useAdvHatchLogic) { - DistillationTowerRecipeLogic logic = new DistillationTowerRecipeLogic(this); - this.recipeMapWorkable = logic; - this.handler = new DistillationTowerLogicHandler(this, logic); + this.recipeMapWorkable = new DistillationTowerRecipeLogic(this); + this.handler = new DistillationTowerLogicHandler(this); } else this.handler = null; } @@ -164,7 +164,7 @@ protected ICubeRenderer getFrontOverlay() { @Override public int getFluidOutputLimit() { - if (this.handler != null) return this.handler.layerCount; + if (this.handler != null) return this.handler.getLayerCount(); else return super.getFluidOutputLimit(); } @@ -176,19 +176,50 @@ public DistillationTowerRecipeLogic(MetaTileEntityDistillationTower tileEntity) @Override protected void outputRecipeOutputs() { - handler.outputRecipeOutputs(); + GTTransferUtils.addItemsToItemHandler(getOutputInventory(), false, itemOutputs); + handler.applyFluidToOutputs(fluidOutputs, true); } @Override protected boolean setupAndConsumeRecipeInputs(@NotNull Recipe recipe, @NotNull IItemHandlerModifiable importInventory, @NotNull IMultipleTankHandler importFluids) { - return handler.setupAndConsumeRecipeInputs(recipe, importInventory, importFluids); + this.overclockResults = calculateOverclock(recipe); + + modifyOverclockPost(overclockResults, recipe.getRecipePropertyStorage()); + + if (!hasEnoughPower(overclockResults)) { + return false; + } + + IItemHandlerModifiable exportInventory = getOutputInventory(); + + // We have already trimmed outputs and chanced outputs at this time + // Attempt to merge all outputs + chanced outputs into the output bus, to prevent voiding chanced outputs + if (!metaTileEntity.canVoidRecipeItemOutputs() && + !GTTransferUtils.addItemsToItemHandler(exportInventory, true, recipe.getAllItemOutputs())) { + this.isOutputsFull = true; + return false; + } + + // We have already trimmed fluid outputs at this time + if (!metaTileEntity.canVoidRecipeFluidOutputs() && + !handler.applyFluidToOutputs(recipe.getAllFluidOutputs(), false)) { + this.isOutputsFull = true; + return false; + } + + this.isOutputsFull = false; + if (recipe.matches(true, importInventory, importFluids)) { + this.metaTileEntity.addNotifiedInput(importInventory); + return true; + } + return false; } @Override protected IMultipleTankHandler getOutputTank() { - return handler.fluidTanks; + return handler.getFluidTanks(); } } } From 979aa3eb3338687758fd04c01ca4bdb2f8c3fba5 Mon Sep 17 00:00:00 2001 From: M-W-K Date: Sat, 6 Jul 2024 20:18:31 -0600 Subject: [PATCH 4/4] me when mui2 --- .../api/capability/impl/DistillationTowerLogicHandler.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/main/java/gregtech/api/capability/impl/DistillationTowerLogicHandler.java b/src/main/java/gregtech/api/capability/impl/DistillationTowerLogicHandler.java index 1bc2ee49823..e674db66763 100644 --- a/src/main/java/gregtech/api/capability/impl/DistillationTowerLogicHandler.java +++ b/src/main/java/gregtech/api/capability/impl/DistillationTowerLogicHandler.java @@ -15,7 +15,6 @@ import net.minecraftforge.fluids.capability.IFluidHandler; import net.minecraftforge.fluids.capability.IFluidTankProperties; -import com.cleanroommc.modularui.utils.FluidTankHandler; import it.unimi.dsi.fastutil.objects.ObjectArrayList; import org.jetbrains.annotations.NotNull; @@ -96,9 +95,7 @@ public void determineOrderedFluidOutputs() { List hatchTanks = new ObjectArrayList<>(); // noinspection unchecked ((IMultiblockAbilityPart) part).registerAbilities(hatchTanks); - if (hatchTanks.size() == 1) - orderedHandlerList.add(FluidTankHandler.getTankFluidHandler(hatchTanks.get(0))); - else orderedHandlerList.add(new FluidTankList(false, hatchTanks)); + orderedHandlerList.add(new FluidTankList(false, hatchTanks)); tankList.addAll(hatchTanks); exportIndex++; } else if (part.getPos().getY() > y) {