distillery
This commit is contained in:
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"type": "minecraft:stonecutting",
|
||||
"count": 1,
|
||||
"ingredient": {
|
||||
"tag": "tfmg:stone_types/bauxite"
|
||||
},
|
||||
"result": "tfmg:bauxite"
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"type": "minecraft:stonecutting",
|
||||
"count": 1,
|
||||
"ingredient": {
|
||||
"tag": "tfmg:stone_types/bauxite"
|
||||
},
|
||||
"result": "tfmg:bauxite_pillar"
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
{
|
||||
"type": "minecraft:crafting_shaped",
|
||||
"group": "cut_bauxite_brick_slab",
|
||||
"key": {
|
||||
"X": {
|
||||
"item": "tfmg:cut_bauxite_bricks"
|
||||
}
|
||||
},
|
||||
"pattern": [
|
||||
"XXX"
|
||||
],
|
||||
"result": {
|
||||
"count": 6,
|
||||
"item": "tfmg:cut_bauxite_brick_slab"
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"type": "minecraft:stonecutting",
|
||||
"count": 2,
|
||||
"ingredient": {
|
||||
"tag": "tfmg:stone_types/bauxite"
|
||||
},
|
||||
"result": "tfmg:cut_bauxite_brick_slab"
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
{
|
||||
"type": "minecraft:crafting_shapeless",
|
||||
"ingredients": [
|
||||
{
|
||||
"item": "tfmg:cut_bauxite_brick_slab"
|
||||
},
|
||||
{
|
||||
"item": "tfmg:cut_bauxite_brick_slab"
|
||||
}
|
||||
],
|
||||
"result": {
|
||||
"item": "tfmg:cut_bauxite_bricks"
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
{
|
||||
"type": "minecraft:crafting_shaped",
|
||||
"group": "cut_bauxite_brick_stairs",
|
||||
"key": {
|
||||
"X": {
|
||||
"item": "tfmg:cut_bauxite_bricks"
|
||||
}
|
||||
},
|
||||
"pattern": [
|
||||
"X ",
|
||||
"XX ",
|
||||
"XXX"
|
||||
],
|
||||
"result": {
|
||||
"count": 4,
|
||||
"item": "tfmg:cut_bauxite_brick_stairs"
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"type": "minecraft:stonecutting",
|
||||
"count": 1,
|
||||
"ingredient": {
|
||||
"tag": "tfmg:stone_types/bauxite"
|
||||
},
|
||||
"result": "tfmg:cut_bauxite_brick_stairs"
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
{
|
||||
"type": "minecraft:crafting_shaped",
|
||||
"key": {
|
||||
"X": {
|
||||
"item": "tfmg:cut_bauxite_bricks"
|
||||
}
|
||||
},
|
||||
"pattern": [
|
||||
"XXX",
|
||||
"XXX"
|
||||
],
|
||||
"result": {
|
||||
"count": 6,
|
||||
"item": "tfmg:cut_bauxite_brick_wall"
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"type": "minecraft:stonecutting",
|
||||
"count": 1,
|
||||
"ingredient": {
|
||||
"tag": "tfmg:stone_types/bauxite"
|
||||
},
|
||||
"result": "tfmg:cut_bauxite_brick_wall"
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"type": "minecraft:stonecutting",
|
||||
"count": 1,
|
||||
"ingredient": {
|
||||
"tag": "tfmg:stone_types/bauxite"
|
||||
},
|
||||
"result": "tfmg:cut_bauxite_bricks"
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"type": "minecraft:stonecutting",
|
||||
"count": 1,
|
||||
"ingredient": {
|
||||
"tag": "tfmg:stone_types/bauxite"
|
||||
},
|
||||
"result": "tfmg:cut_bauxite"
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
{
|
||||
"type": "minecraft:crafting_shaped",
|
||||
"group": "cut_bauxite_slab",
|
||||
"key": {
|
||||
"X": {
|
||||
"item": "tfmg:cut_bauxite"
|
||||
}
|
||||
},
|
||||
"pattern": [
|
||||
"XXX"
|
||||
],
|
||||
"result": {
|
||||
"count": 6,
|
||||
"item": "tfmg:cut_bauxite_slab"
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"type": "minecraft:stonecutting",
|
||||
"count": 2,
|
||||
"ingredient": {
|
||||
"tag": "tfmg:stone_types/bauxite"
|
||||
},
|
||||
"result": "tfmg:cut_bauxite_slab"
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
{
|
||||
"type": "minecraft:crafting_shapeless",
|
||||
"ingredients": [
|
||||
{
|
||||
"item": "tfmg:cut_bauxite_slab"
|
||||
},
|
||||
{
|
||||
"item": "tfmg:cut_bauxite_slab"
|
||||
}
|
||||
],
|
||||
"result": {
|
||||
"item": "tfmg:cut_bauxite"
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
{
|
||||
"type": "minecraft:crafting_shaped",
|
||||
"group": "cut_bauxite_stairs",
|
||||
"key": {
|
||||
"X": {
|
||||
"item": "tfmg:cut_bauxite"
|
||||
}
|
||||
},
|
||||
"pattern": [
|
||||
"X ",
|
||||
"XX ",
|
||||
"XXX"
|
||||
],
|
||||
"result": {
|
||||
"count": 4,
|
||||
"item": "tfmg:cut_bauxite_stairs"
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"type": "minecraft:stonecutting",
|
||||
"count": 1,
|
||||
"ingredient": {
|
||||
"tag": "tfmg:stone_types/bauxite"
|
||||
},
|
||||
"result": "tfmg:cut_bauxite_stairs"
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
{
|
||||
"type": "minecraft:crafting_shaped",
|
||||
"key": {
|
||||
"X": {
|
||||
"item": "tfmg:cut_bauxite"
|
||||
}
|
||||
},
|
||||
"pattern": [
|
||||
"XXX",
|
||||
"XXX"
|
||||
],
|
||||
"result": {
|
||||
"count": 6,
|
||||
"item": "tfmg:cut_bauxite_wall"
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"type": "minecraft:stonecutting",
|
||||
"count": 1,
|
||||
"ingredient": {
|
||||
"tag": "tfmg:stone_types/bauxite"
|
||||
},
|
||||
"result": "tfmg:cut_bauxite_wall"
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"type": "minecraft:stonecutting",
|
||||
"count": 1,
|
||||
"ingredient": {
|
||||
"tag": "tfmg:stone_types/bauxite"
|
||||
},
|
||||
"result": "tfmg:layered_bauxite"
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"type": "minecraft:stonecutting",
|
||||
"count": 1,
|
||||
"ingredient": {
|
||||
"tag": "tfmg:stone_types/bauxite"
|
||||
},
|
||||
"result": "tfmg:polished_cut_bauxite"
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
{
|
||||
"type": "minecraft:crafting_shaped",
|
||||
"group": "polished_cut_bauxite_slab",
|
||||
"key": {
|
||||
"X": {
|
||||
"item": "tfmg:polished_cut_bauxite"
|
||||
}
|
||||
},
|
||||
"pattern": [
|
||||
"XXX"
|
||||
],
|
||||
"result": {
|
||||
"count": 6,
|
||||
"item": "tfmg:polished_cut_bauxite_slab"
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"type": "minecraft:stonecutting",
|
||||
"count": 2,
|
||||
"ingredient": {
|
||||
"tag": "tfmg:stone_types/bauxite"
|
||||
},
|
||||
"result": "tfmg:polished_cut_bauxite_slab"
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
{
|
||||
"type": "minecraft:crafting_shapeless",
|
||||
"ingredients": [
|
||||
{
|
||||
"item": "tfmg:polished_cut_bauxite_slab"
|
||||
},
|
||||
{
|
||||
"item": "tfmg:polished_cut_bauxite_slab"
|
||||
}
|
||||
],
|
||||
"result": {
|
||||
"item": "tfmg:polished_cut_bauxite"
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
{
|
||||
"type": "minecraft:crafting_shaped",
|
||||
"group": "polished_cut_bauxite_stairs",
|
||||
"key": {
|
||||
"X": {
|
||||
"item": "tfmg:polished_cut_bauxite"
|
||||
}
|
||||
},
|
||||
"pattern": [
|
||||
"X ",
|
||||
"XX ",
|
||||
"XXX"
|
||||
],
|
||||
"result": {
|
||||
"count": 4,
|
||||
"item": "tfmg:polished_cut_bauxite_stairs"
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"type": "minecraft:stonecutting",
|
||||
"count": 1,
|
||||
"ingredient": {
|
||||
"tag": "tfmg:stone_types/bauxite"
|
||||
},
|
||||
"result": "tfmg:polished_cut_bauxite_stairs"
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
{
|
||||
"type": "minecraft:crafting_shaped",
|
||||
"key": {
|
||||
"X": {
|
||||
"item": "tfmg:polished_cut_bauxite"
|
||||
}
|
||||
},
|
||||
"pattern": [
|
||||
"XXX",
|
||||
"XXX"
|
||||
],
|
||||
"result": {
|
||||
"count": 6,
|
||||
"item": "tfmg:polished_cut_bauxite_wall"
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"type": "minecraft:stonecutting",
|
||||
"count": 1,
|
||||
"ingredient": {
|
||||
"tag": "tfmg:stone_types/bauxite"
|
||||
},
|
||||
"result": "tfmg:polished_cut_bauxite_wall"
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
{
|
||||
"type": "minecraft:crafting_shaped",
|
||||
"group": "small_bauxite_brick_slab",
|
||||
"key": {
|
||||
"X": {
|
||||
"item": "tfmg:small_bauxite_bricks"
|
||||
}
|
||||
},
|
||||
"pattern": [
|
||||
"XXX"
|
||||
],
|
||||
"result": {
|
||||
"count": 6,
|
||||
"item": "tfmg:small_bauxite_brick_slab"
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"type": "minecraft:stonecutting",
|
||||
"count": 2,
|
||||
"ingredient": {
|
||||
"tag": "tfmg:stone_types/bauxite"
|
||||
},
|
||||
"result": "tfmg:small_bauxite_brick_slab"
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
{
|
||||
"type": "minecraft:crafting_shapeless",
|
||||
"ingredients": [
|
||||
{
|
||||
"item": "tfmg:small_bauxite_brick_slab"
|
||||
},
|
||||
{
|
||||
"item": "tfmg:small_bauxite_brick_slab"
|
||||
}
|
||||
],
|
||||
"result": {
|
||||
"item": "tfmg:small_bauxite_bricks"
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
{
|
||||
"type": "minecraft:crafting_shaped",
|
||||
"group": "small_bauxite_brick_stairs",
|
||||
"key": {
|
||||
"X": {
|
||||
"item": "tfmg:small_bauxite_bricks"
|
||||
}
|
||||
},
|
||||
"pattern": [
|
||||
"X ",
|
||||
"XX ",
|
||||
"XXX"
|
||||
],
|
||||
"result": {
|
||||
"count": 4,
|
||||
"item": "tfmg:small_bauxite_brick_stairs"
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"type": "minecraft:stonecutting",
|
||||
"count": 1,
|
||||
"ingredient": {
|
||||
"tag": "tfmg:stone_types/bauxite"
|
||||
},
|
||||
"result": "tfmg:small_bauxite_brick_stairs"
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
{
|
||||
"type": "minecraft:crafting_shaped",
|
||||
"key": {
|
||||
"X": {
|
||||
"item": "tfmg:small_bauxite_bricks"
|
||||
}
|
||||
},
|
||||
"pattern": [
|
||||
"XXX",
|
||||
"XXX"
|
||||
],
|
||||
"result": {
|
||||
"count": 6,
|
||||
"item": "tfmg:small_bauxite_brick_wall"
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"type": "minecraft:stonecutting",
|
||||
"count": 1,
|
||||
"ingredient": {
|
||||
"tag": "tfmg:stone_types/bauxite"
|
||||
},
|
||||
"result": "tfmg:small_bauxite_brick_wall"
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"type": "minecraft:stonecutting",
|
||||
"count": 1,
|
||||
"ingredient": {
|
||||
"tag": "tfmg:stone_types/bauxite"
|
||||
},
|
||||
"result": "tfmg:small_bauxite_bricks"
|
||||
}
|
||||
@@ -54,8 +54,10 @@ public class CreateTFMG
|
||||
TFMGCreativeModeTabs.init();
|
||||
TFMGFluids.register();
|
||||
TFMGPaletteBlocks.register();
|
||||
|
||||
TFMGColoredFires.register(modEventBus);
|
||||
TFMGFeatures.register(modEventBus);
|
||||
TFMGRecipeTypes.register(modEventBus);
|
||||
|
||||
//
|
||||
modEventBus.addListener(EventPriority.LOWEST, CreateTFMG::gatherData);
|
||||
|
||||
@@ -0,0 +1,210 @@
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,358 @@
|
||||
package com.drmangotea.tfmg.content.machines.oil_processing.distillation;
|
||||
|
||||
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;
|
||||
|
||||
|
||||
int recipeBackupCheck;
|
||||
|
||||
|
||||
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);
|
||||
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"));
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(CompoundTag compound, boolean clientPacket) {
|
||||
super.write(compound, clientPacket);
|
||||
|
||||
compound.put("OutputItems", outputInventory.serializeNBT());
|
||||
|
||||
}
|
||||
/*
|
||||
@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) {
|
||||
if (recipeBackupCheck-- > 0)
|
||||
return;
|
||||
recipeBackupCheck = 20;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
|
||||
|
||||
|
||||
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 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 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);
|
||||
return AllTags.AllBlockTags.PASSIVE_BOILER_HEATERS.matches(state) ? BlazeBurnerBlock.HeatLevel.SMOULDERING : BlazeBurnerBlock.HeatLevel.NONE;
|
||||
}
|
||||
|
||||
public Couple<SmartFluidTankBehaviour> getTanks() {
|
||||
return tanks;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 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();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,427 @@
|
||||
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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,150 @@
|
||||
package com.drmangotea.tfmg.content.machines.oil_processing.distillation;
|
||||
|
||||
|
||||
import com.drmangotea.tfmg.recipes.distillation.DistillationRecipe;
|
||||
import com.drmangotea.tfmg.recipes.distillation.ItemlessRecipe;
|
||||
import com.drmangotea.tfmg.registry.TFMGFluids;
|
||||
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 org.checkerframework.checker.units.qual.C;
|
||||
|
||||
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;
|
||||
|
||||
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();
|
||||
if (!ItemlessRecipe.apply(basin, currentRecipe))
|
||||
return;
|
||||
getProcessedRecipeTrigger().ifPresent(this::award);
|
||||
basin.inputTank.sendDataImmediately();
|
||||
|
||||
|
||||
|
||||
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();
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.drmangotea.tfmg.recipes.distillation;
|
||||
|
||||
|
||||
|
||||
import com.drmangotea.tfmg.registry.TFMGRecipeTypes;
|
||||
import com.simibubi.create.content.processing.recipe.ProcessingRecipeBuilder;
|
||||
import com.simibubi.create.foundation.fluid.FluidIngredient;
|
||||
import mezz.jei.api.constants.RecipeTypes;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
|
||||
public class DistillationRecipe extends ItemlessRecipe {
|
||||
|
||||
public DistillationRecipe(ProcessingRecipeBuilder.ProcessingRecipeParams params) {
|
||||
super(TFMGRecipeTypes.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 ItemStack getFirstItemResult(){
|
||||
return results.get(0).getStack();
|
||||
}
|
||||
public ItemStack getSecondItemResult(){
|
||||
return results.get(1).getStack();
|
||||
}
|
||||
public ItemStack getThirdItemResult(){
|
||||
return results.get(2).getStack();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,206 @@
|
||||
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.simibubi.create.content.processing.burner.BlazeBurnerBlock;
|
||||
import com.simibubi.create.content.processing.recipe.ProcessingRecipe;
|
||||
import com.simibubi.create.content.processing.recipe.ProcessingRecipeBuilder;
|
||||
import com.simibubi.create.foundation.blockEntity.behaviour.fluid.SmartFluidTankBehaviour;
|
||||
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;
|
||||
import net.minecraftforge.items.CapabilityItemHandler;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
public class ItemlessRecipe extends ProcessingRecipe<SmartInventory> {
|
||||
|
||||
public static boolean match(DistillationControllerBlockEntity controller, Recipe<?> recipe) {
|
||||
|
||||
|
||||
|
||||
|
||||
if(recipe instanceof ItemlessRecipe) {
|
||||
|
||||
|
||||
|
||||
return apply(controller, recipe, true);
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
public static boolean apply(DistillationControllerBlockEntity basin, Recipe<?> recipe) {
|
||||
return apply(basin, recipe, false);
|
||||
}
|
||||
|
||||
private static boolean apply(DistillationControllerBlockEntity controller, Recipe<?> recipe, boolean test) {
|
||||
boolean isItemlessRecipe = recipe instanceof ItemlessRecipe;
|
||||
IItemHandler availableItems = controller.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY)
|
||||
.orElse(null);
|
||||
IFluidHandler availableFluids = controller.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY)
|
||||
.orElse(null);
|
||||
|
||||
if (availableItems == null || availableFluids == null)
|
||||
return false;
|
||||
|
||||
BlazeBurnerBlock.HeatLevel heat = DistillationControllerBlockEntity.getHeatLevelOf(controller.getLevel()
|
||||
.getBlockState(controller.getBlockPos()
|
||||
.below(1)));
|
||||
if (isItemlessRecipe && !((ItemlessRecipe) recipe).getRequiredHeat()
|
||||
.testBlazeBurner(heat))
|
||||
return false;
|
||||
|
||||
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())
|
||||
|
||||
|
||||
|
||||
|
||||
for (boolean simulate : Iterate.trueAndFalse) {
|
||||
|
||||
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++) {
|
||||
FluidIngredient fluidIngredient = fluidIngredients.get(i);
|
||||
int amountRequired = fluidIngredient.getRequiredAmount();
|
||||
|
||||
|
||||
for (int tank = 0; tank < availableFluids.getTanks(); tank++) {
|
||||
FluidStack fluidStack = availableFluids.getFluidInTank(tank);
|
||||
if (simulate && fluidStack.getAmount() <= extractedFluidsFromTank[tank])
|
||||
continue;
|
||||
if (!fluidIngredient.test(fluidStack))
|
||||
continue;
|
||||
int drainedAmount = Math.min(amountRequired, fluidStack.getAmount());
|
||||
if (!simulate) {
|
||||
fluidStack.shrink(drainedAmount);
|
||||
fluidsAffected = true;
|
||||
}
|
||||
amountRequired -= drainedAmount;
|
||||
if (amountRequired != 0)
|
||||
continue;
|
||||
extractedFluidsFromTank[tank] += drainedAmount;
|
||||
continue FluidIngredients;
|
||||
}
|
||||
|
||||
// something wasn't found
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fluidsAffected) {
|
||||
controller.getBehaviour(SmartFluidTankBehaviour.INPUT)
|
||||
.forEach(SmartFluidTankBehaviour.TankSegment::onFluidStackChanged);
|
||||
controller.getBehaviour(SmartFluidTankBehaviour.OUTPUT)
|
||||
.forEach(SmartFluidTankBehaviour.TankSegment::onFluidStackChanged);
|
||||
}
|
||||
|
||||
if (simulate) {
|
||||
if (recipe instanceof ItemlessRecipe ItemlessRecipe) {
|
||||
recipeOutputItems.addAll(ItemlessRecipe.rollResults());
|
||||
recipeOutputFluids.addAll(ItemlessRecipe.getFluidResults());
|
||||
|
||||
} 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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected ItemlessRecipe(IRecipeTypeInfo type, ProcessingRecipeBuilder.ProcessingRecipeParams params) {
|
||||
super(type, params);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected int getMaxInputCount() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getMaxOutputCount() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getMaxFluidInputCount() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getMaxFluidOutputCount() {
|
||||
return 3;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canRequireHeat() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(SmartInventory inv, @Nonnull Level worldIn) {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
package com.drmangotea.tfmg.recipes.jei;
|
||||
|
||||
|
||||
import com.drmangotea.tfmg.registry.TFMGBlocks;
|
||||
import com.jozufozu.flywheel.core.PartialModel;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.blaze3d.vertex.VertexConsumer;
|
||||
import com.mojang.math.Vector3f;
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.AllPartialModels;
|
||||
import com.simibubi.create.AllSpriteShifts;
|
||||
import com.simibubi.create.compat.jei.category.animations.AnimatedKinetics;
|
||||
import com.simibubi.create.content.processing.burner.BlazeBurnerBlock;
|
||||
import com.simibubi.create.foundation.block.render.SpriteShiftEntry;
|
||||
import com.simibubi.create.foundation.render.CachedBufferer;
|
||||
import com.simibubi.create.foundation.utility.AnimationTickHolder;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.LightTexture;
|
||||
import net.minecraft.client.renderer.MultiBufferSource;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
|
||||
public class AnimatedDistiller extends AnimatedKinetics {
|
||||
|
||||
|
||||
|
||||
public AnimatedDistiller() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(PoseStack matrixStack, int xOffset, int yOffset) {
|
||||
matrixStack.pushPose();
|
||||
matrixStack.translate(xOffset, yOffset, 200);
|
||||
matrixStack.mulPose(Vector3f.XP.rotationDegrees(-15.5f));
|
||||
matrixStack.mulPose(Vector3f.YP.rotationDegrees(22.5f));
|
||||
int scale = 23;
|
||||
BlazeBurnerBlock.HeatLevel heatLevel = BlazeBurnerBlock.HeatLevel.SMOULDERING;
|
||||
|
||||
|
||||
blockElement(TFMGBlocks.CAST_IRON_DISTILLATION_OUTPUT.getDefaultState())
|
||||
.scale(scale)
|
||||
.render(matrixStack);
|
||||
blockElement(TFMGBlocks.CAST_IRON_DISTILLATION_OUTPUT.getDefaultState())
|
||||
.atLocal(0,1,0)
|
||||
.scale(scale)
|
||||
.render(matrixStack);
|
||||
blockElement(TFMGBlocks.CAST_IRON_DISTILLATION_OUTPUT.getDefaultState())
|
||||
.atLocal(0,2,0)
|
||||
.scale(scale)
|
||||
.render(matrixStack);
|
||||
blockElement(TFMGBlocks.CAST_IRON_DISTILLATION_CONTROLLER.getDefaultState())
|
||||
.atLocal(0,3,0)
|
||||
.scale(scale)
|
||||
.render(matrixStack);
|
||||
|
||||
float offset = (Mth.sin(AnimationTickHolder.getRenderTime() / 16f) + 0.5f) / 16f;
|
||||
|
||||
blockElement(AllBlocks.BLAZE_BURNER.getDefaultState())
|
||||
.atLocal(0, 4.1, 0)
|
||||
.scale(scale)
|
||||
.render(matrixStack);
|
||||
|
||||
PartialModel blaze =
|
||||
AllPartialModels.BLAZE_ACTIVE;
|
||||
PartialModel rods2 = AllPartialModels.BLAZE_BURNER_RODS_2;
|
||||
|
||||
|
||||
|
||||
blockElement(blaze).atLocal(1, 4.1, 1)
|
||||
.rotate(0, 180, 0)
|
||||
.scale(scale)
|
||||
.render(matrixStack);
|
||||
blockElement(rods2).atLocal(1, 4.1 + offset, 1)
|
||||
.rotate(0, 180, 0)
|
||||
.scale(scale)
|
||||
.render(matrixStack);
|
||||
|
||||
|
||||
|
||||
|
||||
matrixStack.scale(scale, -scale, scale);
|
||||
matrixStack.translate(0, -1.8, 0);
|
||||
|
||||
SpriteShiftEntry spriteShift =
|
||||
AllSpriteShifts.BURNER_FLAME;
|
||||
|
||||
float spriteWidth = spriteShift.getTarget()
|
||||
.getU1()
|
||||
- spriteShift.getTarget()
|
||||
.getU0();
|
||||
|
||||
float spriteHeight = spriteShift.getTarget()
|
||||
.getV1()
|
||||
- spriteShift.getTarget()
|
||||
.getV0();
|
||||
|
||||
float time = AnimationTickHolder.getRenderTime(Minecraft.getInstance().level);
|
||||
float speed = 1 / 32f + 1 / 64f * BlazeBurnerBlock.HeatLevel.KINDLED.ordinal();
|
||||
|
||||
double vScroll = speed * time;
|
||||
vScroll = vScroll - Math.floor(vScroll);
|
||||
vScroll = vScroll * spriteHeight / 2;
|
||||
|
||||
double uScroll = speed * time / 2;
|
||||
uScroll = uScroll - Math.floor(uScroll);
|
||||
uScroll = uScroll * spriteWidth / 2;
|
||||
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
MultiBufferSource.BufferSource buffer = mc.renderBuffers()
|
||||
.bufferSource();
|
||||
VertexConsumer vb = buffer.getBuffer(RenderType.cutoutMipped());
|
||||
CachedBufferer.partial(AllPartialModels.BLAZE_BURNER_FLAME, Blocks.AIR.defaultBlockState())
|
||||
.shiftUVScrolling(spriteShift, (float) uScroll, (float) vScroll)
|
||||
.light(LightTexture.FULL_BRIGHT)
|
||||
.renderInto(matrixStack, vb);
|
||||
matrixStack.popPose();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
package com.drmangotea.tfmg.recipes.jei;
|
||||
|
||||
|
||||
|
||||
import com.drmangotea.tfmg.recipes.distillation.DistillationRecipe;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.simibubi.create.compat.jei.category.CreateRecipeCategory;
|
||||
import com.simibubi.create.foundation.fluid.FluidIngredient;
|
||||
import com.simibubi.create.foundation.gui.AllGuiTextures;
|
||||
import mezz.jei.api.forge.ForgeTypes;
|
||||
import mezz.jei.api.gui.builder.IRecipeLayoutBuilder;
|
||||
import mezz.jei.api.gui.ingredient.IRecipeSlotsView;
|
||||
import mezz.jei.api.recipe.IFocusGroup;
|
||||
import mezz.jei.api.recipe.RecipeIngredientRole;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
||||
@ParametersAreNonnullByDefault
|
||||
public class DistillationCategory extends CreateRecipeCategory<DistillationRecipe> {
|
||||
|
||||
private final AnimatedDistiller distiller = new AnimatedDistiller();
|
||||
|
||||
public DistillationCategory(Info<DistillationRecipe> info) {
|
||||
super(info);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void setRecipe(IRecipeLayoutBuilder builder, DistillationRecipe recipe, IFocusGroup focuses) {
|
||||
ItemStack result1 = recipe.getFirstItemResult();
|
||||
ItemStack result2 = recipe.getSecondItemResult();
|
||||
FluidIngredient fluidIngredient=recipe.getInputFluid();
|
||||
|
||||
|
||||
builder
|
||||
.addSlot(RecipeIngredientRole.INPUT, 2, 75)
|
||||
.setBackground(getRenderedSlot(), -1, -1)
|
||||
.addIngredients(ForgeTypes.FLUID_STACK, withImprovedVisibility(recipe.getInputFluid().getMatchingFluidStacks()))
|
||||
.addTooltipCallback(addFluidTooltip(recipe.getInputFluid().getRequiredAmount()));
|
||||
|
||||
|
||||
|
||||
builder
|
||||
.addSlot(RecipeIngredientRole.OUTPUT,150, 55)
|
||||
.setBackground(getRenderedSlot(), -1, -1)
|
||||
.addIngredient(ForgeTypes.FLUID_STACK, withImprovedVisibility(recipe.getFirstFluidResult()))
|
||||
.addTooltipCallback(addFluidTooltip(recipe.getFirstFluidResult().getAmount()));
|
||||
builder
|
||||
.addSlot(RecipeIngredientRole.OUTPUT,150, 33)
|
||||
.setBackground(getRenderedSlot(), -1, -1)
|
||||
.addIngredient(ForgeTypes.FLUID_STACK, withImprovedVisibility(recipe.getSecondFluidResult()))
|
||||
.addTooltipCallback(addFluidTooltip(recipe.getSecondFluidResult().getAmount()));
|
||||
|
||||
builder
|
||||
.addSlot(RecipeIngredientRole.OUTPUT,150, 12)
|
||||
.setBackground(getRenderedSlot(), -1, -1)
|
||||
.addIngredient(ForgeTypes.FLUID_STACK, withImprovedVisibility(recipe.getThirdFluidResult()))
|
||||
.addTooltipCallback(addFluidTooltip(recipe.getThirdFluidResult().getAmount()));
|
||||
|
||||
|
||||
|
||||
builder
|
||||
.addSlot(RecipeIngredientRole.OUTPUT, 105, 100)
|
||||
.setBackground(getRenderedSlot(), -1, -1)
|
||||
.addItemStack(recipe.getFirstItemResult());
|
||||
builder
|
||||
.addSlot(RecipeIngredientRole.OUTPUT, 127, 100)
|
||||
.setBackground(getRenderedSlot(), -1, -1)
|
||||
.addItemStack(recipe.getSecondItemResult());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(DistillationRecipe recipe, IRecipeSlotsView iRecipeSlotsView, PoseStack matrixStack, double mouseX, double mouseY) {
|
||||
distiller
|
||||
.draw(matrixStack, 65, 27);
|
||||
AllGuiTextures.JEI_ARROW.render(matrixStack, 20, 80);
|
||||
AllGuiTextures.JEI_ARROW.render(matrixStack, 100, 14);
|
||||
AllGuiTextures.JEI_ARROW.render(matrixStack, 100, 35);
|
||||
AllGuiTextures.JEI_ARROW.render(matrixStack, 100, 57);
|
||||
AllGuiTextures.JEI_DOWN_ARROW.render(matrixStack, 100, 79);
|
||||
}
|
||||
|
||||
}
|
||||
330
src/main/java/com/drmangotea/tfmg/recipes/jei/TFMGJei.java
Normal file
330
src/main/java/com/drmangotea/tfmg/recipes/jei/TFMGJei.java
Normal file
@@ -0,0 +1,330 @@
|
||||
package com.drmangotea.tfmg.recipes.jei;
|
||||
|
||||
|
||||
import com.drmangotea.tfmg.recipes.distillation.DistillationRecipe;
|
||||
import com.drmangotea.tfmg.registry.TFMGBlocks;
|
||||
import com.drmangotea.tfmg.registry.TFMGFluids;
|
||||
import com.drmangotea.tfmg.registry.TFMGRecipeTypes;
|
||||
import com.simibubi.create.Create;
|
||||
import com.simibubi.create.compat.jei.*;
|
||||
import com.simibubi.create.compat.jei.category.CreateRecipeCategory;
|
||||
import com.simibubi.create.content.equipment.blueprint.BlueprintScreen;
|
||||
import com.simibubi.create.content.logistics.filter.AbstractFilterScreen;
|
||||
import com.simibubi.create.content.redstone.link.controller.LinkedControllerScreen;
|
||||
import com.simibubi.create.content.trains.schedule.ScheduleScreen;
|
||||
import com.simibubi.create.foundation.config.ConfigBase;
|
||||
import com.simibubi.create.foundation.gui.menu.AbstractSimiContainerScreen;
|
||||
import com.simibubi.create.foundation.recipe.IRecipeTypeInfo;
|
||||
import com.simibubi.create.foundation.utility.Lang;
|
||||
import com.simibubi.create.infrastructure.config.AllConfigs;
|
||||
import com.simibubi.create.infrastructure.config.CRecipes;
|
||||
import mezz.jei.api.IModPlugin;
|
||||
import mezz.jei.api.JeiPlugin;
|
||||
import mezz.jei.api.constants.RecipeTypes;
|
||||
import mezz.jei.api.gui.drawable.IDrawable;
|
||||
import mezz.jei.api.recipe.category.IRecipeCategory;
|
||||
import mezz.jei.api.registration.*;
|
||||
import mezz.jei.api.runtime.IIngredientManager;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.crafting.Recipe;
|
||||
import net.minecraft.world.item.crafting.RecipeType;
|
||||
import net.minecraft.world.level.ItemLike;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
import java.util.*;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@JeiPlugin
|
||||
@SuppressWarnings("unused")
|
||||
@ParametersAreNonnullByDefault
|
||||
public class TFMGJei implements IModPlugin {
|
||||
|
||||
private static final ResourceLocation ID = Create.asResource("jei_plugin");
|
||||
|
||||
private final List<CreateRecipeCategory<?>> allCategories = new ArrayList<>();
|
||||
private IIngredientManager ingredientManager;
|
||||
|
||||
private void loadCategories() {
|
||||
allCategories.clear();
|
||||
|
||||
CreateRecipeCategory<?>
|
||||
|
||||
distillation = builder(DistillationRecipe.class)
|
||||
.addTypedRecipes(TFMGRecipeTypes.DISTILLATION)
|
||||
.catalyst(TFMGBlocks.CAST_IRON_DISTILLATION_CONTROLLER::get)
|
||||
.itemIcon(TFMGFluids.CRUDE_OIL.getBucket().get())
|
||||
.emptyBackground(177, 123)
|
||||
.build("distillation", DistillationCategory::new);
|
||||
|
||||
}
|
||||
|
||||
private <T extends Recipe<?>> CategoryBuilder<T> builder(Class<? extends T> recipeClass) {
|
||||
return new CategoryBuilder<>(recipeClass);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nonnull
|
||||
public ResourceLocation getPluginUid() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerCategories(IRecipeCategoryRegistration registration) {
|
||||
loadCategories();
|
||||
registration.addRecipeCategories(allCategories.toArray(IRecipeCategory[]::new));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerRecipes(IRecipeRegistration registration) {
|
||||
ingredientManager = registration.getIngredientManager();
|
||||
|
||||
allCategories.forEach(c -> c.registerRecipes(registration));
|
||||
|
||||
registration.addRecipes(RecipeTypes.CRAFTING, ToolboxColoringRecipeMaker.createRecipes().toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerRecipeCatalysts(IRecipeCatalystRegistration registration) {
|
||||
allCategories.forEach(c -> c.registerCatalysts(registration));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerRecipeTransferHandlers(IRecipeTransferRegistration registration) {
|
||||
registration.addRecipeTransferHandler(new BlueprintTransferHandler(), RecipeTypes.CRAFTING);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* check
|
||||
*/
|
||||
/*
|
||||
@Override
|
||||
public void registerFluidSubtypes(ISubtypeRegistration registration) {
|
||||
PotionFluidSubtypeInterpreter interpreter = new PotionFluidSubtypeInterpreter();
|
||||
PotionFluid potionFluid = AllFluids.POTION.get();
|
||||
registration.registerSubtypeInterpreter(ForgeTypes.FLUID_STACK, potionFluid.getSource(), interpreter);
|
||||
registration.registerSubtypeInterpreter(ForgeTypes.FLUID_STACK, potionFluid.getFlowing(), interpreter);
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
@Override
|
||||
public void registerGuiHandlers(IGuiHandlerRegistration registration) {
|
||||
registration.addGenericGuiContainerHandler(AbstractSimiContainerScreen.class, new SlotMover());
|
||||
|
||||
registration.addGhostIngredientHandler(AbstractFilterScreen.class, new GhostIngredientHandler());
|
||||
registration.addGhostIngredientHandler(BlueprintScreen.class, new GhostIngredientHandler());
|
||||
registration.addGhostIngredientHandler(LinkedControllerScreen.class, new GhostIngredientHandler());
|
||||
registration.addGhostIngredientHandler(ScheduleScreen.class, new GhostIngredientHandler());
|
||||
}
|
||||
|
||||
private class CategoryBuilder<T extends Recipe<?>> {
|
||||
private final Class<? extends T> recipeClass;
|
||||
private Predicate<CRecipes> predicate = cRecipes -> true;
|
||||
|
||||
private IDrawable background;
|
||||
private IDrawable icon;
|
||||
|
||||
private final List<Consumer<List<T>>> recipeListConsumers = new ArrayList<>();
|
||||
private final List<Supplier<? extends ItemStack>> catalysts = new ArrayList<>();
|
||||
|
||||
public CategoryBuilder(Class<? extends T> recipeClass) {
|
||||
this.recipeClass = recipeClass;
|
||||
}
|
||||
|
||||
public CategoryBuilder<T> enableIf(Predicate<CRecipes> predicate) {
|
||||
this.predicate = predicate;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CategoryBuilder<T> enableWhen(Function<CRecipes, ConfigBase.ConfigBool> configValue) {
|
||||
predicate = c -> configValue.apply(c).get();
|
||||
return this;
|
||||
}
|
||||
|
||||
public CategoryBuilder<T> addRecipeListConsumer(Consumer<List<T>> consumer) {
|
||||
recipeListConsumers.add(consumer);
|
||||
return this;
|
||||
}
|
||||
|
||||
public CategoryBuilder<T> addRecipes(Supplier<Collection<? extends T>> collection) {
|
||||
return addRecipeListConsumer(recipes -> recipes.addAll(collection.get()));
|
||||
}
|
||||
|
||||
public CategoryBuilder<T> addAllRecipesIf(Predicate<Recipe<?>> pred) {
|
||||
return addRecipeListConsumer(recipes -> consumeAllRecipes(recipe -> {
|
||||
if (pred.test(recipe)) {
|
||||
recipes.add((T) recipe);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
public CategoryBuilder<T> addAllRecipesIf(Predicate<Recipe<?>> pred, Function<Recipe<?>, T> converter) {
|
||||
return addRecipeListConsumer(recipes -> consumeAllRecipes(recipe -> {
|
||||
if (pred.test(recipe)) {
|
||||
recipes.add(converter.apply(recipe));
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
public CategoryBuilder<T> addTypedRecipes(IRecipeTypeInfo recipeTypeEntry) {
|
||||
return addTypedRecipes(recipeTypeEntry::getType);
|
||||
}
|
||||
|
||||
public CategoryBuilder<T> addTypedRecipes(Supplier<RecipeType<? extends T>> recipeType) {
|
||||
return addRecipeListConsumer(recipes -> CreateJEI.<T>consumeTypedRecipes(recipes::add, recipeType.get()));
|
||||
}
|
||||
|
||||
public CategoryBuilder<T> addTypedRecipes(Supplier<RecipeType<? extends T>> recipeType, Function<Recipe<?>, T> converter) {
|
||||
return addRecipeListConsumer(recipes -> CreateJEI.<T>consumeTypedRecipes(recipe -> recipes.add(converter.apply(recipe)), recipeType.get()));
|
||||
}
|
||||
|
||||
public CategoryBuilder<T> addTypedRecipesIf(Supplier<RecipeType<? extends T>> recipeType, Predicate<Recipe<?>> pred) {
|
||||
return addRecipeListConsumer(recipes -> CreateJEI.<T>consumeTypedRecipes(recipe -> {
|
||||
if (pred.test(recipe)) {
|
||||
recipes.add(recipe);
|
||||
}
|
||||
}, recipeType.get()));
|
||||
}
|
||||
|
||||
public CategoryBuilder<T> addTypedRecipesExcluding(Supplier<RecipeType<? extends T>> recipeType,
|
||||
Supplier<RecipeType<? extends T>> excluded) {
|
||||
return addRecipeListConsumer(recipes -> {
|
||||
List<Recipe<?>> excludedRecipes = getTypedRecipes(excluded.get());
|
||||
CreateJEI.<T>consumeTypedRecipes(recipe -> {
|
||||
for (Recipe<?> excludedRecipe : excludedRecipes) {
|
||||
if (doInputsMatch(recipe, excludedRecipe)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
recipes.add(recipe);
|
||||
}, recipeType.get());
|
||||
});
|
||||
}
|
||||
|
||||
public CategoryBuilder<T> removeRecipes(Supplier<RecipeType<? extends T>> recipeType) {
|
||||
return addRecipeListConsumer(recipes -> {
|
||||
List<Recipe<?>> excludedRecipes = getTypedRecipes(recipeType.get());
|
||||
recipes.removeIf(recipe -> {
|
||||
for (Recipe<?> excludedRecipe : excludedRecipes) {
|
||||
if (doInputsMatch(recipe, excludedRecipe)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public CategoryBuilder<T> catalystStack(Supplier<ItemStack> supplier) {
|
||||
catalysts.add(supplier);
|
||||
return this;
|
||||
}
|
||||
|
||||
public CategoryBuilder<T> catalyst(Supplier<ItemLike> supplier) {
|
||||
return catalystStack(() -> new ItemStack(supplier.get()
|
||||
.asItem()));
|
||||
}
|
||||
|
||||
public CategoryBuilder<T> icon(IDrawable icon) {
|
||||
this.icon = icon;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CategoryBuilder<T> itemIcon(ItemLike item) {
|
||||
icon(new ItemIcon(() -> new ItemStack(item)));
|
||||
return this;
|
||||
}
|
||||
|
||||
public CategoryBuilder<T> doubleItemIcon(ItemLike item1, ItemLike item2) {
|
||||
icon(new DoubleItemIcon(() -> new ItemStack(item1), () -> new ItemStack(item2)));
|
||||
return this;
|
||||
}
|
||||
|
||||
public CategoryBuilder<T> background(IDrawable background) {
|
||||
this.background = background;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CategoryBuilder<T> emptyBackground(int width, int height) {
|
||||
background(new EmptyBackground(width, height));
|
||||
return this;
|
||||
}
|
||||
|
||||
public CreateRecipeCategory<T> build(String name, CreateRecipeCategory.Factory<T> factory) {
|
||||
Supplier<List<T>> recipesSupplier;
|
||||
if (predicate.test(AllConfigs.server().recipes)) {
|
||||
recipesSupplier = () -> {
|
||||
List<T> recipes = new ArrayList<>();
|
||||
for (Consumer<List<T>> consumer : recipeListConsumers)
|
||||
consumer.accept(recipes);
|
||||
return recipes;
|
||||
};
|
||||
} else {
|
||||
recipesSupplier = () -> Collections.emptyList();
|
||||
}
|
||||
|
||||
CreateRecipeCategory.Info<T> info = new CreateRecipeCategory.Info<>(
|
||||
new mezz.jei.api.recipe.RecipeType<>(Create.asResource(name), recipeClass),
|
||||
Lang.translateDirect("recipe." + name), background, icon, recipesSupplier, catalysts);
|
||||
CreateRecipeCategory<T> category = factory.create(info);
|
||||
allCategories.add(category);
|
||||
return category;
|
||||
}
|
||||
}
|
||||
|
||||
public static void consumeAllRecipes(Consumer<Recipe<?>> consumer) {
|
||||
Minecraft.getInstance()
|
||||
.getConnection()
|
||||
.getRecipeManager()
|
||||
.getRecipes()
|
||||
.forEach(consumer);
|
||||
}
|
||||
|
||||
public static <T extends Recipe<?>> void consumeTypedRecipes(Consumer<T> consumer, RecipeType<?> type) {
|
||||
Map<ResourceLocation, Recipe<?>> map = (Map<ResourceLocation, Recipe<?>>) Minecraft.getInstance()
|
||||
.getConnection()
|
||||
.getRecipeManager().getRecipes();
|
||||
if (map != null) {
|
||||
map.values().forEach(recipe -> consumer.accept((T) recipe));
|
||||
}
|
||||
}
|
||||
|
||||
public static List<Recipe<?>> getTypedRecipes(RecipeType<?> type) {
|
||||
List<Recipe<?>> recipes = new ArrayList<>();
|
||||
consumeTypedRecipes(recipes::add, type);
|
||||
return recipes;
|
||||
}
|
||||
|
||||
public static List<Recipe<?>> getTypedRecipesExcluding(RecipeType<?> type, Predicate<Recipe<?>> exclusionPred) {
|
||||
List<Recipe<?>> recipes = getTypedRecipes(type);
|
||||
recipes.removeIf(exclusionPred);
|
||||
return recipes;
|
||||
}
|
||||
|
||||
public static boolean doInputsMatch(Recipe<?> recipe1, Recipe<?> recipe2) {
|
||||
if (recipe1.getIngredients()
|
||||
.isEmpty()
|
||||
|| recipe2.getIngredients()
|
||||
.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
ItemStack[] matchingStacks = recipe1.getIngredients()
|
||||
.get(0)
|
||||
.getItems();
|
||||
if (matchingStacks.length == 0) {
|
||||
return false;
|
||||
}
|
||||
return recipe2.getIngredients()
|
||||
.get(0)
|
||||
.test(matchingStacks[0]);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -7,6 +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.pipes.normal.LockablePipeBlockEntity;
|
||||
import com.drmangotea.tfmg.content.machines.tanks.SteelFluidTankRenderer;
|
||||
import com.drmangotea.tfmg.content.machines.tanks.SteelTankBlockEntity;
|
||||
@@ -100,5 +102,16 @@ public class TFMGBlockEntities {
|
||||
.register();
|
||||
|
||||
|
||||
public static final BlockEntityEntry<DistillationOutputBlockEntity> CAST_IRON_DISTILLATION_OUTPUT = REGISTRATE
|
||||
.blockEntity("distiller", DistillationOutputBlockEntity::new)
|
||||
.validBlocks(TFMGBlocks.CAST_IRON_DISTILLATION_OUTPUT)
|
||||
.register();
|
||||
|
||||
public static final BlockEntityEntry<DistillationControllerBlockEntity> CAST_IRON_DISTILLATION_CONTROLLER = REGISTRATE
|
||||
.blockEntity("distiller_controller", DistillationControllerBlockEntity::new)
|
||||
.validBlocks(TFMGBlocks.CAST_IRON_DISTILLATION_CONTROLLER)
|
||||
.register();
|
||||
|
||||
|
||||
public static void register() {}
|
||||
}
|
||||
|
||||
@@ -10,6 +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.pipes.normal.steel.EncasedSteelPipeBlock;
|
||||
import com.drmangotea.tfmg.content.machines.pipes.normal.steel.GlassSteelPipeBlock;
|
||||
import com.drmangotea.tfmg.content.machines.pipes.normal.steel.SteelPipeAttachmentModel;
|
||||
@@ -30,6 +32,7 @@ import com.simibubi.create.content.decoration.encasing.EncasingRegistry;
|
||||
import com.simibubi.create.content.fluids.pipes.SmartFluidPipeGenerator;
|
||||
import com.simibubi.create.content.fluids.pipes.valve.FluidValveBlock;
|
||||
import com.simibubi.create.content.kinetics.BlockStressDefaults;
|
||||
import com.simibubi.create.content.processing.AssemblyOperatorBlockItem;
|
||||
import com.simibubi.create.foundation.data.*;
|
||||
import com.tterrag.registrate.util.entry.BlockEntry;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
@@ -233,8 +236,27 @@ public class TFMGBlocks {
|
||||
.register();
|
||||
/////
|
||||
|
||||
//Distillation
|
||||
|
||||
|
||||
public static final BlockEntry<DistillationOutputBlock> CAST_IRON_DISTILLATION_OUTPUT =
|
||||
REGISTRATE.block("cast_iron_distillation_output", DistillationOutputBlock::new)
|
||||
.initialProperties(SharedProperties::copperMetal)
|
||||
.properties(p -> p.color(MaterialColor.STONE))
|
||||
.properties(BlockBehaviour.Properties::noOcclusion)
|
||||
.transform(axeOrPickaxe())
|
||||
.item(AssemblyOperatorBlockItem::new)
|
||||
.build()
|
||||
.register();
|
||||
public static final BlockEntry<DistillationControllerBlock> CAST_IRON_DISTILLATION_CONTROLLER =
|
||||
REGISTRATE.block("cast_iron_distillation_controller", DistillationControllerBlock::new)
|
||||
.initialProperties(SharedProperties::copperMetal)
|
||||
.item()
|
||||
.build()
|
||||
.register();
|
||||
|
||||
//////
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
112
src/main/java/com/drmangotea/tfmg/registry/TFMGRecipeTypes.java
Normal file
112
src/main/java/com/drmangotea/tfmg/registry/TFMGRecipeTypes.java
Normal file
@@ -0,0 +1,112 @@
|
||||
package com.drmangotea.tfmg.registry;
|
||||
|
||||
|
||||
import com.drmangotea.tfmg.CreateTFMG;
|
||||
import com.drmangotea.tfmg.recipes.distillation.DistillationRecipe;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.simibubi.create.content.processing.recipe.ProcessingRecipeBuilder.ProcessingRecipeFactory;
|
||||
import com.simibubi.create.content.processing.recipe.ProcessingRecipeSerializer;
|
||||
import com.simibubi.create.foundation.recipe.IRecipeTypeInfo;
|
||||
import com.simibubi.create.foundation.utility.Lang;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.item.crafting.Recipe;
|
||||
import net.minecraft.world.item.crafting.RecipeSerializer;
|
||||
import net.minecraft.world.item.crafting.RecipeType;
|
||||
import net.minecraft.world.item.crafting.ShapedRecipe;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraftforge.eventbus.api.IEventBus;
|
||||
import net.minecraftforge.registries.DeferredRegister;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
import net.minecraftforge.registries.RegistryObject;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public enum TFMGRecipeTypes implements IRecipeTypeInfo {
|
||||
|
||||
DISTILLATION(DistillationRecipe::new);
|
||||
|
||||
private final ResourceLocation id;
|
||||
private final RegistryObject<RecipeSerializer<?>> serializerObject;
|
||||
@Nullable
|
||||
private final RegistryObject<RecipeType<?>> typeObject;
|
||||
private final Supplier<RecipeType<?>> type;
|
||||
|
||||
TFMGRecipeTypes(Supplier<RecipeSerializer<?>> serializerSupplier, Supplier<RecipeType<?>> typeSupplier, boolean registerType) {
|
||||
String name = Lang.asId(name());
|
||||
id = CreateTFMG.asResource(name);
|
||||
serializerObject = Registers.SERIALIZER_REGISTER.register(name, serializerSupplier);
|
||||
if (registerType) {
|
||||
typeObject = Registers.TYPE_REGISTER.register(name, typeSupplier);
|
||||
type = typeObject;
|
||||
} else {
|
||||
typeObject = null;
|
||||
type = typeSupplier;
|
||||
}
|
||||
}
|
||||
|
||||
TFMGRecipeTypes(Supplier<RecipeSerializer<?>> serializerSupplier) {
|
||||
String name = Lang.asId(name());
|
||||
id = CreateTFMG.asResource(name);
|
||||
serializerObject = Registers.SERIALIZER_REGISTER.register(name, serializerSupplier);
|
||||
typeObject = Registers.TYPE_REGISTER.register(name, () -> simpleType(id));
|
||||
type = typeObject;
|
||||
}
|
||||
|
||||
TFMGRecipeTypes(ProcessingRecipeFactory<?> processingFactory) {
|
||||
this(() -> new ProcessingRecipeSerializer<>(processingFactory));
|
||||
}
|
||||
|
||||
public static <T extends Recipe<?>> RecipeType<T> simpleType(ResourceLocation id) {
|
||||
String stringId = id.toString();
|
||||
return new RecipeType<T>() {
|
||||
@Override
|
||||
public String toString() {
|
||||
return stringId;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static void register(IEventBus modEventBus) {
|
||||
ShapedRecipe.setCraftingSize(9, 9);
|
||||
|
||||
Registers.SERIALIZER_REGISTER.register(modEventBus);
|
||||
Registers.TYPE_REGISTER.register(modEventBus);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <T extends RecipeSerializer<?>> T getSerializer() {
|
||||
return (T) serializerObject.get();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <T extends RecipeType<?>> T getType() {
|
||||
return (T) type.get();
|
||||
}
|
||||
|
||||
public <C extends Container, T extends Recipe<C>> Optional<T> find(C inv, Level world) {
|
||||
return world.getRecipeManager()
|
||||
.getRecipeFor(getType(), inv, world);
|
||||
}
|
||||
|
||||
public static final Set<ResourceLocation> RECIPE_DENY_SET =
|
||||
ImmutableSet.of(new ResourceLocation("occultism", "spirit_trade"), new ResourceLocation("occultism", "ritual"));
|
||||
|
||||
|
||||
private static class Registers {
|
||||
private static final DeferredRegister<RecipeSerializer<?>> SERIALIZER_REGISTER = DeferredRegister.create(ForgeRegistries.RECIPE_SERIALIZERS, CreateTFMG.MOD_ID);
|
||||
private static final DeferredRegister<RecipeType<?>> TYPE_REGISTER = DeferredRegister.create(Registry.RECIPE_TYPE_REGISTRY, CreateTFMG.MOD_ID);
|
||||
}
|
||||
|
||||
}
|
||||
210
src/main/resources/backup/DistillationControllerBlock.java
Normal file
210
src/main/resources/backup/DistillationControllerBlock.java
Normal file
@@ -0,0 +1,210 @@
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
588
src/main/resources/backup/DistillationControllerBlockEntity.java
Normal file
588
src/main/resources/backup/DistillationControllerBlockEntity.java
Normal file
@@ -0,0 +1,588 @@
|
||||
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();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
57
src/main/resources/backup/DistillationOutputBlock.java
Normal file
57
src/main/resources/backup/DistillationOutputBlock.java
Normal file
@@ -0,0 +1,57 @@
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
423
src/main/resources/backup/DistillationOutputBlockEntity.java
Normal file
423
src/main/resources/backup/DistillationOutputBlockEntity.java
Normal file
@@ -0,0 +1,423 @@
|
||||
package com.drmangotea.tfmg.content.machines.oil_processing.distillation.backup;
|
||||
|
||||
|
||||
import com.drmangotea.tfmg.CreateTFMG;
|
||||
import com.drmangotea.tfmg.recipes.distillation.DistillationRecipe;
|
||||
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.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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
156
src/main/resources/backup/FluidProcessingBlockEntity.java
Normal file
156
src/main/resources/backup/FluidProcessingBlockEntity.java
Normal file
@@ -0,0 +1,156 @@
|
||||
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();
|
||||
}
|
||||
@@ -18,4 +18,8 @@ Version 0.6.0
|
||||
-created a building block creative mode tab
|
||||
-added lead
|
||||
-added steel valves and smart pipes
|
||||
-added brass, lead, plastic, aluminum and cast iron pipes, smart pipes, pumps and valves
|
||||
-added brass, lead, plastic, aluminum and cast iron pipes, smart pipes, pumps and valves
|
||||
-added compass to the surface scanner that shows directions to found deposit
|
||||
-added flag to the surface scanner that gets raised when oil is under 10 block away
|
||||
-doubled the range of surface scanners
|
||||
-added sheetmetals
|
||||
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"type": "tfmg:distillation",
|
||||
"ingredients": [
|
||||
|
||||
{
|
||||
"fluid": "tfmg:heavy_oil",
|
||||
"nbt": {},
|
||||
"amount": 90
|
||||
}
|
||||
],
|
||||
"results": [
|
||||
{
|
||||
"fluid": "tfmg:diesel",
|
||||
"amount": 30
|
||||
},
|
||||
{
|
||||
"fluid": "tfmg:lubrication_oil",
|
||||
"amount": 30
|
||||
},
|
||||
{
|
||||
"fluid": "tfmg:lubrication_oil",
|
||||
"amount": 30
|
||||
},
|
||||
{
|
||||
"item": "tfmg:steel_ingot"
|
||||
|
||||
},
|
||||
{
|
||||
"item": "minecraft:air"
|
||||
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"type": "tfmg:distillation",
|
||||
"ingredients": [
|
||||
|
||||
{
|
||||
"fluid": "tfmg:naphtha",
|
||||
"nbt": {},
|
||||
"amount": 9
|
||||
}
|
||||
],
|
||||
"results": [
|
||||
{
|
||||
"fluid": "tfmg:propylene",
|
||||
"amount": 3
|
||||
},
|
||||
{
|
||||
"fluid": "tfmg:ethylene",
|
||||
"amount": 3
|
||||
},
|
||||
{
|
||||
"fluid": "tfmg:ethylene",
|
||||
"amount": 3
|
||||
},
|
||||
{
|
||||
"item": "minecraft:air"
|
||||
|
||||
},
|
||||
{
|
||||
"item": "minecraft:air"
|
||||
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user