distillery improvements

This commit is contained in:
DrMangoTea
2023-09-14 16:07:03 +02:00
parent 60a3c7b9d5
commit 4de10aa5ae
16 changed files with 225 additions and 1942 deletions

View File

@@ -1,210 +0,0 @@
package com.drmangotea.tfmg.content.machines.oil_processing.distillation;
import com.drmangotea.tfmg.registry.TFMGBlockEntities;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllShapes;
import com.simibubi.create.Create;
import com.simibubi.create.content.equipment.wrench.IWrenchable;
import com.simibubi.create.content.fluids.transfer.GenericItemEmptying;
import com.simibubi.create.content.fluids.transfer.GenericItemFilling;
import com.simibubi.create.content.kinetics.belt.BeltBlockEntity;
import com.simibubi.create.content.kinetics.belt.behaviour.DirectBeltInputBehaviour;
import com.simibubi.create.content.logistics.funnel.FunnelBlock;
import com.simibubi.create.content.processing.basin.BasinOperatingBlockEntity;
import com.simibubi.create.foundation.block.IBE;
import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour;
import com.simibubi.create.foundation.fluid.FluidHelper;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.StateDefinition;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.world.level.block.state.properties.DirectionProperty;
import net.minecraft.world.level.pathfinder.PathComputationType;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.EntityCollisionContext;
import net.minecraft.world.phys.shapes.VoxelShape;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
import net.minecraftforge.fluids.capability.IFluidHandler;
import net.minecraftforge.items.IItemHandlerModifiable;
import net.minecraftforge.items.ItemStackHandler;
public class DistillationControllerBlock extends Block implements IBE<DistillationControllerBlockEntity>, IWrenchable {
public static final DirectionProperty FACING = BlockStateProperties.FACING_HOPPER;
public DistillationControllerBlock(Properties p_i48440_1_) {
super(p_i48440_1_);
registerDefaultState(defaultBlockState().setValue(FACING, Direction.DOWN));
}
@Override
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> p_206840_1_) {
super.createBlockStateDefinition(p_206840_1_.add(FACING));
}
@Override
public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) {
BlockEntity tileEntity = world.getBlockEntity(pos.above());
if (tileEntity instanceof BasinOperatingBlockEntity)
return false;
return true;
}
@Override
public InteractionResult use(BlockState state, Level worldIn, BlockPos pos, Player player, InteractionHand handIn,
BlockHitResult hit) {
ItemStack heldItem = player.getItemInHand(handIn);
return onBlockEntityUse(worldIn, pos, te -> {
if (!heldItem.isEmpty()) {
if (FluidHelper.tryEmptyItemIntoBE(worldIn, player, handIn, heldItem, te))
return InteractionResult.SUCCESS;
if (FluidHelper.tryFillItemFromBE(worldIn, player, handIn, heldItem, te))
return InteractionResult.SUCCESS;
if (GenericItemEmptying.canItemBeEmptied(worldIn, heldItem)
|| GenericItemFilling.canItemBeFilled(worldIn, heldItem))
return InteractionResult.SUCCESS;
if (heldItem.getItem()
.equals(Items.SPONGE)
&& !te.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY)
.map(iFluidHandler -> iFluidHandler.drain(Integer.MAX_VALUE, IFluidHandler.FluidAction.EXECUTE))
.orElse(FluidStack.EMPTY)
.isEmpty()) {
return InteractionResult.SUCCESS;
}
return InteractionResult.PASS;
}
IItemHandlerModifiable inv = te.itemCapability.orElse(new ItemStackHandler(1));
boolean success = false;
for (int slot = 0; slot < inv.getSlots(); slot++) {
ItemStack stackInSlot = inv.getStackInSlot(slot);
if (stackInSlot.isEmpty())
continue;
player.getInventory()
.placeItemBackInInventory(stackInSlot);
inv.setStackInSlot(slot, ItemStack.EMPTY);
success = true;
}
if (success)
worldIn.playSound(null, pos, SoundEvents.ITEM_PICKUP, SoundSource.PLAYERS, .2f,
1f + Create.RANDOM.nextFloat());
te.onEmptied();
return InteractionResult.SUCCESS;
});
}
@Override
public void updateEntityAfterFallOn(BlockGetter worldIn, Entity entityIn) {
super.updateEntityAfterFallOn(worldIn, entityIn);
if (!AllBlocks.BASIN.has(worldIn.getBlockState(entityIn.blockPosition())))
return;
if (!(entityIn instanceof ItemEntity))
return;
if (!entityIn.isAlive())
return;
ItemEntity itemEntity = (ItemEntity) entityIn;
withBlockEntityDo(worldIn, entityIn.blockPosition(), te -> {
// Tossed items bypass the quarter-stack limit
});
}
@Override
public VoxelShape getInteractionShape(BlockState p_199600_1_, BlockGetter p_199600_2_, BlockPos p_199600_3_) {
return AllShapes.BASIN_RAYTRACE_SHAPE;
}
@Override
public VoxelShape getShape(BlockState state, BlockGetter worldIn, BlockPos pos, CollisionContext context) {
return AllShapes.BASIN_BLOCK_SHAPE;
}
@Override
public VoxelShape getCollisionShape(BlockState state, BlockGetter reader, BlockPos pos, CollisionContext ctx) {
if (ctx instanceof EntityCollisionContext && ((EntityCollisionContext) ctx).getEntity() instanceof ItemEntity)
return AllShapes.BASIN_COLLISION_SHAPE;
return getShape(state, reader, pos, ctx);
}
@Override
public void onRemove(BlockState state, Level worldIn, BlockPos pos, BlockState newState, boolean isMoving) {
IBE.onRemove(state, worldIn, pos, newState);
}
@Override
public boolean hasAnalogOutputSignal(BlockState state) {
return true;
}
@Override
public Class<DistillationControllerBlockEntity> getBlockEntityClass() {
return DistillationControllerBlockEntity.class;
}
@Override
public BlockEntityType<? extends DistillationControllerBlockEntity> getBlockEntityType() {
return TFMGBlockEntities.CAST_IRON_DISTILLATION_CONTROLLER.get();
}
public static boolean canOutputTo(BlockGetter world, BlockPos basinPos, Direction direction) {
BlockPos neighbour = basinPos.relative(direction);
BlockPos output = neighbour.below();
BlockState blockState = world.getBlockState(neighbour);
if (FunnelBlock.isFunnel(blockState)) {
if (FunnelBlock.getFunnelFacing(blockState) == direction)
return false;
} else if (!blockState.getCollisionShape(world, neighbour)
.isEmpty()) {
return false;
} else {
BlockEntity tileEntity = world.getBlockEntity(output);
if (tileEntity instanceof BeltBlockEntity) {
BeltBlockEntity belt = (BeltBlockEntity) tileEntity;
return belt.getSpeed() == 0 || belt.getMovementFacing() != direction.getOpposite();
}
}
DirectBeltInputBehaviour directBeltInputBehaviour =
BlockEntityBehaviour.get(world, output, DirectBeltInputBehaviour.TYPE);
if (directBeltInputBehaviour != null)
return directBeltInputBehaviour.canInsertFromSide(direction);
return false;
}
@Override
public boolean isPathfindable(BlockState state, BlockGetter reader, BlockPos pos, PathComputationType type) {
return false;
}
}

View File

@@ -1,57 +0,0 @@
package com.drmangotea.tfmg.content.machines.oil_processing.distillation;
import com.drmangotea.tfmg.registry.TFMGBlockEntities;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllShapes;
import com.simibubi.create.foundation.block.IBE;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.pathfinder.PathComputationType;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.EntityCollisionContext;
import net.minecraft.world.phys.shapes.VoxelShape;
public class DistillationOutputBlock extends Block implements IBE<DistillationOutputBlockEntity> {
public DistillationOutputBlock(Properties properties) {
super(properties);
}
@Override
public boolean canSurvive(BlockState state, LevelReader worldIn, BlockPos pos) {
return !AllBlocks.BASIN.has(worldIn.getBlockState(pos.below()));
}
@Override
public VoxelShape getShape(BlockState state, BlockGetter worldIn, BlockPos pos, CollisionContext context) {
if (context instanceof EntityCollisionContext
&& ((EntityCollisionContext) context).getEntity() instanceof Player)
return AllShapes.CASING_14PX.get(Direction.DOWN);
return AllShapes.MECHANICAL_PROCESSOR_SHAPE;
}
@Override
public Class<DistillationOutputBlockEntity> getBlockEntityClass() {
return DistillationOutputBlockEntity.class;
}
@Override
public BlockEntityType<? extends DistillationOutputBlockEntity> getBlockEntityType() {
return TFMGBlockEntities.CAST_IRON_DISTILLATION_OUTPUT.get();
}
@Override
public boolean isPathfindable(BlockState state, BlockGetter reader, BlockPos pos, PathComputationType type) {
return false;
}
}

View File

@@ -1,427 +0,0 @@
package com.drmangotea.tfmg.content.machines.oil_processing.distillation;
import com.drmangotea.tfmg.CreateTFMG;
import com.drmangotea.tfmg.recipes.distillation.DistillationRecipe;
import com.drmangotea.tfmg.recipes.distillation.ItemlessRecipe;
import com.drmangotea.tfmg.registry.TFMGFluids;
import com.drmangotea.tfmg.registry.TFMGRecipeTypes;
import com.simibubi.create.AllRecipeTypes;
import com.simibubi.create.content.equipment.goggles.IHaveGoggleInformation;
import com.simibubi.create.content.kinetics.press.MechanicalPressBlockEntity;
import com.simibubi.create.content.processing.burner.BlazeBurnerBlock;
import com.simibubi.create.content.processing.burner.BlazeBurnerBlockEntity;
import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour;
import com.simibubi.create.foundation.fluid.SmartFluidTank;
import com.simibubi.create.foundation.recipe.RecipeFinder;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.NbtUtils;
import net.minecraft.network.chat.Component;
import net.minecraft.world.Container;
import net.minecraft.world.item.crafting.CraftingRecipe;
import net.minecraft.world.item.crafting.Recipe;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.level.material.Fluids;
import net.minecraft.world.phys.AABB;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.crafting.IShapedRecipe;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.IFluidTank;
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
import net.minecraftforge.fluids.capability.IFluidHandler;
import net.minecraftforge.fluids.capability.templates.FluidTank;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
public class DistillationOutputBlockEntity extends FluidProcessingBlockEntity implements IHaveGoggleInformation {
protected LazyOptional<IFluidHandler> fluidCapability;
public FluidTank tankInventory;
protected BlockPos lastKnownPos;
private static final int SYNC_RATE = 8;
protected int syncCooldown;
protected boolean queuedSync;
private static final Object DistillationRecipesKey = new Object();
public boolean running;
public DistillationOutputBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
super(type, pos, state);
tankInventory = createInventory();
fluidCapability = LazyOptional.of(() -> tankInventory);
refreshCapability();
}
protected <C extends Container> boolean matchItemlessRecipe(Recipe<C> recipe) {
if (recipe == null)
return false;
Optional<DistillationControllerBlockEntity> controller = getController();
if (!controller.isPresent())
return false;
return DistillationRecipe.match(controller.get(), recipe);
}
@Override
protected boolean updateController() {
if (level == null || level.isClientSide)
return true;
Optional<DistillationControllerBlockEntity> basin = getController();
List<Recipe<?>> recipes = getMatchingRecipes();
if (recipes.isEmpty())
return true;
currentRecipe = recipes.get(0);
startProcessing();
sendData();
return true;
}
@Override
public void addBehaviours(List<BlockEntityBehaviour> behaviours) {
super.addBehaviours(behaviours);
// registerAwardables(behaviours, AllAdvancements.MIXER);
}
@Override
protected AABB createRenderBoundingBox() {
return new AABB(worldPosition).expandTowards(0, -1.5, 0);
}
@Override
protected void read(CompoundTag compound, boolean clientPacket) {
running = compound.getBoolean("Running");
super.read(compound, clientPacket);
lastKnownPos = null;
if (compound.contains("LastKnownPos"))
lastKnownPos = NbtUtils.readBlockPos(compound.getCompound("LastKnownPos"));
tankInventory.setCapacity(8000);
tankInventory.readFromNBT(compound.getCompound("TankContent"));
if (tankInventory.getSpace() < 0)
tankInventory.drain(-tankInventory.getSpace(), IFluidHandler.FluidAction.EXECUTE);
}
@Override
public void write(CompoundTag compound, boolean clientPacket) {
compound.putBoolean("Running", running);
if (lastKnownPos != null)
compound.put("LastKnownPos", NbtUtils.writeBlockPos(lastKnownPos));
compound.put("TankContent", tankInventory.writeToNBT(new CompoundTag()));
super.write(compound, clientPacket);
super.write(compound, clientPacket);
}
@Override
public void tick() {
super.tick();
if (level != null) {
if ((!level.isClientSide || isVirtual())) {
process();
sendData();
}
}
if (syncCooldown > 0) {
syncCooldown--;
if (syncCooldown == 0 && queuedSync)
sendData();
}
}
protected void process() {
updateController();
if (currentRecipe == null)
return;
// if((currentRecipe instanceof ShapelessRecipe))
// return;
BlockEntity above1 = level.getBlockEntity(this.getBlockPos().above(1));
BlockEntity above2 = level.getBlockEntity(this.getBlockPos().above(2));
BlockEntity burner = level.getBlockEntity(this.getBlockPos().below(2));
if(!(burner instanceof BlazeBurnerBlockEntity))
return;
if(((BlazeBurnerBlockEntity) burner).getHeatLevelFromBlock()== BlazeBurnerBlock.HeatLevel.NONE)
return;
if(((BlazeBurnerBlockEntity) burner).getHeatLevelFromBlock()== BlazeBurnerBlock.HeatLevel.SMOULDERING)
return;
if(above1 !=null&& above2 !=null
// &&
/// tankInventory.getFluidAmount()+
/// ((DistillationRecipe)currentRecipe)
/// .getFirstFluidResult()
/// .getAmount()
/// <8000&&
// ((DistillationOutputBlockEntity) above1).tankInventory.getFluidAmount()+((DistillationRecipe)currentRecipe).getFluidResults().get(1).getAmount()<((DistillationOutputBlockEntity) above2).tankInventory.getCapacity()&&
// ((DistillationOutputBlockEntity) above2).tankInventory.getFluidAmount()+((DistillationRecipe)currentRecipe).getFluidResults().get(2).getAmount()<((DistillationOutputBlockEntity) above2).tankInventory.getCapacity()
){
Optional<DistillationControllerBlockEntity> optionalController = getController();
if (!optionalController.isPresent())
return;
if(!(above1 instanceof DistillationOutputBlockEntity)&&
!( above2 instanceof DistillationOutputBlockEntity)) {
return;
}
CreateTFMG.LOGGER.debug("EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEe");
FluidStack fluidInRecipe1 = ((DistillationRecipe) currentRecipe).getFirstFluidResult();
FluidStack fluidInRecipe2 = ((DistillationRecipe) currentRecipe).getSecondFluidResult();
FluidStack fluidInRecipe3 = ((DistillationRecipe) currentRecipe).getThirdFluidResult();
if (fluidInRecipe1.getFluid() != this.tankInventory.getFluid().getFluid()
&& tankInventory.getFluidAmount()!=0
)
return;
if (fluidInRecipe3.getFluid() != (((DistillationOutputBlockEntity) above1).tankInventory.getFluid().getFluid())
&&((DistillationOutputBlockEntity) above1).tankInventory.getFluidAmount()!=0
)
return;
if (fluidInRecipe3.getFluid() != (((DistillationOutputBlockEntity) above2).tankInventory.getFluid().getFluid())
&&((DistillationOutputBlockEntity) above2).tankInventory.getFluidAmount()!=0
)
return;
if(getController().get().getTanks().get(true).getPrimaryHandler().getFluid().getFluid() != ((DistillationRecipe) currentRecipe).getInputFluid().getMatchingFluidStacks().get(0).getFluid())
return;
DistillationControllerBlockEntity controller = optionalController.get();
IFluidHandler availableFluids = controller.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY)
.orElse(null);
if(controller.outputInventory.getStackInSlot(0).getCount()>=1||
controller.outputInventory.getStackInSlot(1).getCount()>=1||
controller.outputInventory.getStackInSlot(2).getCount()>=1)
return;
if (!controller.getTanks().get(true).isEmpty()) {
if(!level.isClientSide) {
// if(((DistillationRecipe)currentRecipe).getInputFluid().getMatchingFluidStacks().get(0).getFluid() != TFMGFluids.HEAVY_OIL.get())
// return;
controller.getTanks().get(true).getPrimaryHandler().drain(((DistillationRecipe) currentRecipe).getFluidIngredients().get(0).getRequiredAmount(), IFluidHandler.FluidAction.EXECUTE);
if (!(((DistillationRecipe) currentRecipe).getFluidResults().get(0).isEmpty()))
tankInventory.setFluid(new FluidStack(((DistillationRecipe) currentRecipe).getFluidResults().get(0).getFluid(), ((DistillationRecipe) currentRecipe).getFluidResults().get(0).getAmount() + this.tankInventory.getFluidAmount()));
if (!(((DistillationRecipe) currentRecipe).getFluidResults().get(1).isEmpty()))
((DistillationOutputBlockEntity) above1).tankInventory.setFluid(new FluidStack(((DistillationRecipe) currentRecipe).getFluidResults().get(1).getFluid(), ((DistillationRecipe) currentRecipe).getFluidResults().get(1).getAmount() + ((DistillationOutputBlockEntity) above1).tankInventory.getFluidAmount()));
if (!(((DistillationRecipe) currentRecipe).getFluidResults().get(2).isEmpty()))
((DistillationOutputBlockEntity) above2).tankInventory.setFluid(new FluidStack(((DistillationRecipe) currentRecipe).getFluidResults().get(2).getFluid(), ((DistillationRecipe) currentRecipe).getFluidResults().get(2).getAmount() + ((DistillationOutputBlockEntity) above2).tankInventory.getFluidAmount()));
if (!(((DistillationRecipe) currentRecipe).getFirstItemResult().isEmpty()))
controller.outputInventory.setItem(0, ((DistillationRecipe) currentRecipe).getFirstItemResult());
if (!(((DistillationRecipe) currentRecipe).getSecondItemResult().isEmpty()))
controller.outputInventory.setItem(1, ((DistillationRecipe) currentRecipe).getSecondItemResult());
}
/*
if(!(((DistillationRecipe) currentRecipe).getThirdItemResult().isEmpty()))
controller.outputInventory.setItem(2,((DistillationRecipe) currentRecipe).getFirstItemResult());
*/
controller.notifyChangeOfContents();
}
}
}
@Override
protected List<Recipe<?>> getMatchingRecipes() {
List<Recipe<?>> list = RecipeFinder.get(getRecipeCacheKey(), level, this::matchStaticFilters);
return list.stream()
.filter(this::matchItemlessRecipe)
.sorted((r1, r2) -> r2.getIngredients()
.size()
- r1.getIngredients()
.size())
.collect(Collectors.toList());
}
@Override
protected <C extends Container> boolean matchStaticFilters(Recipe<C> r) {
return ((r instanceof CraftingRecipe && !(r instanceof IShapedRecipe<?>)
&& r.getIngredients()
.size() > 1
&& !MechanicalPressBlockEntity.canCompress(r)) && !AllRecipeTypes.shouldIgnoreInAutomation(r)
|| r.getType() == TFMGRecipeTypes.DISTILLATION.getType());
}
@Override
public void startProcessing() {
if (running )
return;
super.startProcessing();
running = true;
}
@Override
public boolean continueWithPreviousRecipe() {
return true;
}
@Override
protected void onBasinRemoved() {
if (!running)
return;
running = false;
}
@Override
protected Object getRecipeCacheKey() {
return DistillationRecipesKey;
}
@Override
protected boolean isRunning() {
return running;
}
/*
@Override
protected Optional<CreateAdvancement> getProcessedRecipeTrigger() {
return Optional.of(AllAdvancements.MIXER);
}
*/
@Override
@OnlyIn(Dist.CLIENT)
public void tickAudio() {
super.tickAudio();
// SoundEvents.BLOCK_STONE_BREAK
}
protected SmartFluidTank createInventory() {
return new SmartFluidTank(8000, this::onFluidStackChanged);
}
protected void onFluidStackChanged(FluidStack newFluidStack) {
if (!hasLevel())
return;
}
public void sendDataImmediately() {
syncCooldown = 0;
queuedSync = false;
sendData();
}
@Override
public void sendData() {
if (syncCooldown > 0) {
queuedSync = true;
return;
}
super.sendData();
queuedSync = false;
syncCooldown = SYNC_RATE;
}
private void refreshCapability() {
LazyOptional<IFluidHandler> oldCap = fluidCapability;
fluidCapability = LazyOptional.of(() -> handlerForCapability());
oldCap.invalidate();
}
private IFluidHandler handlerForCapability() {
return tankInventory;
}
public boolean addToGoggleTooltip(List<Component> tooltip, boolean isPlayerSneaking) {
return containedFluidTooltip(tooltip, isPlayerSneaking,
this.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY));
}
@Nonnull
@Override
public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, @Nullable Direction side) {
if (!fluidCapability.isPresent())
refreshCapability();
if (cap == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY)
return fluidCapability.cast();
return super.getCapability(cap, side);
}
public IFluidTank getTankInventory() {
return tankInventory;
}
public FluidStack getFluid(int tank) {
return tankInventory.getFluid()
.copy();
}
}

View File

@@ -0,0 +1,76 @@
package com.drmangotea.tfmg.content.machines.oil_processing.distillation.distillery;
import com.drmangotea.tfmg.registry.TFMGBlockEntities;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.Create;
import com.simibubi.create.content.equipment.wrench.IWrenchable;
import com.simibubi.create.content.fluids.transfer.GenericItemEmptying;
import com.simibubi.create.content.fluids.transfer.GenericItemFilling;
import com.simibubi.create.content.kinetics.belt.BeltBlockEntity;
import com.simibubi.create.content.kinetics.belt.behaviour.DirectBeltInputBehaviour;
import com.simibubi.create.content.logistics.funnel.FunnelBlock;
import com.simibubi.create.content.processing.basin.BasinOperatingBlockEntity;
import com.simibubi.create.foundation.block.IBE;
import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour;
import com.simibubi.create.foundation.fluid.FluidHelper;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.StateDefinition;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.world.level.block.state.properties.DirectionProperty;
import net.minecraft.world.level.pathfinder.PathComputationType;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
import net.minecraftforge.fluids.capability.IFluidHandler;
import net.minecraftforge.items.IItemHandlerModifiable;
import net.minecraftforge.items.ItemStackHandler;
public class DistilleryControllerBlock extends Block implements IBE<DistilleryControllerBlockEntity>, IWrenchable {
public DistilleryControllerBlock(Properties p_i48440_1_) {
super(p_i48440_1_);
}
@Override
public void onRemove(BlockState state, Level worldIn, BlockPos pos, BlockState newState, boolean isMoving) {
IBE.onRemove(state, worldIn, pos, newState);
}
@Override
public Class<DistilleryControllerBlockEntity> getBlockEntityClass() {
return DistilleryControllerBlockEntity.class;
}
@Override
public BlockEntityType<? extends DistilleryControllerBlockEntity> getBlockEntityType() {
return TFMGBlockEntities.CAST_IRON_DISTILLATION_CONTROLLER.get();
}
@Override
public boolean isPathfindable(BlockState state, BlockGetter reader, BlockPos pos, PathComputationType type) {
return false;
}
}

View File

@@ -1,14 +1,12 @@
package com.drmangotea.tfmg.content.machines.oil_processing.distillation;
package com.drmangotea.tfmg.content.machines.oil_processing.distillation.distillery;
import com.google.common.collect.ImmutableList;
import com.drmangotea.tfmg.content.machines.oil_processing.distillation.FluidProcessingBlockEntity;
import com.simibubi.create.AllTags;
import com.simibubi.create.content.equipment.goggles.IHaveGoggleInformation;
import com.simibubi.create.content.kinetics.belt.behaviour.DirectBeltInputBehaviour;
import com.simibubi.create.content.processing.burner.BlazeBurnerBlock;
import com.simibubi.create.foundation.blockEntity.SmartBlockEntity;
import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour;
import com.simibubi.create.foundation.blockEntity.behaviour.ValueBoxTransform;
import com.simibubi.create.foundation.blockEntity.behaviour.filtering.FilteringBehaviour;
import com.simibubi.create.foundation.blockEntity.behaviour.fluid.SmartFluidTankBehaviour;
import com.simibubi.create.foundation.blockEntity.behaviour.inventory.InvManipulationBehaviour;
import com.simibubi.create.foundation.fluid.CombinedTankWrapper;
@@ -22,11 +20,9 @@ import net.minecraft.nbt.StringTag;
import net.minecraft.nbt.Tag;
import net.minecraft.network.chat.Component;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.fluids.FluidStack;
@@ -41,7 +37,7 @@ import net.minecraftforge.items.wrapper.CombinedInvWrapper;
import javax.annotation.Nonnull;
import java.util.*;
public class DistillationControllerBlockEntity extends SmartBlockEntity implements IHaveGoggleInformation {
public class DistilleryControllerBlockEntity extends SmartBlockEntity implements IHaveGoggleInformation {
public SmartFluidTankBehaviour inputTank;
protected SmartInventory outputInventory;
@@ -49,17 +45,14 @@ public class DistillationControllerBlockEntity extends SmartBlockEntity implemen
private boolean contentsChanged;
private Couple<SmartFluidTankBehaviour> tanks;
public LazyOptional<IItemHandlerModifiable> itemCapability;
protected LazyOptional<IFluidHandler> fluidCapability;
int recipeBackupCheck;
public DistillationControllerBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
public DistilleryControllerBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
super(type, pos, state);
outputInventory = new SmartInventory(9, this).forbidInsertion()
@@ -68,7 +61,9 @@ public class DistillationControllerBlockEntity extends SmartBlockEntity implemen
itemCapability = LazyOptional.of(() -> new CombinedInvWrapper( outputInventory));
contentsChanged = true;
tanks = Couple.create(inputTank, outputTank);
recipeBackupCheck = 20;
}
@@ -76,8 +71,6 @@ public class DistillationControllerBlockEntity extends SmartBlockEntity implemen
public void addBehaviours(List<BlockEntityBehaviour> behaviours) {
behaviours.add(new DirectBeltInputBehaviour(this));
inputTank = new SmartFluidTankBehaviour(SmartFluidTankBehaviour.INPUT, this, 2, 1000, true)
.whenFluidUpdates(() -> contentsChanged = true);
outputTank = new SmartFluidTankBehaviour(SmartFluidTankBehaviour.OUTPUT, this, 2, 1000, true)
@@ -99,7 +92,6 @@ public class DistillationControllerBlockEntity extends SmartBlockEntity implemen
outputInventory.deserializeNBT(compound.getCompound("OutputItems"));
}
@Override
@@ -162,10 +154,6 @@ public class DistillationControllerBlockEntity extends SmartBlockEntity implemen
recipeBackupCheck = 20;
}
}
@@ -174,7 +162,6 @@ public class DistillationControllerBlockEntity extends SmartBlockEntity implemen
super.tick();
if (!contentsChanged)
return;
@@ -185,16 +172,16 @@ public class DistillationControllerBlockEntity extends SmartBlockEntity implemen
BlockPos toUpdate = worldPosition.above()
.relative(offset);
BlockState stateToUpdate = level.getBlockState(toUpdate);
if (stateToUpdate.getBlock() instanceof DistillationControllerBlock
&& stateToUpdate.getValue(DistillationControllerBlock.FACING) == offset.getOpposite()) {
BlockEntity te = level.getBlockEntity(toUpdate);
if (te instanceof DistillationControllerBlockEntity)
((DistillationControllerBlockEntity) te).contentsChanged = true;
if (stateToUpdate.getBlock() instanceof DistilleryControllerBlock) {
BlockEntity be = level.getBlockEntity(toUpdate);
if (be instanceof DistilleryControllerBlockEntity)
((DistilleryControllerBlockEntity) be).contentsChanged = true;
}
}
}
private Optional<FluidProcessingBlockEntity> getOperator() {
if (level == null)
return Optional.empty();
@@ -217,106 +204,6 @@ public class DistillationControllerBlockEntity extends SmartBlockEntity implemen
}
public boolean acceptOutputs(List<ItemStack> outputItems, List<FluidStack> outputFluids, boolean simulate) {
outputInventory.allowInsertion();
outputTank.allowInsertion();
boolean acceptOutputsInner = acceptOutputsInner(outputItems, outputFluids, simulate);
outputInventory.forbidInsertion();
outputTank.forbidInsertion();
return acceptOutputsInner;
}
private boolean acceptOutputsInner(List<ItemStack> outputItems, List<FluidStack> outputFluids, boolean simulate) {
BlockState blockState = getBlockState();
if (!(blockState.getBlock() instanceof DistillationControllerBlock))
return false;
Direction direction = blockState.getValue(DistillationControllerBlock.FACING);
if (direction != Direction.DOWN) {
BlockEntity te = level.getBlockEntity(worldPosition.below()
.relative(direction));
InvManipulationBehaviour inserter =
te == null ? null : BlockEntityBehaviour.get(level, te.getBlockPos(), InvManipulationBehaviour.TYPE);
IItemHandler targetInv = te == null ? null
: te.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, direction.getOpposite())
.orElse(inserter == null ? null : inserter.getInventory());
IFluidHandler targetTank = te == null ? null
: te.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, direction.getOpposite())
.orElse(null);
boolean externalTankNotPresent = targetTank == null;
if (!outputItems.isEmpty() && targetInv == null)
return false;
if (!outputFluids.isEmpty() && externalTankNotPresent) {
// Special case - fluid outputs but output only accepts items
targetTank = outputTank.getCapability()
.orElse(null);
if (targetTank == null)
return false;
if (!acceptFluidOutputsIntoBasin(outputFluids, simulate, targetTank))
return false;
}
if (simulate)
return true;
if (!externalTankNotPresent)
return true;
}
IItemHandler targetInv = outputInventory;
IFluidHandler targetTank = outputTank.getCapability()
.orElse(null);
if (targetInv == null && !outputItems.isEmpty())
return false;
if (!acceptItemOutputsIntoBasin(outputItems, simulate, targetInv))
return false;
if (outputFluids.isEmpty())
return true;
if (targetTank == null)
return false;
if (!acceptFluidOutputsIntoBasin(outputFluids, simulate, targetTank))
return false;
return true;
}
private boolean acceptFluidOutputsIntoBasin(List<FluidStack> outputFluids, boolean simulate,
IFluidHandler targetTank) {
for (FluidStack fluidStack : outputFluids) {
IFluidHandler.FluidAction action = simulate ? IFluidHandler.FluidAction.SIMULATE : IFluidHandler.FluidAction.EXECUTE;
int fill = targetTank instanceof SmartFluidTankBehaviour.InternalFluidHandler
? ((SmartFluidTankBehaviour.InternalFluidHandler) targetTank).forceFill(fluidStack.copy(), action)
: targetTank.fill(fluidStack.copy(), action);
if (fill != fluidStack.getAmount())
return false;
}
return true;
}
private boolean acceptItemOutputsIntoBasin(List<ItemStack> outputItems, boolean simulate, IItemHandler targetInv) {
for (ItemStack itemStack : outputItems) {
// Catalyst items are never consumed
if (itemStack.hasCraftingRemainingItem() && itemStack.getCraftingRemainingItem()
.sameItem(itemStack))
continue;
if (!ItemHandlerHelper.insertItemStacked(targetInv, itemStack.copy(), simulate)
.isEmpty())
return false;
}
return true;
}
public void readOnlyItems(CompoundTag compound) {
outputInventory.deserializeNBT(compound.getCompound("OutputItems"));
}
public static BlazeBurnerBlock.HeatLevel getHeatLevelOf(BlockState state) {
if (state.hasProperty(BlazeBurnerBlock.HEAT_LEVEL))
return state.getValue(BlazeBurnerBlock.HEAT_LEVEL);
@@ -328,31 +215,11 @@ public class DistillationControllerBlockEntity extends SmartBlockEntity implemen
}
// client things
@Override
public boolean addToGoggleTooltip(List<Component> tooltip, boolean isPlayerSneaking) {
return containedFluidTooltip(tooltip, isPlayerSneaking,
getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY));
}
class BasinValueBox extends ValueBoxTransform.Sided {
@Override
protected Vec3 getSouthLocation() {
return VecHelper.voxelSpace(8, 12, 15.75);
}
@Override
protected boolean isSideActive(BlockState state, Direction direction) {
return direction.getAxis()
.isHorizontal();
}
}
}

View File

@@ -0,0 +1,42 @@
package com.drmangotea.tfmg.content.machines.oil_processing.distillation.distillery;
import com.drmangotea.tfmg.registry.TFMGBlockEntities;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.foundation.block.IBE;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.pathfinder.PathComputationType;
public class DistilleryOutputBlock extends Block implements IBE<DistilleryOutputBlockEntity> {
public DistilleryOutputBlock(Properties properties) {
super(properties);
}
@Override
public boolean canSurvive(BlockState state, LevelReader worldIn, BlockPos pos) {
return !AllBlocks.BASIN.has(worldIn.getBlockState(pos.below()));
}
@Override
public Class<DistilleryOutputBlockEntity> getBlockEntityClass() {
return DistilleryOutputBlockEntity.class;
}
@Override
public BlockEntityType<? extends DistilleryOutputBlockEntity> getBlockEntityType() {
return TFMGBlockEntities.CAST_IRON_DISTILLATION_OUTPUT.get();
}
@Override
public boolean isPathfindable(BlockState state, BlockGetter reader, BlockPos pos, PathComputationType type) {
return false;
}
}

View File

@@ -1,7 +1,8 @@
package com.drmangotea.tfmg.content.machines.oil_processing.distillation.backup;
package com.drmangotea.tfmg.content.machines.oil_processing.distillation.distillery;
import com.drmangotea.tfmg.CreateTFMG;
import com.drmangotea.tfmg.content.machines.oil_processing.distillation.FluidProcessingBlockEntity;
import com.drmangotea.tfmg.recipes.distillation.DistillationRecipe;
import com.drmangotea.tfmg.registry.TFMGRecipeTypes;
import com.simibubi.create.AllRecipeTypes;
@@ -41,7 +42,7 @@ import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
public class DistillationOutputBlockEntity extends FluidProcessingBlockEntity implements IHaveGoggleInformation {
public class DistilleryOutputBlockEntity extends FluidProcessingBlockEntity implements IHaveGoggleInformation {
protected LazyOptional<IFluidHandler> fluidCapability;
public FluidTank tankInventory;
@@ -56,7 +57,7 @@ public class DistillationOutputBlockEntity extends FluidProcessingBlockEntity im
public boolean running;
public DistillationOutputBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
public DistilleryOutputBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
super(type, pos, state);
tankInventory = createInventory();
fluidCapability = LazyOptional.of(() -> tankInventory);
@@ -66,7 +67,7 @@ public class DistillationOutputBlockEntity extends FluidProcessingBlockEntity im
protected <C extends Container> boolean matchItemlessRecipe(Recipe<C> recipe) {
if (recipe == null)
return false;
Optional<DistillationControllerBlockEntity> controller = getController();
Optional<DistilleryControllerBlockEntity> controller = getController();
if (!controller.isPresent())
return false;
return DistillationRecipe.match(controller.get(), recipe);
@@ -76,11 +77,8 @@ public class DistillationOutputBlockEntity extends FluidProcessingBlockEntity im
protected boolean updateController() {
if (level == null || level.isClientSide)
return true;
Optional<DistillationControllerBlockEntity> basin = getController();
List<Recipe<?>> recipes = getMatchingRecipes();
if (recipes.isEmpty())
@@ -94,7 +92,7 @@ public class DistillationOutputBlockEntity extends FluidProcessingBlockEntity im
@Override
public void addBehaviours(List<BlockEntityBehaviour> behaviours) {
super.addBehaviours(behaviours);
// registerAwardables(behaviours, AllAdvancements.MIXER);
}
@Override
@@ -118,9 +116,7 @@ public class DistillationOutputBlockEntity extends FluidProcessingBlockEntity im
if (tankInventory.getSpace() < 0)
tankInventory.drain(-tankInventory.getSpace(), IFluidHandler.FluidAction.EXECUTE);
}
@Override
public void write(CompoundTag compound, boolean clientPacket) {
compound.putBoolean("Running", running);
@@ -158,8 +154,6 @@ public class DistillationOutputBlockEntity extends FluidProcessingBlockEntity im
if (currentRecipe == null)
return;
// if((currentRecipe instanceof ShapelessRecipe))
// return;
@@ -184,16 +178,20 @@ if(above1 !=null&& above2 !=null
// ((DistillationOutputBlockEntity) above1).tankInventory.getFluidAmount()+((DistillationRecipe)currentRecipe).getFluidResults().get(1).getAmount()<((DistillationOutputBlockEntity) above2).tankInventory.getCapacity()&&
// ((DistillationOutputBlockEntity) above2).tankInventory.getFluidAmount()+((DistillationRecipe)currentRecipe).getFluidResults().get(2).getAmount()<((DistillationOutputBlockEntity) above2).tankInventory.getCapacity()
){
Optional<DistillationControllerBlockEntity> optionalController = getController();
Optional<DistilleryControllerBlockEntity> optionalController = getController();
if (!optionalController.isPresent())
return;
if(!(above1 instanceof DistillationOutputBlockEntity)&&
!( above2 instanceof DistillationOutputBlockEntity)) {
if(!(above1 instanceof DistilleryOutputBlockEntity)&&
!( above2 instanceof DistilleryOutputBlockEntity)) {
return;
}
CreateTFMG.LOGGER.debug("EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEe");
if(!(above1 instanceof DistilleryOutputBlockEntity))
return;
if(!(above2 instanceof DistilleryOutputBlockEntity))
return;
FluidStack fluidInRecipe1 = ((DistillationRecipe) currentRecipe).getFirstFluidResult();
FluidStack fluidInRecipe2 = ((DistillationRecipe) currentRecipe).getSecondFluidResult();
@@ -207,12 +205,12 @@ if(above1 !=null&& above2 !=null
)
return;
if (fluidInRecipe3.getFluid() != (((DistillationOutputBlockEntity) above1).tankInventory.getFluid().getFluid())
&&((DistillationOutputBlockEntity) above1).tankInventory.getFluidAmount()!=0
if (fluidInRecipe2.getFluid() != (((DistilleryOutputBlockEntity) above1).tankInventory.getFluid().getFluid())
&&((DistilleryOutputBlockEntity) above1).tankInventory.getFluidAmount()!=0
)
return;
if (fluidInRecipe3.getFluid() != (((DistillationOutputBlockEntity) above2).tankInventory.getFluid().getFluid())
&&((DistillationOutputBlockEntity) above2).tankInventory.getFluidAmount()!=0
if (fluidInRecipe3.getFluid() != (((DistilleryOutputBlockEntity) above2).tankInventory.getFluid().getFluid())
&&((DistilleryOutputBlockEntity) above2).tankInventory.getFluidAmount()!=0
)
return;
@@ -222,7 +220,7 @@ if(above1 !=null&& above2 !=null
if(getController().get().getTanks().get(true).getPrimaryHandler().getFluid().getFluid() != ((DistillationRecipe) currentRecipe).getInputFluid().getMatchingFluidStacks().get(0).getFluid())
return;
DistillationControllerBlockEntity controller = optionalController.get();
DistilleryControllerBlockEntity controller = optionalController.get();
IFluidHandler availableFluids = controller.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY)
.orElse(null);
@@ -241,9 +239,9 @@ if(above1 !=null&& above2 !=null
if (!(((DistillationRecipe) currentRecipe).getFluidResults().get(0).isEmpty()))
tankInventory.setFluid(new FluidStack(((DistillationRecipe) currentRecipe).getFluidResults().get(0).getFluid(), ((DistillationRecipe) currentRecipe).getFluidResults().get(0).getAmount() + this.tankInventory.getFluidAmount()));
if (!(((DistillationRecipe) currentRecipe).getFluidResults().get(1).isEmpty()))
((DistillationOutputBlockEntity) above1).tankInventory.setFluid(new FluidStack(((DistillationRecipe) currentRecipe).getFluidResults().get(1).getFluid(), ((DistillationRecipe) currentRecipe).getFluidResults().get(1).getAmount() + ((DistillationOutputBlockEntity) above1).tankInventory.getFluidAmount()));
((DistilleryOutputBlockEntity) above1).tankInventory.setFluid(new FluidStack(((DistillationRecipe) currentRecipe).getFluidResults().get(1).getFluid(), ((DistillationRecipe) currentRecipe).getFluidResults().get(1).getAmount() + ((DistilleryOutputBlockEntity) above1).tankInventory.getFluidAmount()));
if (!(((DistillationRecipe) currentRecipe).getFluidResults().get(2).isEmpty()))
((DistillationOutputBlockEntity) above2).tankInventory.setFluid(new FluidStack(((DistillationRecipe) currentRecipe).getFluidResults().get(2).getFluid(), ((DistillationRecipe) currentRecipe).getFluidResults().get(2).getAmount() + ((DistillationOutputBlockEntity) above2).tankInventory.getFluidAmount()));
((DistilleryOutputBlockEntity) above2).tankInventory.setFluid(new FluidStack(((DistillationRecipe) currentRecipe).getFluidResults().get(2).getFluid(), ((DistillationRecipe) currentRecipe).getFluidResults().get(2).getAmount() + ((DistilleryOutputBlockEntity) above2).tankInventory.getFluidAmount()));
if (!(((DistillationRecipe) currentRecipe).getFirstItemResult().isEmpty()))
@@ -259,10 +257,6 @@ if(!(((DistillationRecipe) currentRecipe).getThirdItemResult().isEmpty()))
*/
controller.notifyChangeOfContents();
}
@@ -330,16 +324,7 @@ if(!(((DistillationRecipe) currentRecipe).getThirdItemResult().isEmpty()))
return Optional.of(AllAdvancements.MIXER);
}
*/
@Override
@OnlyIn(Dist.CLIENT)
public void tickAudio() {
super.tickAudio();
// SoundEvents.BLOCK_STONE_BREAK
}
protected SmartFluidTank createInventory() {
@@ -355,11 +340,6 @@ if(!(((DistillationRecipe) currentRecipe).getThirdItemResult().isEmpty()))
}
public void sendDataImmediately() {
syncCooldown = 0;
queuedSync = false;
sendData();
}
@Override
public void sendData() {

View File

@@ -1,8 +1,6 @@
package com.drmangotea.tfmg.recipes.distillation;
import com.drmangotea.tfmg.CreateTFMG;
import com.drmangotea.tfmg.content.machines.oil_processing.distillation.DistillationControllerBlockEntity;
import com.drmangotea.tfmg.registry.TFMGFluids;
import com.drmangotea.tfmg.content.machines.oil_processing.distillation.distillery.DistilleryControllerBlockEntity;
import com.simibubi.create.content.processing.burner.BlazeBurnerBlock;
import com.simibubi.create.content.processing.recipe.ProcessingRecipe;
import com.simibubi.create.content.processing.recipe.ProcessingRecipeBuilder;
@@ -11,12 +9,10 @@ import com.simibubi.create.foundation.fluid.FluidIngredient;
import com.simibubi.create.foundation.item.SmartInventory;
import com.simibubi.create.foundation.recipe.IRecipeTypeInfo;
import com.simibubi.create.foundation.utility.Iterate;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.Ingredient;
import net.minecraft.world.item.crafting.Recipe;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.material.Fluid;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
import net.minecraftforge.fluids.capability.IFluidHandler;
@@ -31,7 +27,7 @@ import java.util.List;
public class ItemlessRecipe extends ProcessingRecipe<SmartInventory> {
public static boolean match(DistillationControllerBlockEntity controller, Recipe<?> recipe) {
public static boolean match(DistilleryControllerBlockEntity controller, Recipe<?> recipe) {
@@ -48,11 +44,11 @@ public class ItemlessRecipe extends ProcessingRecipe<SmartInventory> {
}
public static boolean apply(DistillationControllerBlockEntity basin, Recipe<?> recipe) {
public static boolean apply(DistilleryControllerBlockEntity basin, Recipe<?> recipe) {
return apply(basin, recipe, false);
}
private static boolean apply(DistillationControllerBlockEntity controller, Recipe<?> recipe, boolean test) {
private static boolean apply(DistilleryControllerBlockEntity controller, Recipe<?> recipe, boolean test) {
boolean isItemlessRecipe = recipe instanceof ItemlessRecipe;
IItemHandler availableItems = controller.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY)
.orElse(null);
@@ -62,7 +58,7 @@ public class ItemlessRecipe extends ProcessingRecipe<SmartInventory> {
if (availableItems == null || availableFluids == null)
return false;
BlazeBurnerBlock.HeatLevel heat = DistillationControllerBlockEntity.getHeatLevelOf(controller.getLevel()
BlazeBurnerBlock.HeatLevel heat = DistilleryControllerBlockEntity.getHeatLevelOf(controller.getLevel()
.getBlockState(controller.getBlockPos()
.below(1)));
if (isItemlessRecipe && !((ItemlessRecipe) recipe).getRequiredHeat()
@@ -72,7 +68,7 @@ public class ItemlessRecipe extends ProcessingRecipe<SmartInventory> {
List<ItemStack> recipeOutputItems = new ArrayList<>();
List<FluidStack> recipeOutputFluids = new ArrayList<>();
List<Ingredient> ingredients = new LinkedList<>(recipe.getIngredients());
List<FluidIngredient> fluidIngredients =
isItemlessRecipe ? ((ItemlessRecipe) recipe).getFluidIngredients() : Collections.emptyList();
if(!fluidIngredients.isEmpty())
@@ -85,28 +81,8 @@ public class ItemlessRecipe extends ProcessingRecipe<SmartInventory> {
if (!simulate && test)
return true;
int[] extractedItemsFromSlot = new int[availableItems.getSlots()];
int[] extractedFluidsFromTank = new int[availableFluids.getTanks()];
Ingredients: for (int i = 0; i < ingredients.size(); i++) {
Ingredient ingredient = ingredients.get(i);
for (int slot = 0; slot < availableItems.getSlots(); slot++) {
if (simulate && availableItems.getStackInSlot(slot)
.getCount() <= extractedItemsFromSlot[slot])
continue;
ItemStack extracted = availableItems.extractItem(slot, 1, true);
if (!ingredient.test(extracted))
continue;
if (!simulate)
availableItems.extractItem(slot, 1, false);
extractedItemsFromSlot[slot]++;
continue Ingredients;
}
// something wasn't found
return false;
}
boolean fluidsAffected = false;
FluidIngredients: for (int i = 0; i < fluidIngredients.size(); i++) {
@@ -150,17 +126,9 @@ public class ItemlessRecipe extends ProcessingRecipe<SmartInventory> {
} else {
recipeOutputItems.add(recipe.getResultItem());
/*
if (recipe instanceof CraftingRecipe craftingRecipe) {
recipeOutputItems.addAll(craftingRecipe.getRemainingItems(new DummyCraftingContainer(availableItems, extractedItemsFromSlot)));
}
*/
}
}
if (!controller.acceptOutputs(recipeOutputItems, recipeOutputFluids, simulate))
return false;
}
return true;
@@ -190,7 +158,7 @@ public class ItemlessRecipe extends ProcessingRecipe<SmartInventory> {
@Override
protected int getMaxFluidOutputCount() {
return 3;
return 6;
}
@Override

View File

@@ -0,0 +1,50 @@
package com.drmangotea.tfmg.recipes.distillation.advanced;
import com.drmangotea.tfmg.recipes.distillation.ItemlessRecipe;
import com.drmangotea.tfmg.registry.TFMGRecipeTypes;
import com.simibubi.create.content.processing.recipe.ProcessingRecipeBuilder;
import com.simibubi.create.foundation.fluid.FluidIngredient;
import net.minecraft.world.item.ItemStack;
import net.minecraftforge.fluids.FluidStack;
public class AdvancedDistillationRecipe extends ItemlessRecipe {
public AdvancedDistillationRecipe(ProcessingRecipeBuilder.ProcessingRecipeParams params) {
super(TFMGRecipeTypes.ADVANCED_DISTILLATION, params);
}
public FluidIngredient getInputFluid(){
return getFluidIngredients().get(0);
}
public FluidStack getFirstFluidResult(){
return fluidResults.get(0);
}
public FluidStack getSecondFluidResult(){
return fluidResults.get(1);
}
public FluidStack getThirdFluidResult(){
return fluidResults.get(2);
}
public FluidStack getFourthFluidResult(){
return fluidResults.get(3);
}
public FluidStack getFifthFluidResult(){
return fluidResults.get(4);
}
public FluidStack getSixthFluidResult(){
return fluidResults.get(5);
}
public ItemStack getFirstItemResult(){
return results.get(0).getStack();
}
public ItemStack getSecondItemResult(){
return results.get(1).getStack();
}
public ItemStack getThirdItemResult(){
return results.get(2).getStack();
}
}

View File

@@ -7,8 +7,8 @@ import com.drmangotea.tfmg.content.decoration.doors.TFMGSlidingDoorRenderer;
import com.drmangotea.tfmg.content.deposits.FluidDepositBlockEntity;
import com.drmangotea.tfmg.content.deposits.surface_scanner.SurfaceScannerRenderer;
import com.drmangotea.tfmg.content.deposits.surface_scanner.SurfaceScannerTileEntity;
import com.drmangotea.tfmg.content.machines.oil_processing.distillation.DistillationControllerBlockEntity;
import com.drmangotea.tfmg.content.machines.oil_processing.distillation.DistillationOutputBlockEntity;
import com.drmangotea.tfmg.content.machines.oil_processing.distillation.distillery.DistilleryControllerBlockEntity;
import com.drmangotea.tfmg.content.machines.oil_processing.distillation.distillery.DistilleryOutputBlockEntity;
import com.drmangotea.tfmg.content.machines.pipes.normal.LockablePipeBlockEntity;
import com.drmangotea.tfmg.content.machines.tanks.SteelFluidTankRenderer;
import com.drmangotea.tfmg.content.machines.tanks.SteelTankBlockEntity;
@@ -102,13 +102,13 @@ public class TFMGBlockEntities {
.register();
public static final BlockEntityEntry<DistillationOutputBlockEntity> CAST_IRON_DISTILLATION_OUTPUT = REGISTRATE
.blockEntity("distiller", DistillationOutputBlockEntity::new)
public static final BlockEntityEntry<DistilleryOutputBlockEntity> CAST_IRON_DISTILLATION_OUTPUT = REGISTRATE
.blockEntity("distiller", DistilleryOutputBlockEntity::new)
.validBlocks(TFMGBlocks.CAST_IRON_DISTILLATION_OUTPUT)
.register();
public static final BlockEntityEntry<DistillationControllerBlockEntity> CAST_IRON_DISTILLATION_CONTROLLER = REGISTRATE
.blockEntity("distiller_controller", DistillationControllerBlockEntity::new)
public static final BlockEntityEntry<DistilleryControllerBlockEntity> CAST_IRON_DISTILLATION_CONTROLLER = REGISTRATE
.blockEntity("distiller_controller", DistilleryControllerBlockEntity::new)
.validBlocks(TFMGBlocks.CAST_IRON_DISTILLATION_CONTROLLER)
.register();

View File

@@ -10,8 +10,8 @@ import com.drmangotea.tfmg.content.gadgets.explosives.napalm.NapalmBombBlock;
import com.drmangotea.tfmg.content.items.CoalCokeBlockItem;
import com.drmangotea.tfmg.content.items.FossilstoneItem;
import com.drmangotea.tfmg.content.deposits.surface_scanner.SurfaceScannerBlock;
import com.drmangotea.tfmg.content.machines.oil_processing.distillation.DistillationControllerBlock;
import com.drmangotea.tfmg.content.machines.oil_processing.distillation.DistillationOutputBlock;
import com.drmangotea.tfmg.content.machines.oil_processing.distillation.distillery.DistilleryControllerBlock;
import com.drmangotea.tfmg.content.machines.oil_processing.distillation.distillery.DistilleryOutputBlock;
import com.drmangotea.tfmg.content.machines.pipes.normal.steel.EncasedSteelPipeBlock;
import com.drmangotea.tfmg.content.machines.pipes.normal.steel.GlassSteelPipeBlock;
import com.drmangotea.tfmg.content.machines.pipes.normal.steel.SteelPipeAttachmentModel;
@@ -239,8 +239,8 @@ public class TFMGBlocks {
//Distillation
public static final BlockEntry<DistillationOutputBlock> CAST_IRON_DISTILLATION_OUTPUT =
REGISTRATE.block("cast_iron_distillation_output", DistillationOutputBlock::new)
public static final BlockEntry<DistilleryOutputBlock> CAST_IRON_DISTILLATION_OUTPUT =
REGISTRATE.block("cast_iron_distillation_output", DistilleryOutputBlock::new)
.initialProperties(SharedProperties::copperMetal)
.properties(p -> p.color(MaterialColor.STONE))
.properties(BlockBehaviour.Properties::noOcclusion)
@@ -248,12 +248,15 @@ public class TFMGBlocks {
.item(AssemblyOperatorBlockItem::new)
.build()
.register();
public static final BlockEntry<DistillationControllerBlock> CAST_IRON_DISTILLATION_CONTROLLER =
REGISTRATE.block("cast_iron_distillation_controller", DistillationControllerBlock::new)
public static final BlockEntry<DistilleryControllerBlock> CAST_IRON_DISTILLATION_CONTROLLER =
REGISTRATE.block("cast_iron_distillation_controller", DistilleryControllerBlock::new)
.initialProperties(SharedProperties::copperMetal)
.item()
.build()
.register();
//
//////

View File

@@ -3,6 +3,7 @@ package com.drmangotea.tfmg.registry;
import com.drmangotea.tfmg.CreateTFMG;
import com.drmangotea.tfmg.recipes.distillation.DistillationRecipe;
import com.drmangotea.tfmg.recipes.distillation.advanced.AdvancedDistillationRecipe;
import com.google.common.collect.ImmutableSet;
import com.simibubi.create.content.processing.recipe.ProcessingRecipeBuilder.ProcessingRecipeFactory;
import com.simibubi.create.content.processing.recipe.ProcessingRecipeSerializer;
@@ -28,7 +29,8 @@ import java.util.function.Supplier;
public enum TFMGRecipeTypes implements IRecipeTypeInfo {
DISTILLATION(DistillationRecipe::new);
DISTILLATION(DistillationRecipe::new),
ADVANCED_DISTILLATION(AdvancedDistillationRecipe::new);
private final ResourceLocation id;
private final RegistryObject<RecipeSerializer<?>> serializerObject;

View File

@@ -1,210 +0,0 @@
package com.drmangotea.tfmg.content.machines.oil_processing.distillation.backup;
import com.drmangotea.tfmg.registry.TFMGBlockEntities;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllShapes;
import com.simibubi.create.Create;
import com.simibubi.create.content.equipment.wrench.IWrenchable;
import com.simibubi.create.content.fluids.transfer.GenericItemEmptying;
import com.simibubi.create.content.fluids.transfer.GenericItemFilling;
import com.simibubi.create.content.kinetics.belt.BeltBlockEntity;
import com.simibubi.create.content.kinetics.belt.behaviour.DirectBeltInputBehaviour;
import com.simibubi.create.content.logistics.funnel.FunnelBlock;
import com.simibubi.create.content.processing.basin.BasinOperatingBlockEntity;
import com.simibubi.create.foundation.block.IBE;
import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour;
import com.simibubi.create.foundation.fluid.FluidHelper;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.StateDefinition;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.world.level.block.state.properties.DirectionProperty;
import net.minecraft.world.level.pathfinder.PathComputationType;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.EntityCollisionContext;
import net.minecraft.world.phys.shapes.VoxelShape;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
import net.minecraftforge.fluids.capability.IFluidHandler;
import net.minecraftforge.items.IItemHandlerModifiable;
import net.minecraftforge.items.ItemStackHandler;
public class DistillationControllerBlock extends Block implements IBE<DistillationControllerBlockEntity>, IWrenchable {
public static final DirectionProperty FACING = BlockStateProperties.FACING_HOPPER;
public DistillationControllerBlock(Properties p_i48440_1_) {
super(p_i48440_1_);
registerDefaultState(defaultBlockState().setValue(FACING, Direction.DOWN));
}
@Override
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> p_206840_1_) {
super.createBlockStateDefinition(p_206840_1_.add(FACING));
}
@Override
public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) {
BlockEntity tileEntity = world.getBlockEntity(pos.above());
if (tileEntity instanceof BasinOperatingBlockEntity)
return false;
return true;
}
@Override
public InteractionResult use(BlockState state, Level worldIn, BlockPos pos, Player player, InteractionHand handIn,
BlockHitResult hit) {
ItemStack heldItem = player.getItemInHand(handIn);
return onBlockEntityUse(worldIn, pos, te -> {
if (!heldItem.isEmpty()) {
if (FluidHelper.tryEmptyItemIntoBE(worldIn, player, handIn, heldItem, te))
return InteractionResult.SUCCESS;
if (FluidHelper.tryFillItemFromBE(worldIn, player, handIn, heldItem, te))
return InteractionResult.SUCCESS;
if (GenericItemEmptying.canItemBeEmptied(worldIn, heldItem)
|| GenericItemFilling.canItemBeFilled(worldIn, heldItem))
return InteractionResult.SUCCESS;
if (heldItem.getItem()
.equals(Items.SPONGE)
&& !te.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY)
.map(iFluidHandler -> iFluidHandler.drain(Integer.MAX_VALUE, IFluidHandler.FluidAction.EXECUTE))
.orElse(FluidStack.EMPTY)
.isEmpty()) {
return InteractionResult.SUCCESS;
}
return InteractionResult.PASS;
}
IItemHandlerModifiable inv = te.itemCapability.orElse(new ItemStackHandler(1));
boolean success = false;
for (int slot = 0; slot < inv.getSlots(); slot++) {
ItemStack stackInSlot = inv.getStackInSlot(slot);
if (stackInSlot.isEmpty())
continue;
player.getInventory()
.placeItemBackInInventory(stackInSlot);
inv.setStackInSlot(slot, ItemStack.EMPTY);
success = true;
}
if (success)
worldIn.playSound(null, pos, SoundEvents.ITEM_PICKUP, SoundSource.PLAYERS, .2f,
1f + Create.RANDOM.nextFloat());
te.onEmptied();
return InteractionResult.SUCCESS;
});
}
@Override
public void updateEntityAfterFallOn(BlockGetter worldIn, Entity entityIn) {
super.updateEntityAfterFallOn(worldIn, entityIn);
if (!AllBlocks.BASIN.has(worldIn.getBlockState(entityIn.blockPosition())))
return;
if (!(entityIn instanceof ItemEntity))
return;
if (!entityIn.isAlive())
return;
ItemEntity itemEntity = (ItemEntity) entityIn;
withBlockEntityDo(worldIn, entityIn.blockPosition(), te -> {
// Tossed items bypass the quarter-stack limit
});
}
@Override
public VoxelShape getInteractionShape(BlockState p_199600_1_, BlockGetter p_199600_2_, BlockPos p_199600_3_) {
return AllShapes.BASIN_RAYTRACE_SHAPE;
}
@Override
public VoxelShape getShape(BlockState state, BlockGetter worldIn, BlockPos pos, CollisionContext context) {
return AllShapes.BASIN_BLOCK_SHAPE;
}
@Override
public VoxelShape getCollisionShape(BlockState state, BlockGetter reader, BlockPos pos, CollisionContext ctx) {
if (ctx instanceof EntityCollisionContext && ((EntityCollisionContext) ctx).getEntity() instanceof ItemEntity)
return AllShapes.BASIN_COLLISION_SHAPE;
return getShape(state, reader, pos, ctx);
}
@Override
public void onRemove(BlockState state, Level worldIn, BlockPos pos, BlockState newState, boolean isMoving) {
IBE.onRemove(state, worldIn, pos, newState);
}
@Override
public boolean hasAnalogOutputSignal(BlockState state) {
return true;
}
@Override
public Class<DistillationControllerBlockEntity> getBlockEntityClass() {
return DistillationControllerBlockEntity.class;
}
@Override
public BlockEntityType<? extends DistillationControllerBlockEntity> getBlockEntityType() {
return TFMGBlockEntities.CAST_IRON_DISTILLATION_CONTROLLER.get();
}
public static boolean canOutputTo(BlockGetter world, BlockPos basinPos, Direction direction) {
BlockPos neighbour = basinPos.relative(direction);
BlockPos output = neighbour.below();
BlockState blockState = world.getBlockState(neighbour);
if (FunnelBlock.isFunnel(blockState)) {
if (FunnelBlock.getFunnelFacing(blockState) == direction)
return false;
} else if (!blockState.getCollisionShape(world, neighbour)
.isEmpty()) {
return false;
} else {
BlockEntity tileEntity = world.getBlockEntity(output);
if (tileEntity instanceof BeltBlockEntity) {
BeltBlockEntity belt = (BeltBlockEntity) tileEntity;
return belt.getSpeed() == 0 || belt.getMovementFacing() != direction.getOpposite();
}
}
DirectBeltInputBehaviour directBeltInputBehaviour =
BlockEntityBehaviour.get(world, output, DirectBeltInputBehaviour.TYPE);
if (directBeltInputBehaviour != null)
return directBeltInputBehaviour.canInsertFromSide(direction);
return false;
}
@Override
public boolean isPathfindable(BlockState state, BlockGetter reader, BlockPos pos, PathComputationType type) {
return false;
}
}

View File

@@ -1,588 +0,0 @@
package com.drmangotea.tfmg.content.machines.oil_processing.distillation.backup;
import com.google.common.collect.ImmutableList;
import com.simibubi.create.AllTags;
import com.simibubi.create.content.equipment.goggles.IHaveGoggleInformation;
import com.simibubi.create.content.kinetics.belt.behaviour.DirectBeltInputBehaviour;
import com.simibubi.create.content.processing.burner.BlazeBurnerBlock;
import com.simibubi.create.foundation.blockEntity.SmartBlockEntity;
import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour;
import com.simibubi.create.foundation.blockEntity.behaviour.ValueBoxTransform;
import com.simibubi.create.foundation.blockEntity.behaviour.filtering.FilteringBehaviour;
import com.simibubi.create.foundation.blockEntity.behaviour.fluid.SmartFluidTankBehaviour;
import com.simibubi.create.foundation.blockEntity.behaviour.inventory.InvManipulationBehaviour;
import com.simibubi.create.foundation.fluid.CombinedTankWrapper;
import com.simibubi.create.foundation.item.SmartInventory;
import com.simibubi.create.foundation.utility.*;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag;
import net.minecraft.nbt.StringTag;
import net.minecraft.nbt.Tag;
import net.minecraft.network.chat.Component;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
import net.minecraftforge.fluids.capability.IFluidHandler;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.IItemHandlerModifiable;
import net.minecraftforge.items.ItemHandlerHelper;
import net.minecraftforge.items.wrapper.CombinedInvWrapper;
import javax.annotation.Nonnull;
import java.util.*;
public class DistillationControllerBlockEntity extends SmartBlockEntity implements IHaveGoggleInformation {
public SmartFluidTankBehaviour inputTank;
protected SmartInventory outputInventory;
protected SmartFluidTankBehaviour outputTank;
private boolean contentsChanged;
private Couple<SmartFluidTankBehaviour> tanks;
public LazyOptional<IItemHandlerModifiable> itemCapability;
protected LazyOptional<IFluidHandler> fluidCapability;
List<Direction> disabledSpoutputs;
Direction preferredSpoutput;
protected List<ItemStack> spoutputBuffer;
protected List<FluidStack> spoutputFluidBuffer;
int recipeBackupCheck;
public static final int OUTPUT_ANIMATION_TIME = 10;
List<IntAttached<ItemStack>> visualizedOutputItems;
List<IntAttached<FluidStack>> visualizedOutputFluids;
public DistillationControllerBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
super(type, pos, state);
outputInventory = new SmartInventory(9, this).forbidInsertion()
.withMaxStackSize(64);
itemCapability = LazyOptional.of(() -> new CombinedInvWrapper( outputInventory));
contentsChanged = true;
tanks = Couple.create(inputTank, outputTank);
visualizedOutputItems = Collections.synchronizedList(new ArrayList<>());
visualizedOutputFluids = Collections.synchronizedList(new ArrayList<>());
disabledSpoutputs = new ArrayList<>();
preferredSpoutput = null;
spoutputBuffer = new ArrayList<>();
spoutputFluidBuffer = new ArrayList<>();
recipeBackupCheck = 20;
}
@Override
public void addBehaviours(List<BlockEntityBehaviour> behaviours) {
behaviours.add(new DirectBeltInputBehaviour(this));
inputTank = new SmartFluidTankBehaviour(SmartFluidTankBehaviour.INPUT, this, 2, 1000, true)
.whenFluidUpdates(() -> contentsChanged = true);
outputTank = new SmartFluidTankBehaviour(SmartFluidTankBehaviour.OUTPUT, this, 2, 1000, true)
.whenFluidUpdates(() -> contentsChanged = true)
.forbidInsertion();
behaviours.add(inputTank);
behaviours.add(outputTank);
fluidCapability = LazyOptional.of(() -> {
LazyOptional<? extends IFluidHandler> inputCap = inputTank.getCapability();
LazyOptional<? extends IFluidHandler> outputCap = outputTank.getCapability();
return new CombinedTankWrapper(outputCap.orElse(null), inputCap.orElse(null));
});
}
@Override
protected void read(CompoundTag compound, boolean clientPacket) {
super.read(compound, clientPacket);
outputInventory.deserializeNBT(compound.getCompound("OutputItems"));
preferredSpoutput = null;
if (compound.contains("PreferredSpoutput"))
preferredSpoutput = NBTHelper.readEnum(compound, "PreferredSpoutput", Direction.class);
disabledSpoutputs.clear();
ListTag disabledList = compound.getList("DisabledSpoutput", Tag.TAG_STRING);
disabledList.forEach(d -> disabledSpoutputs.add(Direction.valueOf(((StringTag) d).getAsString())));
spoutputBuffer = NBTHelper.readItemList(compound.getList("Overflow", Tag.TAG_COMPOUND));
spoutputFluidBuffer = NBTHelper.readCompoundList(compound.getList("FluidOverflow", Tag.TAG_COMPOUND),
FluidStack::loadFluidStackFromNBT);
if (!clientPacket)
return;
NBTHelper.iterateCompoundList(compound.getList("VisualizedItems", Tag.TAG_COMPOUND),
c -> visualizedOutputItems.add(IntAttached.with(OUTPUT_ANIMATION_TIME, ItemStack.of(c))));
NBTHelper.iterateCompoundList(compound.getList("VisualizedFluids", Tag.TAG_COMPOUND),
c -> visualizedOutputFluids
.add(IntAttached.with(OUTPUT_ANIMATION_TIME, FluidStack.loadFluidStackFromNBT(c))));
}
@Override
public void write(CompoundTag compound, boolean clientPacket) {
super.write(compound, clientPacket);
compound.put("OutputItems", outputInventory.serializeNBT());
if (preferredSpoutput != null)
NBTHelper.writeEnum(compound, "PreferredSpoutput", preferredSpoutput);
ListTag disabledList = new ListTag();
disabledSpoutputs.forEach(d -> disabledList.add(StringTag.valueOf(d.name())));
compound.put("DisabledSpoutput", disabledList);
compound.put("Overflow", NBTHelper.writeItemList(spoutputBuffer));
compound.put("FluidOverflow",
NBTHelper.writeCompoundList(spoutputFluidBuffer, fs -> fs.writeToNBT(new CompoundTag())));
if (!clientPacket)
return;
compound.put("VisualizedItems", NBTHelper.writeCompoundList(visualizedOutputItems, ia -> ia.getValue()
.serializeNBT()));
compound.put("VisualizedFluids", NBTHelper.writeCompoundList(visualizedOutputFluids, ia -> ia.getValue()
.writeToNBT(new CompoundTag())));
visualizedOutputItems.clear();
visualizedOutputFluids.clear();
}
/*
@Override
public void destroy() {
super.destroy();
ItemHelper.dropContents(level, worldPosition, outputInventory);
spoutputBuffer.forEach(is -> Block.popResource(level, worldPosition, is));
}
*/
@Override
public void remove() {
super.remove();
onEmptied();
}
public void onEmptied() {
getOperator().ifPresent(te -> te.basinRemoved = true);
}
@Override
public void invalidate() {
super.invalidate();
itemCapability.invalidate();
fluidCapability.invalidate();
}
@Nonnull
@Override
public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, Direction side) {
if (cap == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY)
return itemCapability.cast();
if (cap == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY)
return fluidCapability.cast();
return super.getCapability(cap, side);
}
@Override
public void notifyUpdate() {
super.notifyUpdate();
}
@Override
public void lazyTick() {
super.lazyTick();
notifyUpdate();
if (!level.isClientSide) {
updateSpoutput();
if (recipeBackupCheck-- > 0)
return;
recipeBackupCheck = 20;
}
}
private void updateSpoutput() {
BlockState blockState = getBlockState();
Direction currentFacing = blockState.getValue(DistillationControllerBlock.FACING);
Direction newFacing = Direction.DOWN;
for (Direction test : Iterate.horizontalDirections) {
boolean canOutputTo = DistillationControllerBlock.canOutputTo(level, worldPosition, test);
if (canOutputTo && !disabledSpoutputs.contains(test))
newFacing = test;
}
if (preferredSpoutput != null && DistillationControllerBlock.canOutputTo(level, worldPosition, preferredSpoutput)
&& preferredSpoutput != Direction.UP)
newFacing = preferredSpoutput;
if (newFacing == currentFacing)
return;
level.setBlockAndUpdate(worldPosition, blockState.setValue(DistillationControllerBlock.FACING, newFacing));
if (newFacing.getAxis()
.isVertical())
return;
for (int slot = 0; slot < outputInventory.getSlots(); slot++) {
ItemStack extractItem = outputInventory.extractItem(slot, 64, true);
if (extractItem.isEmpty())
continue;
if (acceptOutputs(ImmutableList.of(extractItem), Collections.emptyList(), true))
acceptOutputs(ImmutableList.of(outputInventory.extractItem(slot, 64, false)), Collections.emptyList(),
false);
}
IFluidHandler handler = outputTank.getCapability()
.orElse(null);
for (int slot = 0; slot < handler.getTanks(); slot++) {
FluidStack fs = handler.getFluidInTank(slot)
.copy();
if (fs.isEmpty())
continue;
if (acceptOutputs(Collections.emptyList(), ImmutableList.of(fs), true)) {
handler.drain(fs, IFluidHandler.FluidAction.EXECUTE);
acceptOutputs(Collections.emptyList(), ImmutableList.of(fs), false);
}
}
notifyChangeOfContents();
notifyUpdate();
}
@Override
public void tick() {
super.tick();
if (level.isClientSide) {
tickVisualizedOutputs();
}
if ((!spoutputBuffer.isEmpty() || !spoutputFluidBuffer.isEmpty()) && !level.isClientSide)
tryClearingSpoutputOverflow();
if (!contentsChanged)
return;
contentsChanged = false;
getOperator().ifPresent(te -> te.basinChecker.scheduleUpdate());
for (Direction offset : Iterate.horizontalDirections) {
BlockPos toUpdate = worldPosition.above()
.relative(offset);
BlockState stateToUpdate = level.getBlockState(toUpdate);
if (stateToUpdate.getBlock() instanceof DistillationControllerBlock
&& stateToUpdate.getValue(DistillationControllerBlock.FACING) == offset.getOpposite()) {
BlockEntity te = level.getBlockEntity(toUpdate);
if (te instanceof DistillationControllerBlockEntity)
((DistillationControllerBlockEntity) te).contentsChanged = true;
}
}
}
private void tryClearingSpoutputOverflow() {
BlockState blockState = getBlockState();
if (!(blockState.getBlock() instanceof DistillationControllerBlock))
return;
Direction direction = blockState.getValue(DistillationControllerBlock.FACING);
BlockEntity te = level.getBlockEntity(worldPosition.below()
.relative(direction));
FilteringBehaviour filter = null;
InvManipulationBehaviour inserter = null;
if (te != null) {
filter = BlockEntityBehaviour.get(level, te.getBlockPos(), FilteringBehaviour.TYPE);
inserter = BlockEntityBehaviour.get(level, te.getBlockPos(), InvManipulationBehaviour.TYPE);
}
IItemHandler targetInv = te == null ? null
: te.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, direction.getOpposite())
.orElse(inserter == null ? null : inserter.getInventory());
IFluidHandler targetTank = te == null ? null
: te.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, direction.getOpposite())
.orElse(null);
boolean update = false;
for (Iterator<ItemStack> iterator = spoutputBuffer.iterator(); iterator.hasNext();) {
ItemStack itemStack = iterator.next();
if (direction == Direction.DOWN) {
Block.popResource(level, worldPosition, itemStack);
iterator.remove();
update = true;
continue;
}
if (targetInv == null)
break;
if (!ItemHandlerHelper.insertItemStacked(targetInv, itemStack, true)
.isEmpty())
continue;
// if (filter != null && !filter.test(itemStack))
// continue;
update = true;
ItemHandlerHelper.insertItemStacked(targetInv, itemStack.copy(), false);
iterator.remove();
visualizedOutputItems.add(IntAttached.withZero(itemStack));
}
for (Iterator<FluidStack> iterator = spoutputFluidBuffer.iterator(); iterator.hasNext();) {
FluidStack fluidStack = iterator.next();
if (direction == Direction.DOWN) {
iterator.remove();
update = true;
continue;
}
if (targetTank == null)
break;
for (boolean simulate : Iterate.trueAndFalse) {
IFluidHandler.FluidAction action = simulate ? IFluidHandler.FluidAction.SIMULATE : IFluidHandler.FluidAction.EXECUTE;
int fill = targetTank instanceof SmartFluidTankBehaviour.InternalFluidHandler
? ((SmartFluidTankBehaviour.InternalFluidHandler) targetTank).forceFill(fluidStack.copy(), action)
: targetTank.fill(fluidStack.copy(), action);
if (fill != fluidStack.getAmount())
break;
if (simulate)
continue;
update = true;
iterator.remove();
visualizedOutputFluids.add(IntAttached.withZero(fluidStack));
}
}
if (update) {
notifyChangeOfContents();
sendData();
}
}
public float getTotalFluidUnits(float partialTicks) {
int renderedFluids = 0;
float totalUnits = 0;
for (SmartFluidTankBehaviour behaviour : getTanks()) {
if (behaviour == null)
continue;
for (SmartFluidTankBehaviour.TankSegment tankSegment : behaviour.getTanks()) {
if (tankSegment.getRenderedFluid()
.isEmpty())
continue;
float units = tankSegment.getTotalUnits(partialTicks);
if (units < 1)
continue;
totalUnits += units;
renderedFluids++;
}
}
if (renderedFluids == 0)
return 0;
if (totalUnits < 1)
return 0;
return totalUnits;
}
private Optional<FluidProcessingBlockEntity> getOperator() {
if (level == null)
return Optional.empty();
BlockEntity te = level.getBlockEntity(worldPosition.above());
if (te instanceof FluidProcessingBlockEntity)
return Optional.of((FluidProcessingBlockEntity) te);
return Optional.empty();
}
public void notifyChangeOfContents() {
contentsChanged = true;
}
public SmartInventory getOutputInventory() {
return outputInventory;
}
public boolean canContinueProcessing() {
return spoutputBuffer.isEmpty() && spoutputFluidBuffer.isEmpty();
}
public boolean acceptOutputs(List<ItemStack> outputItems, List<FluidStack> outputFluids, boolean simulate) {
outputInventory.allowInsertion();
outputTank.allowInsertion();
boolean acceptOutputsInner = acceptOutputsInner(outputItems, outputFluids, simulate);
outputInventory.forbidInsertion();
outputTank.forbidInsertion();
return acceptOutputsInner;
}
private boolean acceptOutputsInner(List<ItemStack> outputItems, List<FluidStack> outputFluids, boolean simulate) {
BlockState blockState = getBlockState();
if (!(blockState.getBlock() instanceof DistillationControllerBlock))
return false;
Direction direction = blockState.getValue(DistillationControllerBlock.FACING);
if (direction != Direction.DOWN) {
BlockEntity te = level.getBlockEntity(worldPosition.below()
.relative(direction));
InvManipulationBehaviour inserter =
te == null ? null : BlockEntityBehaviour.get(level, te.getBlockPos(), InvManipulationBehaviour.TYPE);
IItemHandler targetInv = te == null ? null
: te.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, direction.getOpposite())
.orElse(inserter == null ? null : inserter.getInventory());
IFluidHandler targetTank = te == null ? null
: te.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, direction.getOpposite())
.orElse(null);
boolean externalTankNotPresent = targetTank == null;
if (!outputItems.isEmpty() && targetInv == null)
return false;
if (!outputFluids.isEmpty() && externalTankNotPresent) {
// Special case - fluid outputs but output only accepts items
targetTank = outputTank.getCapability()
.orElse(null);
if (targetTank == null)
return false;
if (!acceptFluidOutputsIntoBasin(outputFluids, simulate, targetTank))
return false;
}
if (simulate)
return true;
for (ItemStack itemStack : outputItems) {
if (itemStack.hasCraftingRemainingItem() && itemStack.getCraftingRemainingItem()
.sameItem(itemStack))
continue;
spoutputBuffer.add(itemStack.copy());
}
if (!externalTankNotPresent)
for (FluidStack fluidStack : outputFluids)
spoutputFluidBuffer.add(fluidStack.copy());
return true;
}
IItemHandler targetInv = outputInventory;
IFluidHandler targetTank = outputTank.getCapability()
.orElse(null);
if (targetInv == null && !outputItems.isEmpty())
return false;
if (!acceptItemOutputsIntoBasin(outputItems, simulate, targetInv))
return false;
if (outputFluids.isEmpty())
return true;
if (targetTank == null)
return false;
if (!acceptFluidOutputsIntoBasin(outputFluids, simulate, targetTank))
return false;
return true;
}
private boolean acceptFluidOutputsIntoBasin(List<FluidStack> outputFluids, boolean simulate,
IFluidHandler targetTank) {
for (FluidStack fluidStack : outputFluids) {
IFluidHandler.FluidAction action = simulate ? IFluidHandler.FluidAction.SIMULATE : IFluidHandler.FluidAction.EXECUTE;
int fill = targetTank instanceof SmartFluidTankBehaviour.InternalFluidHandler
? ((SmartFluidTankBehaviour.InternalFluidHandler) targetTank).forceFill(fluidStack.copy(), action)
: targetTank.fill(fluidStack.copy(), action);
if (fill != fluidStack.getAmount())
return false;
}
return true;
}
private boolean acceptItemOutputsIntoBasin(List<ItemStack> outputItems, boolean simulate, IItemHandler targetInv) {
for (ItemStack itemStack : outputItems) {
// Catalyst items are never consumed
if (itemStack.hasCraftingRemainingItem() && itemStack.getCraftingRemainingItem()
.sameItem(itemStack))
continue;
if (!ItemHandlerHelper.insertItemStacked(targetInv, itemStack.copy(), simulate)
.isEmpty())
return false;
}
return true;
}
public void readOnlyItems(CompoundTag compound) {
outputInventory.deserializeNBT(compound.getCompound("OutputItems"));
}
public static BlazeBurnerBlock.HeatLevel getHeatLevelOf(BlockState state) {
if (state.hasProperty(BlazeBurnerBlock.HEAT_LEVEL))
return state.getValue(BlazeBurnerBlock.HEAT_LEVEL);
return AllTags.AllBlockTags.PASSIVE_BOILER_HEATERS.matches(state) ? BlazeBurnerBlock.HeatLevel.SMOULDERING : BlazeBurnerBlock.HeatLevel.NONE;
}
public Couple<SmartFluidTankBehaviour> getTanks() {
return tanks;
}
// client things
private void tickVisualizedOutputs() {
visualizedOutputFluids.forEach(IntAttached::decrement);
visualizedOutputItems.forEach(IntAttached::decrement);
visualizedOutputFluids.removeIf(IntAttached::isOrBelowZero);
visualizedOutputItems.removeIf(IntAttached::isOrBelowZero);
}
@Override
public boolean addToGoggleTooltip(List<Component> tooltip, boolean isPlayerSneaking) {
return containedFluidTooltip(tooltip, isPlayerSneaking,
getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY));
}
class BasinValueBox extends ValueBoxTransform.Sided {
@Override
protected Vec3 getSouthLocation() {
return VecHelper.voxelSpace(8, 12, 15.75);
}
@Override
protected boolean isSideActive(BlockState state, Direction direction) {
return direction.getAxis()
.isHorizontal();
}
}
}

View File

@@ -1,57 +0,0 @@
package com.drmangotea.tfmg.content.machines.oil_processing.distillation.backup;
import com.drmangotea.tfmg.registry.TFMGBlockEntities;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllShapes;
import com.simibubi.create.foundation.block.IBE;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.pathfinder.PathComputationType;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.EntityCollisionContext;
import net.minecraft.world.phys.shapes.VoxelShape;
public class DistillationOutputBlock extends Block implements IBE<DistillationOutputBlockEntity> {
public DistillationOutputBlock(Properties properties) {
super(properties);
}
@Override
public boolean canSurvive(BlockState state, LevelReader worldIn, BlockPos pos) {
return !AllBlocks.BASIN.has(worldIn.getBlockState(pos.below()));
}
@Override
public VoxelShape getShape(BlockState state, BlockGetter worldIn, BlockPos pos, CollisionContext context) {
if (context instanceof EntityCollisionContext
&& ((EntityCollisionContext) context).getEntity() instanceof Player)
return AllShapes.CASING_14PX.get(Direction.DOWN);
return AllShapes.MECHANICAL_PROCESSOR_SHAPE;
}
@Override
public Class<DistillationOutputBlockEntity> getBlockEntityClass() {
return DistillationOutputBlockEntity.class;
}
@Override
public BlockEntityType<? extends DistillationOutputBlockEntity> getBlockEntityType() {
return TFMGBlockEntities.CAST_IRON_DISTILLATION_OUTPUT.get();
}
@Override
public boolean isPathfindable(BlockState state, BlockGetter reader, BlockPos pos, PathComputationType type) {
return false;
}
}

View File

@@ -1,156 +0,0 @@
package com.drmangotea.tfmg.content.machines.oil_processing.distillation.backup;
import com.drmangotea.tfmg.recipes.distillation.ItemlessRecipe;
import com.simibubi.create.content.kinetics.base.KineticBlockEntity;
import com.simibubi.create.foundation.advancement.CreateAdvancement;
import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour;
import com.simibubi.create.foundation.blockEntity.behaviour.simple.DeferralBehaviour;
import com.simibubi.create.foundation.recipe.RecipeFinder;
import net.minecraft.core.BlockPos;
import net.minecraft.world.Container;
import net.minecraft.world.item.crafting.Recipe;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
public abstract class FluidProcessingBlockEntity extends KineticBlockEntity {
public DeferralBehaviour basinChecker;
public boolean basinRemoved;
protected Recipe<?> currentRecipe;
public FluidProcessingBlockEntity(BlockEntityType<?> typeIn, BlockPos pos, BlockState state) {
super(typeIn, pos, state);
}
@Override
public void addBehaviours(List<BlockEntityBehaviour> behaviours) {
super.addBehaviours(behaviours);
basinChecker = new DeferralBehaviour(this, this::updateController);
behaviours.add(basinChecker);
}
@Override
public void onSpeedChanged(float prevSpeed) {
super.onSpeedChanged(prevSpeed);
if (getSpeed() == 0)
basinRemoved = true;
basinRemoved = false;
basinChecker.scheduleUpdate();
}
@Override
public void tick() {
if (basinRemoved) {
basinRemoved = false;
onBasinRemoved();
sendData();
return;
}
super.tick();
}
protected boolean updateController() {
if (isRunning())
return true;
if (level == null || level.isClientSide)
return true;
Optional<DistillationControllerBlockEntity> basin = getController();
if (!basin.filter(DistillationControllerBlockEntity::canContinueProcessing)
.isPresent())
return true;
List<Recipe<?>> recipes = getMatchingRecipes();
if (recipes.isEmpty())
return true;
currentRecipe = recipes.get(0);
// if(currentRecipe instanceof DistillationRecipe) {
// if (((DistillationRecipe) currentRecipe).getInputFluid().getMatchingFluidStacks().get(0).getFluid() != TFMGFluids.HEAVY_OIL.get()) {
// return true;
// }
// }
startProcessing();
sendData();
return true;
}
protected abstract boolean isRunning();
public void startProcessing() {}
public boolean continueWithPreviousRecipe() {
return true;
}
protected <C extends Container> boolean matchItemlessRecipe(Recipe<C> recipe) {
if (recipe == null)
return false;
Optional<DistillationControllerBlockEntity> basin = getController();
if (!basin.isPresent())
return false;
return ItemlessRecipe.match(basin.get(), recipe);
}
protected void applyItemlessRecipe() {
if (currentRecipe == null)
return;
Optional<DistillationControllerBlockEntity> optionalBasin = getController();
if (!optionalBasin.isPresent())
return;
DistillationControllerBlockEntity basin = optionalBasin.get();
boolean wasEmpty = basin.canContinueProcessing();
if (!ItemlessRecipe.apply(basin, currentRecipe))
return;
getProcessedRecipeTrigger().ifPresent(this::award);
basin.inputTank.sendDataImmediately();
// Continue mixing
if (wasEmpty && matchItemlessRecipe(currentRecipe)) {
continueWithPreviousRecipe();
sendData();
}
basin.notifyChangeOfContents();
}
protected List<Recipe<?>> getMatchingRecipes() {
List<Recipe<?>> list = RecipeFinder.get(getRecipeCacheKey(), level, this::matchStaticFilters);
return list.stream()
.filter(this::matchItemlessRecipe)
.sorted((r1, r2) -> r2.getIngredients()
.size()
- r1.getIngredients()
.size())
.collect(Collectors.toList());
}
protected abstract void onBasinRemoved();
protected Optional<DistillationControllerBlockEntity> getController() {
if (level == null)
return Optional.empty();
BlockEntity basinTE = level.getBlockEntity(worldPosition.below(1));
if (!(basinTE instanceof DistillationControllerBlockEntity))
return Optional.empty();
return Optional.of((DistillationControllerBlockEntity) basinTE);
}
protected Optional<CreateAdvancement> getProcessedRecipeTrigger() {
return Optional.empty();
}
protected abstract <C extends Container> boolean matchStaticFilters(Recipe<C> recipe);
protected abstract Object getRecipeCacheKey();
}