tank content renderer, tank TE, pipes connect to tanks

This commit is contained in:
LordGrimmauld 2020-06-16 12:46:16 +02:00
parent dc1ccb6741
commit b0950a23cb
9 changed files with 689 additions and 337 deletions

View file

@ -114,7 +114,7 @@ de8a40b7daf1497d5aecee47a43b3e0b1d030b00 assets\create\blockstates\fancy_scoria_
fc9ac0a7e7191b93516719455a17177fa6524ecc assets\create\blockstates\fancy_weathered_limestone_bricks_slab.json
b2a7c321b1795f20e7433f81a55ce4683de081b8 assets\create\blockstates\fancy_weathered_limestone_bricks_stairs.json
6372fe02ba0065acb0758121c45a15a1a8fdc5de assets\create\blockstates\fancy_weathered_limestone_bricks_wall.json
1f290b70c7cdd53e336081ee5707fd25d08c0e2c assets\create\blockstates\fluid_pipe.json
3aa8213ea6cd12a6964e3a70900b12d76d794d20 assets\create\blockstates\fluid_pipe.json
9d0e78a4d6d0ccac37c06d0f5810a800a04844b2 assets\create\blockstates\fluid_tank.json
e9da1794b6ece7f9aa8bcb43d42c23a55446133b assets\create\blockstates\flywheel.json
ac00d40e1ef50a37041c0481afa1a23a14dea78e assets\create\blockstates\framed_glass.json
@ -276,7 +276,7 @@ b7829c2ef2c47188713f8cab21b2c9bc7f9c5b79 assets\create\blockstates\portable_stor
e8b0a401c10d1ba67ed71ba31bd5f9bc28571b65 assets\create\blockstates\powered_toggle_latch.json
3a739f9d4276828d83f2d2750bf3227c87bcd438 assets\create\blockstates\pulley_magnet.json
469e430d96cb0a5e1aaf6b7cc5d401d488c9e600 assets\create\blockstates\pulse_repeater.json
4e1fb033316e9230d2f024d67c27940ea731643a assets\create\blockstates\radial_chassis.json
8d7e653bfd9846e684a0d3725595714a19201017 assets\create\blockstates\radial_chassis.json
8929677f2cc5354aa19ef182af69f9f0b41eb242 assets\create\blockstates\redstone_contact.json
c29213b77ac0c78d8979c5f6188d2b265696f9b9 assets\create\blockstates\redstone_link.json
1eac804cba08aebb5f4646758ae1ef9b32e01365 assets\create\blockstates\reinforced_rail.json

View file

@ -60,10 +60,10 @@
},
{
"when": {
"south": "false",
"up": "true",
"north": "true",
"down": "false",
"up": "true"
"south": "false",
"down": "false"
},
"apply": {
"model": "create:block/fluid_pipe/lu_x"
@ -71,10 +71,10 @@
},
{
"when": {
"south": "true",
"up": "true",
"north": "false",
"down": "false",
"up": "true"
"south": "true",
"down": "false"
},
"apply": {
"model": "create:block/fluid_pipe/ru_x"
@ -82,10 +82,10 @@
},
{
"when": {
"south": "false",
"up": "false",
"north": "true",
"down": "true",
"up": "false"
"south": "false",
"down": "true"
},
"apply": {
"model": "create:block/fluid_pipe/ld_x"
@ -93,10 +93,10 @@
},
{
"when": {
"south": "true",
"up": "false",
"north": "false",
"down": "true",
"up": "false"
"south": "true",
"down": "true"
},
"apply": {
"model": "create:block/fluid_pipe/rd_x"
@ -104,10 +104,10 @@
},
{
"when": {
"south": "false",
"up": "true",
"north": "false",
"down": "true",
"up": "true"
"south": "false",
"down": "true"
},
"apply": {
"model": "create:block/fluid_pipe/ud_x"
@ -115,10 +115,10 @@
},
{
"when": {
"south": "false",
"up": "true",
"north": "false",
"down": "false",
"up": "true"
"south": "false",
"down": "false"
},
"apply": {
"model": "create:block/fluid_pipe/ud_x"
@ -126,10 +126,10 @@
},
{
"when": {
"south": "false",
"up": "false",
"north": "false",
"down": "true",
"up": "false"
"south": "false",
"down": "true"
},
"apply": {
"model": "create:block/fluid_pipe/ud_x"
@ -137,32 +137,10 @@
},
{
"when": {
"south": "true",
"up": "false",
"north": "true",
"down": "false",
"up": "false"
},
"apply": {
"model": "create:block/fluid_pipe/lr_x"
}
},
{
"when": {
"south": "false",
"north": "true",
"down": "false",
"up": "false"
},
"apply": {
"model": "create:block/fluid_pipe/lr_x"
}
},
{
"when": {
"south": "true",
"north": "false",
"down": "false",
"up": "false"
"down": "false"
},
"apply": {
"model": "create:block/fluid_pipe/lr_x"
@ -170,10 +148,32 @@
},
{
"when": {
"up": "false",
"north": "true",
"south": "false",
"down": "false"
},
"apply": {
"model": "create:block/fluid_pipe/lr_x"
}
},
{
"when": {
"up": "false",
"north": "false",
"down": "false",
"up": "false"
"south": "true",
"down": "false"
},
"apply": {
"model": "create:block/fluid_pipe/lr_x"
}
},
{
"when": {
"up": "false",
"north": "false",
"south": "false",
"down": "false"
},
"apply": {
"model": "create:block/fluid_pipe/none_x"
@ -181,10 +181,10 @@
},
{
"when": {
"south": "true",
"north": "false",
"west": "true",
"east": "false",
"west": "true"
"north": "false",
"south": "true"
},
"apply": {
"model": "create:block/fluid_pipe/lu_y"
@ -192,10 +192,10 @@
},
{
"when": {
"south": "true",
"north": "false",
"west": "false",
"east": "true",
"west": "false"
"north": "false",
"south": "true"
},
"apply": {
"model": "create:block/fluid_pipe/ru_y"
@ -203,10 +203,10 @@
},
{
"when": {
"south": "false",
"north": "true",
"west": "true",
"east": "false",
"west": "true"
"north": "true",
"south": "false"
},
"apply": {
"model": "create:block/fluid_pipe/ld_y"
@ -214,10 +214,10 @@
},
{
"when": {
"south": "false",
"north": "true",
"west": "false",
"east": "true",
"west": "false"
"north": "true",
"south": "false"
},
"apply": {
"model": "create:block/fluid_pipe/rd_y"
@ -225,10 +225,10 @@
},
{
"when": {
"south": "true",
"west": "false",
"east": "false",
"north": "true",
"east": "false",
"west": "false"
"south": "true"
},
"apply": {
"model": "create:block/fluid_pipe/ud_y"
@ -236,10 +236,10 @@
},
{
"when": {
"south": "true",
"west": "false",
"east": "false",
"north": "false",
"east": "false",
"west": "false"
"south": "true"
},
"apply": {
"model": "create:block/fluid_pipe/ud_y"
@ -247,10 +247,10 @@
},
{
"when": {
"south": "false",
"west": "false",
"east": "false",
"north": "true",
"east": "false",
"west": "false"
"south": "false"
},
"apply": {
"model": "create:block/fluid_pipe/ud_y"
@ -258,10 +258,10 @@
},
{
"when": {
"south": "false",
"north": "false",
"west": "true",
"east": "true",
"west": "true"
"north": "false",
"south": "false"
},
"apply": {
"model": "create:block/fluid_pipe/lr_y"
@ -269,10 +269,10 @@
},
{
"when": {
"south": "false",
"north": "false",
"west": "true",
"east": "false",
"west": "true"
"north": "false",
"south": "false"
},
"apply": {
"model": "create:block/fluid_pipe/lr_y"
@ -280,10 +280,10 @@
},
{
"when": {
"south": "false",
"north": "false",
"west": "false",
"east": "true",
"west": "false"
"north": "false",
"south": "false"
},
"apply": {
"model": "create:block/fluid_pipe/lr_y"
@ -291,10 +291,10 @@
},
{
"when": {
"south": "false",
"north": "false",
"west": "false",
"east": "false",
"west": "false"
"north": "false",
"south": "false"
},
"apply": {
"model": "create:block/fluid_pipe/none_y"
@ -302,10 +302,10 @@
},
{
"when": {
"down": "false",
"east": "true",
"west": "false",
"up": "true"
"east": "true",
"up": "true",
"down": "false"
},
"apply": {
"model": "create:block/fluid_pipe/lu_z"
@ -313,10 +313,10 @@
},
{
"when": {
"down": "false",
"east": "false",
"west": "true",
"up": "true"
"east": "false",
"up": "true",
"down": "false"
},
"apply": {
"model": "create:block/fluid_pipe/ru_z"
@ -324,10 +324,10 @@
},
{
"when": {
"down": "true",
"east": "true",
"west": "false",
"up": "false"
"east": "true",
"up": "false",
"down": "true"
},
"apply": {
"model": "create:block/fluid_pipe/ld_z"
@ -335,10 +335,10 @@
},
{
"when": {
"down": "true",
"east": "false",
"west": "true",
"up": "false"
"east": "false",
"up": "false",
"down": "true"
},
"apply": {
"model": "create:block/fluid_pipe/rd_z"
@ -346,10 +346,10 @@
},
{
"when": {
"down": "true",
"east": "false",
"west": "false",
"up": "true"
"east": "false",
"up": "true",
"down": "true"
},
"apply": {
"model": "create:block/fluid_pipe/ud_z"
@ -357,10 +357,10 @@
},
{
"when": {
"down": "false",
"east": "false",
"west": "false",
"up": "true"
"east": "false",
"up": "true",
"down": "false"
},
"apply": {
"model": "create:block/fluid_pipe/ud_z"
@ -368,10 +368,10 @@
},
{
"when": {
"down": "true",
"east": "false",
"west": "false",
"up": "false"
"east": "false",
"up": "false",
"down": "true"
},
"apply": {
"model": "create:block/fluid_pipe/ud_z"
@ -379,21 +379,21 @@
},
{
"when": {
"down": "false",
"east": "true",
"west": "true",
"up": "false"
},
"apply": {
"model": "create:block/fluid_pipe/lr_z"
}
},
{
"when": {
"down": "false",
"east": "true",
"west": "false",
"up": "false"
"up": "false",
"down": "false"
},
"apply": {
"model": "create:block/fluid_pipe/lr_z"
}
},
{
"when": {
"west": "false",
"east": "true",
"up": "false",
"down": "false"
},
"apply": {
"model": "create:block/fluid_pipe/lr_z"
@ -401,10 +401,10 @@
},
{
"when": {
"down": "false",
"east": "false",
"west": "true",
"up": "false"
"east": "false",
"up": "false",
"down": "false"
},
"apply": {
"model": "create:block/fluid_pipe/lr_z"
@ -412,10 +412,10 @@
},
{
"when": {
"down": "false",
"east": "false",
"west": "false",
"up": "false"
"east": "false",
"up": "false",
"down": "false"
},
"apply": {
"model": "create:block/fluid_pipe/none_z"

View file

@ -29,8 +29,8 @@
},
{
"when": {
"axis": "x",
"sticky_south": "true"
"sticky_south": "true",
"axis": "x"
},
"apply": {
"model": "create:block/radial_chassis_side_x_sticky",
@ -39,8 +39,8 @@
},
{
"when": {
"axis": "y",
"sticky_south": "true"
"sticky_south": "true",
"axis": "y"
},
"apply": {
"model": "create:block/radial_chassis_side_y_sticky"
@ -48,8 +48,8 @@
},
{
"when": {
"axis": "z",
"sticky_south": "true"
"sticky_south": "true",
"axis": "z"
},
"apply": {
"model": "create:block/radial_chassis_side_x_sticky",
@ -59,8 +59,8 @@
},
{
"when": {
"axis": "x",
"sticky_south": "false"
"sticky_south": "false",
"axis": "x"
},
"apply": {
"model": "create:block/radial_chassis_side_x",
@ -69,8 +69,8 @@
},
{
"when": {
"axis": "y",
"sticky_south": "false"
"sticky_south": "false",
"axis": "y"
},
"apply": {
"model": "create:block/radial_chassis_side_y"
@ -78,8 +78,8 @@
},
{
"when": {
"axis": "z",
"sticky_south": "false"
"sticky_south": "false",
"axis": "z"
},
"apply": {
"model": "create:block/radial_chassis_side_x",
@ -207,8 +207,8 @@
},
{
"when": {
"axis": "x",
"sticky_east": "true"
"sticky_east": "true",
"axis": "x"
},
"apply": {
"model": "create:block/radial_chassis_side_x_sticky",
@ -217,8 +217,8 @@
},
{
"when": {
"axis": "y",
"sticky_east": "true"
"sticky_east": "true",
"axis": "y"
},
"apply": {
"model": "create:block/radial_chassis_side_y_sticky",
@ -227,8 +227,8 @@
},
{
"when": {
"axis": "z",
"sticky_east": "true"
"sticky_east": "true",
"axis": "z"
},
"apply": {
"model": "create:block/radial_chassis_side_z_sticky"
@ -236,8 +236,8 @@
},
{
"when": {
"axis": "x",
"sticky_east": "false"
"sticky_east": "false",
"axis": "x"
},
"apply": {
"model": "create:block/radial_chassis_side_x",
@ -246,8 +246,8 @@
},
{
"when": {
"axis": "y",
"sticky_east": "false"
"sticky_east": "false",
"axis": "y"
},
"apply": {
"model": "create:block/radial_chassis_side_y",
@ -256,8 +256,8 @@
},
{
"when": {
"axis": "z",
"sticky_east": "false"
"sticky_east": "false",
"axis": "z"
},
"apply": {
"model": "create:block/radial_chassis_side_z"

View file

@ -45,6 +45,8 @@ import com.simibubi.create.content.contraptions.components.structureMovement.pul
import com.simibubi.create.content.contraptions.components.structureMovement.pulley.PulleyTileEntity;
import com.simibubi.create.content.contraptions.components.turntable.TurntableTileEntity;
import com.simibubi.create.content.contraptions.components.waterwheel.WaterWheelTileEntity;
import com.simibubi.create.content.contraptions.fluids.FluidTankRenderer;
import com.simibubi.create.content.contraptions.fluids.FluidTankTileEntity;
import com.simibubi.create.content.contraptions.fluids.PumpRenderer;
import com.simibubi.create.content.contraptions.fluids.PumpTileEntity;
import com.simibubi.create.content.contraptions.processing.BasinRenderer;
@ -140,6 +142,8 @@ public class AllTileEntities {
public static final TileEntityEntry<PumpTileEntity> MECHANICAL_PUMP =
register("mechanical_pump", PumpTileEntity::new, AllBlocks.MECHANICAL_PUMP);
public static final TileEntityEntry<FluidTankTileEntity> FLUID_TANK =
register("fluid_tank", FluidTankTileEntity::new, AllBlocks.FLUID_TANK);
public static final TileEntityEntry<BeltTileEntity> BELT = register("belt", BeltTileEntity::new, AllBlocks.BELT);
public static final TileEntityEntry<BeltTunnelTileEntity> BELT_TUNNEL =
@ -257,6 +261,7 @@ public class AllTileEntities {
bind(ANALOG_LEVER, AnalogLeverRenderer::new);
bind(MECHANICAL_PUMP, PumpRenderer::new);
bind(FLUID_TANK, FluidTankRenderer::new);
bind(MECHANICAL_PISTON, MechanicalPistonRenderer::new);
bind(MECHANICAL_BEARING, BearingRenderer::new);

View file

@ -1,9 +1,6 @@
package com.simibubi.create.content.contraptions.fluids;
import javax.annotation.Nullable;
import com.simibubi.create.foundation.utility.Iterate;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.SixWayBlock;
@ -16,124 +13,128 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.world.ILightReader;
import net.minecraft.world.IWorld;
import javax.annotation.Nullable;
public class FluidPipeBlock extends SixWayBlock {
public FluidPipeBlock(Properties properties) {
super(4 / 16f, properties);
public FluidPipeBlock(Properties properties) {
super(4 / 16f, properties);
}
public static boolean isPipe(BlockState state) {
return state.getBlock() instanceof FluidPipeBlock;
}
public static boolean isTank(BlockState state) {
return state.getBlock() instanceof FluidTankBlock;
}
// TODO: more generic pipe connection handling. Ideally without marker interface
public static boolean canConnectTo(ILightReader world, BlockPos pos, BlockState neighbour, Direction blockFace) {
if (isPipe(neighbour) || isTank(neighbour))
return true;
return neighbour.getBlock() instanceof PumpBlock && blockFace.getAxis() == neighbour.get(PumpBlock.FACING)
.getAxis();
}
@Override
protected void fillStateContainer(Builder<Block, BlockState> builder) {
builder.add(NORTH, EAST, SOUTH, WEST, UP, DOWN);
}
public static boolean shouldDrawRim(ILightReader world, BlockPos pos, BlockState state, Direction direction) {
if (!isPipe(state))
return false;
if (!state.get(FACING_TO_PROPERTY_MAP.get(direction)))
return false;
BlockPos offsetPos = pos.offset(direction);
BlockState facingState = world.getBlockState(offsetPos);
if (facingState.getBlock() instanceof PumpBlock && facingState.get(PumpBlock.FACING)
.getAxis() == direction.getAxis())
return false;
if (!isPipe(facingState))
return true;
if (!isCornerOrEndPipe(world, pos, state))
return false;
if (isStraightPipe(world, offsetPos, facingState))
return true;
if (!shouldDrawCasing(world, pos, state) && shouldDrawCasing(world, offsetPos, facingState))
return true;
if (isCornerOrEndPipe(world, offsetPos, facingState))
return direction.getAxisDirection() == AxisDirection.POSITIVE;
return false;
}
@Override
public BlockState getStateForPlacement(BlockItemUseContext context) {
return updateBlockState(getDefaultState(), context.getNearestLookingDirection(), null, context.getWorld(),
context.getPos());
}
public static boolean isCornerOrEndPipe(ILightReader world, BlockPos pos, BlockState state) {
return isPipe(state) && !isStraightPipe(world, pos, state) && !shouldDrawCasing(world, pos, state);
}
@Override
public BlockState updatePostPlacement(BlockState state, Direction direction, BlockState neighbourState,
IWorld world, BlockPos pos, BlockPos neighbourPos) {
return updateBlockState(state, direction, direction.getOpposite(), world, pos);
}
public static boolean isStraightPipe(ILightReader world, BlockPos pos, BlockState state) {
if (!isPipe(state))
return false;
boolean axisFound = false;
for (Axis axis : Iterate.axes) {
Direction d1 = Direction.getFacingFromAxis(AxisDirection.NEGATIVE, axis);
Direction d2 = Direction.getFacingFromAxis(AxisDirection.POSITIVE, axis);
if (state.get(FACING_TO_PROPERTY_MAP.get(d1)) && state.get(FACING_TO_PROPERTY_MAP.get(d2)))
if (axisFound)
return false;
else
axisFound = true;
}
return axisFound;
}
public BlockState updateBlockState(BlockState state, Direction preferredDirection, @Nullable Direction ignore,
ILightReader world, BlockPos pos) {
// Update sides that are not ignored
for (Direction d : Iterate.directions)
if (d != ignore)
state = state.with(FACING_TO_PROPERTY_MAP.get(d),
canConnectTo(world, pos.offset(d), world.getBlockState(pos.offset(d)), d.getOpposite()));
public static boolean shouldDrawCasing(ILightReader world, BlockPos pos, BlockState state) {
if (!isPipe(state))
return false;
for (Axis axis : Iterate.axes) {
int connections = 0;
for (Direction direction : Iterate.directions)
if (direction.getAxis() != axis && state.get(FACING_TO_PROPERTY_MAP.get(direction)))
connections++;
if (connections > 2)
return true;
}
return false;
}
// See if it has enough connections
Direction connectedDirection = null;
for (Direction d : Iterate.directions) {
if (state.get(FACING_TO_PROPERTY_MAP.get(d))) {
if (connectedDirection != null)
return state;
connectedDirection = d;
}
}
@Override
protected void fillStateContainer(Builder<Block, BlockState> builder) {
builder.add(NORTH, EAST, SOUTH, WEST, UP, DOWN);
}
// Add opposite end if only one connection
if (connectedDirection != null)
return state.with(FACING_TO_PROPERTY_MAP.get(connectedDirection.getOpposite()), true);
@Override
public BlockState getStateForPlacement(BlockItemUseContext context) {
return updateBlockState(getDefaultState(), context.getNearestLookingDirection(), null, context.getWorld(),
context.getPos());
}
// Use preferred
return state.with(FACING_TO_PROPERTY_MAP.get(preferredDirection), true)
.with(FACING_TO_PROPERTY_MAP.get(preferredDirection.getOpposite()), true);
}
@Override
public BlockState updatePostPlacement(BlockState state, Direction direction, BlockState neighbourState,
IWorld world, BlockPos pos, BlockPos neighbourPos) {
return updateBlockState(state, direction, direction.getOpposite(), world, pos);
}
public static boolean isPipe(BlockState state) {
return state.getBlock() instanceof FluidPipeBlock;
}
public BlockState updateBlockState(BlockState state, Direction preferredDirection, @Nullable Direction ignore,
ILightReader world, BlockPos pos) {
// Update sides that are not ignored
for (Direction d : Iterate.directions)
if (d != ignore)
state = state.with(FACING_TO_PROPERTY_MAP.get(d),
canConnectTo(world, pos.offset(d), world.getBlockState(pos.offset(d)), d.getOpposite()));
// TODO: more generic pipe connection handling. Ideally without marker interface
public static boolean canConnectTo(ILightReader world, BlockPos pos, BlockState neighbour, Direction blockFace) {
if (isPipe(neighbour))
return true;
if (neighbour.getBlock() instanceof PumpBlock && blockFace.getAxis() == neighbour.get(PumpBlock.FACING)
.getAxis())
return true;
return false;
}
// See if it has enough connections
Direction connectedDirection = null;
for (Direction d : Iterate.directions) {
if (state.get(FACING_TO_PROPERTY_MAP.get(d))) {
if (connectedDirection != null)
return state;
connectedDirection = d;
}
}
public static boolean shouldDrawRim(ILightReader world, BlockPos pos, BlockState state, Direction direction) {
if (!isPipe(state))
return false;
if (!state.get(FACING_TO_PROPERTY_MAP.get(direction)))
return false;
BlockPos offsetPos = pos.offset(direction);
BlockState facingState = world.getBlockState(offsetPos);
if (facingState.getBlock() instanceof PumpBlock && facingState.get(PumpBlock.FACING)
.getAxis() == direction.getAxis())
return false;
if (!isPipe(facingState))
return true;
if (!isCornerOrEndPipe(world, pos, state))
return false;
if (isStraightPipe(world, offsetPos, facingState))
return true;
if (!shouldDrawCasing(world, pos, state) && shouldDrawCasing(world, offsetPos, facingState))
return true;
if (isCornerOrEndPipe(world, offsetPos, facingState))
return direction.getAxisDirection() == AxisDirection.POSITIVE;
return false;
}
// Add opposite end if only one connection
if (connectedDirection != null)
return state.with(FACING_TO_PROPERTY_MAP.get(connectedDirection.getOpposite()), true);
public static boolean isCornerOrEndPipe(ILightReader world, BlockPos pos, BlockState state) {
return isPipe(state) && !isStraightPipe(world, pos, state) && !shouldDrawCasing(world, pos, state);
}
public static boolean isStraightPipe(ILightReader world, BlockPos pos, BlockState state) {
if (!isPipe(state))
return false;
boolean axisFound = false;
for (Axis axis : Iterate.axes) {
Direction d1 = Direction.getFacingFromAxis(AxisDirection.NEGATIVE, axis);
Direction d2 = Direction.getFacingFromAxis(AxisDirection.POSITIVE, axis);
if (state.get(FACING_TO_PROPERTY_MAP.get(d1)) && state.get(FACING_TO_PROPERTY_MAP.get(d2)))
if (axisFound)
return false;
else
axisFound = true;
}
return axisFound;
}
public static boolean shouldDrawCasing(ILightReader world, BlockPos pos, BlockState state) {
if (!isPipe(state))
return false;
for (Axis axis : Iterate.axes) {
int connections = 0;
for (Direction direction : Iterate.directions)
if (direction.getAxis() != axis && state.get(FACING_TO_PROPERTY_MAP.get(direction)))
connections++;
if (connections > 2)
return true;
}
return false;
}
// Use preferred
return state.with(FACING_TO_PROPERTY_MAP.get(preferredDirection), true)
.with(FACING_TO_PROPERTY_MAP.get(preferredDirection.getOpposite()), true);
}
}

View file

@ -2,13 +2,15 @@ package com.simibubi.create.content.contraptions.fluids;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllShapes;
import com.simibubi.create.AllTileEntities;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.item.BlockItemUseContext;
import net.minecraft.state.BooleanProperty;
import net.minecraft.state.StateContainer.Builder;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Direction;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.shapes.ISelectionContext;
import net.minecraft.util.math.shapes.VoxelShape;
@ -21,96 +23,114 @@ import net.minecraftforge.api.distmarker.OnlyIn;
public class FluidTankBlock extends Block {
public static final BooleanProperty TOP = BooleanProperty.create("top");
public static final BooleanProperty BOTTOM = BooleanProperty.create("bottom");
public static final BooleanProperty TOP = BooleanProperty.create("top");
public static final BooleanProperty BOTTOM = BooleanProperty.create("bottom");
public FluidTankBlock(Properties p_i48440_1_) {
super(p_i48440_1_);
setDefaultState(getDefaultState().with(TOP, true)
.with(BOTTOM, true));
}
public FluidTankBlock(Properties p_i48440_1_) {
super(p_i48440_1_);
setDefaultState(getDefaultState().with(TOP, true)
.with(BOTTOM, true));
}
@Override
protected void fillStateContainer(Builder<Block, BlockState> p_206840_1_) {
p_206840_1_.add(TOP, BOTTOM);
}
public static boolean shouldDrawDiagonalFiller(ILightReader world, BlockPos pos, BlockState state, boolean north,
boolean east) {
if (!isTank(state))
return false;
int northOffset = north ? 1 : -1;
int eastOffset = east ? 1 : -1;
if (!isTank(world.getBlockState(pos.north(northOffset))))
return false;
if (!isTank(world.getBlockState(pos.east(eastOffset))))
return false;
return !isTank(world.getBlockState(pos.east(eastOffset)
.north(northOffset)));
}
@Override
public BlockState getStateForPlacement(BlockItemUseContext p_196258_1_) {
World world = p_196258_1_.getWorld();
BlockPos pos = p_196258_1_.getPos();
BlockState state = super.getStateForPlacement(p_196258_1_);
state = updateState(state, world, pos, Direction.UP);
state = updateState(state, world, pos, Direction.DOWN);
return state;
}
public static boolean shouldDrawCapFiller(ILightReader world, BlockPos pos, BlockState state, Direction direction,
boolean top) {
if (!isTank(state))
return false;
if (top && !state.get(TOP))
return false;
if (!top && !state.get(BOTTOM))
return false;
BlockPos adjacentPos = pos.offset(direction);
BlockState adjacentState = world.getBlockState(adjacentPos);
if (!isTank(adjacentState))
return false;
if (top && adjacentState.get(TOP))
return false;
return top || !adjacentState.get(BOTTOM);
}
@Override
public VoxelShape getShape(BlockState state, IBlockReader p_220053_2_, BlockPos p_220053_3_,
ISelectionContext p_220053_4_) {
boolean top = state.get(TOP);
boolean bottom = state.get(BOTTOM);
return top ? bottom ? AllShapes.TANK_TOP_BOTTOM : AllShapes.TANK_TOP
: bottom ? AllShapes.TANK_BOTTOM : AllShapes.TANK;
}
public static boolean isTank(BlockState state) {
return state.getBlock() instanceof FluidTankBlock;
}
@Override
public BlockState updatePostPlacement(BlockState state, Direction direction, BlockState p_196271_3_, IWorld world,
BlockPos pos, BlockPos p_196271_6_) {
return updateState(state, world, pos, direction);
}
@Override
protected void fillStateContainer(Builder<Block, BlockState> p_206840_1_) {
p_206840_1_.add(TOP, BOTTOM);
}
private BlockState updateState(BlockState state, ILightReader reader, BlockPos pos, Direction direction) {
if (direction.getAxis()
.isHorizontal())
return state;
return state.with(direction == Direction.UP ? TOP : BOTTOM,
!AllBlocks.FLUID_TANK.has(reader.getBlockState(pos.offset(direction))));
}
@Override
public BlockState getStateForPlacement(BlockItemUseContext p_196258_1_) {
World world = p_196258_1_.getWorld();
BlockPos pos = p_196258_1_.getPos();
BlockState state = super.getStateForPlacement(p_196258_1_);
state = updateState(state, world, pos, Direction.UP);
state = updateState(state, world, pos, Direction.DOWN);
return state;
}
@Override
@OnlyIn(Dist.CLIENT)
public boolean isSideInvisible(BlockState state, BlockState adjacentBlockState, Direction side) {
return adjacentBlockState.getBlock() == this;
}
private boolean isTankToDirection(IBlockReader world, BlockPos pos, Direction direction) {
return world.getBlockState(pos.offset(direction)).getBlock() instanceof FluidTankBlock;
}
public static boolean shouldDrawDiagonalFiller(ILightReader world, BlockPos pos, BlockState state, boolean north,
boolean east) {
if (!isTank(state))
return false;
int northOffset = north ? 1 : -1;
int eastOffset = east ? 1 : -1;
if (!isTank(world.getBlockState(pos.north(northOffset))))
return false;
if (!isTank(world.getBlockState(pos.east(eastOffset))))
return false;
if (isTank(world.getBlockState(pos.east(eastOffset)
.north(northOffset))))
return false;
return true;
}
public AxisAlignedBB getTankBodyShape(IBlockReader world, BlockPos pos) {
return new AxisAlignedBB((isTankToDirection(world, pos, Direction.WEST) ? 0 : 2) / 16f,
(isTankToDirection(world, pos, Direction.DOWN) ? 0 : 3) / 16f,
(isTankToDirection(world, pos, Direction.NORTH) ? 0 : 2) / 16f,
(isTankToDirection(world, pos, Direction.EAST) ? 16 : 14) / 16f,
(isTankToDirection(world, pos, Direction.UP) ? 16 : 13) / 16f,
(isTankToDirection(world, pos, Direction.SOUTH) ? 16 : 14) / 16f);
}
public static boolean shouldDrawCapFiller(ILightReader world, BlockPos pos, BlockState state, Direction direction,
boolean top) {
if (!isTank(state))
return false;
if (top && !state.get(TOP))
return false;
if (!top && !state.get(BOTTOM))
return false;
BlockPos adjacentPos = pos.offset(direction);
BlockState adjacentState = world.getBlockState(adjacentPos);
if (!isTank(adjacentState))
return false;
if (top && adjacentState.get(TOP))
return false;
if (!top && adjacentState.get(BOTTOM))
return false;
return true;
}
@Override
public VoxelShape getShape(BlockState state, IBlockReader world, BlockPos pos,
ISelectionContext p_220053_4_) {
boolean top = state.get(TOP);
boolean bottom = state.get(BOTTOM);
return top ? bottom ? AllShapes.TANK_TOP_BOTTOM : AllShapes.TANK_TOP
: bottom ? AllShapes.TANK_BOTTOM : AllShapes.TANK;
}
public static boolean isTank(BlockState state) {
return state.getBlock() instanceof FluidTankBlock;
}
@Override
public BlockState updatePostPlacement(BlockState state, Direction direction, BlockState p_196271_3_, IWorld world,
BlockPos pos, BlockPos p_196271_6_) {
return updateState(state, world, pos, direction);
}
private BlockState updateState(BlockState state, ILightReader reader, BlockPos pos, Direction direction) {
if (direction.getAxis()
.isHorizontal())
return state;
return state.with(direction == Direction.UP ? TOP : BOTTOM,
!AllBlocks.FLUID_TANK.has(reader.getBlockState(pos.offset(direction))));
}
@Override
@OnlyIn(Dist.CLIENT)
public boolean isSideInvisible(BlockState state, BlockState adjacentBlockState, Direction side) {
return adjacentBlockState.getBlock() == this;
}
@Override
public boolean hasTileEntity(BlockState state) {
return true;
}
@Override
public TileEntity createTileEntity(BlockState state, IBlockReader world) {
return AllTileEntities.FLUID_TANK.create();
}
}

View file

@ -0,0 +1,213 @@
package com.simibubi.create.content.contraptions.fluids;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.vertex.IVertexBuilder;
import com.simibubi.create.foundation.tileEntity.renderer.SafeTileEntityRenderer;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.IRenderTypeBuffer;
import net.minecraft.client.renderer.Matrix4f;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.texture.AtlasTexture;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
import net.minecraft.fluid.Fluid;
import net.minecraft.util.Direction;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraftforge.fluids.IFluidTank;
import java.util.Collection;
import java.util.Collections;
public class FluidTankRenderer extends SafeTileEntityRenderer<FluidTankTileEntity> {
public FluidTankRenderer(TileEntityRendererDispatcher dispatcher) {
super(dispatcher);
}
private static int[] decomposeColor(int color) {
int[] res = new int[4];
res[0] = color >> 24 & 0xff;
res[1] = color >> 16 & 0xff;
res[2] = color >> 8 & 0xff;
res[3] = color & 0xff;
return res;
}
@Override
protected void renderSafe(FluidTankTileEntity te, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer,
int light, int overlay) {
renderFluid(te, partialTicks, ms, buffer, light, overlay);
}
private void renderFluid(FluidTankTileEntity te, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer,
int light, int overlay) {
if (te.getWorld().isAreaLoaded(te.getPos(), 0)) {
IVertexBuilder builder = buffer.getBuffer(RenderType.getTranslucent());
Matrix4f posMat = ms.peek().getModel();
for (TankRenderInfo tankRenderInfo : getTanksToRender(te)) {
doRender(builder, tankRenderInfo, posMat, light);
}
}
// Minecraft.getInstance().getBlockRendererDispatcher().renderFluid(te.getPos().up(2), Minecraft.getInstance().world, buffer.getBuffer(RenderType.getSolid()), tank.getFluid().getRawFluid().getDefaultState());
}
private void doRender(IVertexBuilder builder, TankRenderInfo tankRenderInfo, Matrix4f posMat, int combinedLight) {
IFluidTank tank = tankRenderInfo.getTank();
if (tank.getFluidAmount() == 0) return;
Fluid fluid = tank.getFluid().getFluid();
ResourceLocation texture = fluid.getAttributes().getStillTexture(tank.getFluid());
TextureAtlasSprite still = Minecraft.getInstance().getSpriteAtlas(AtlasTexture.LOCATION_BLOCKS_TEXTURE).apply(texture);
int[] cols = decomposeColor(fluid.getAttributes().getColor(tank.getFluid()));
AxisAlignedBB bounds = getRenderBounds(tank, tankRenderInfo.getBounds());
float x1 = (float) bounds.minX;
float x2 = (float) bounds.maxX;
float y1 = (float) bounds.minY;
float y2 = (float) bounds.maxY;
float z1 = (float) bounds.minZ;
float z2 = (float) bounds.maxZ;
double bx1 = bounds.minX * 16;
double bx2 = bounds.maxX * 16;
double by1 = bounds.minY * 16;
double by2 = bounds.maxY * 16;
double bz1 = bounds.minZ * 16;
double bz2 = bounds.maxZ * 16;
if (tankRenderInfo.shouldRender(Direction.DOWN)) {
float u1 = still.getInterpolatedU(bx1);
float u2 = still.getInterpolatedU(bx2);
float v1 = still.getInterpolatedV(bz1);
float v2 = still.getInterpolatedV(bz2);
renderDown(builder, posMat, combinedLight, cols, x1, y1, z1, z2, u1, v1, v2);
renderDown(builder, posMat, combinedLight, cols, x2, y1, z2, z1, u2, v2, v1);
}
if (tankRenderInfo.shouldRender(Direction.UP)) {
float u1 = still.getInterpolatedU(bx1);
float u2 = still.getInterpolatedU(bx2);
float v1 = still.getInterpolatedV(bz1);
float v2 = still.getInterpolatedV(bz2);
renderUp(builder, posMat, combinedLight, cols, x2, x1, y2, z2, u2, u1, v2);
renderUp(builder, posMat, combinedLight, cols, x1, x2, y2, z1, u1, u2, v1);
}
if (tankRenderInfo.shouldRender(Direction.NORTH)) {
float u1 = still.getInterpolatedU(bx1);
float u2 = still.getInterpolatedU(bx2);
float v1 = still.getInterpolatedV(by1);
float v2 = still.getInterpolatedV(by2);
renderNorth(builder, posMat, combinedLight, cols, x1, y1, y2, z1, u1, v1, v2);
renderNorth(builder, posMat, combinedLight, cols, x2, y2, y1, z1, u2, v2, v1);
}
if (tankRenderInfo.shouldRender(Direction.SOUTH)) {
float u1 = still.getInterpolatedU(bx1);
float u2 = still.getInterpolatedU(bx2);
float v1 = still.getInterpolatedV(by1);
float v2 = still.getInterpolatedV(by2);
renderSouth(builder, posMat, combinedLight, cols, x2, y1, y2, z2, u2, v1, v2);
renderSouth(builder, posMat, combinedLight, cols, x1, y2, y1, z2, u1, v2, v1);
}
if (tankRenderInfo.shouldRender(Direction.WEST)) {
float u1 = still.getInterpolatedU(by1);
float u2 = still.getInterpolatedU(by2);
float v1 = still.getInterpolatedV(bz1);
float v2 = still.getInterpolatedV(bz2);
renderWest(builder, posMat, combinedLight, cols, x1, y1, y2, z2, u1, u2, v2);
renderWest(builder, posMat, combinedLight, cols, x1, y2, y1, z1, u2, u1, v1);
}
if (tankRenderInfo.shouldRender(Direction.EAST)) {
float u1 = still.getInterpolatedU(by1);
float u2 = still.getInterpolatedU(by2);
float v1 = still.getInterpolatedV(bz1);
float v2 = still.getInterpolatedV(bz2);
renderEast(builder, posMat, combinedLight, cols, x2, y1, y2, z1, u1, u2, v1);
renderEast(builder, posMat, combinedLight, cols, x2, y2, y1, z2, u2, u1, v2);
}
}
private void renderEast(IVertexBuilder builder, Matrix4f posMat, int combinedLight, int[] cols, float x2, float y1, float y2, float z1, float u1, float u2, float v1) {
builder.vertex(posMat, x2, y1, z1).color(cols[1], cols[2], cols[3], cols[0]).texture(u1, v1).light(combinedLight).normal(1f, 0f, 0f).endVertex();
builder.vertex(posMat, x2, y2, z1).color(cols[1], cols[2], cols[3], cols[0]).texture(u2, v1).light(combinedLight).normal(1f, 0f, 0f).endVertex();
}
private void renderWest(IVertexBuilder builder, Matrix4f posMat, int combinedLight, int[] cols, float x1, float y1, float y2, float z2, float u1, float u2, float v2) {
builder.vertex(posMat, x1, y1, z2).color(cols[1], cols[2], cols[3], cols[0]).texture(u1, v2).light(combinedLight).normal(-1f, 0f, 0f).endVertex();
builder.vertex(posMat, x1, y2, z2).color(cols[1], cols[2], cols[3], cols[0]).texture(u2, v2).light(combinedLight).normal(-1f, 0f, 0f).endVertex();
}
private void renderSouth(IVertexBuilder builder, Matrix4f posMat, int combinedLight, int[] cols, float x2, float y1, float y2, float z2, float u2, float v1, float v2) {
builder.vertex(posMat, x2, y1, z2).color(cols[1], cols[2], cols[3], cols[0]).texture(u2, v1).light(combinedLight).normal(0f, 0f, 1f).endVertex();
builder.vertex(posMat, x2, y2, z2).color(cols[1], cols[2], cols[3], cols[0]).texture(u2, v2).light(combinedLight).normal(0f, 0f, 1f).endVertex();
}
private void renderNorth(IVertexBuilder builder, Matrix4f posMat, int combinedLight, int[] cols, float x1, float y1, float y2, float z1, float u1, float v1, float v2) {
builder.vertex(posMat, x1, y1, z1).color(cols[1], cols[2], cols[3], cols[0]).texture(u1, v1).light(combinedLight).normal(0f, 0f, -1f).endVertex();
builder.vertex(posMat, x1, y2, z1).color(cols[1], cols[2], cols[3], cols[0]).texture(u1, v2).light(combinedLight).normal(0f, 0f, -1f).endVertex();
}
private void renderUp(IVertexBuilder builder, Matrix4f posMat, int combinedLight, int[] cols, float x1, float x2, float y2, float z1, float u1, float u2, float v1) {
builder.vertex(posMat, x2, y2, z1).color(cols[1], cols[2], cols[3], cols[0]).texture(u2, v1).light(combinedLight).normal(0f, 1f, 0f).endVertex();
builder.vertex(posMat, x1, y2, z1).color(cols[1], cols[2], cols[3], cols[0]).texture(u1, v1).light(combinedLight).normal(0f, 1f, 0f).endVertex();
}
private void renderDown(IVertexBuilder builder, Matrix4f posMat, int combinedLight, int[] cols, float x1, float y1, float z1, float z2, float u1, float v1, float v2) {
builder.vertex(posMat, x1, y1, z2).color(cols[1], cols[2], cols[3], cols[0]).texture(u1, v2).light(combinedLight).normal(0f, -1f, 0f).endVertex();
builder.vertex(posMat, x1, y1, z1).color(cols[1], cols[2], cols[3], cols[0]).texture(u1, v1).light(combinedLight).normal(0f, -1f, 0f).endVertex();
}
private AxisAlignedBB getRenderBounds(IFluidTank tank, AxisAlignedBB tankBounds) {
float percent = (float) tank.getFluidAmount() / (float) tank.getCapacity();
double tankHeight = tankBounds.maxY - tankBounds.minY;
double y1 = tankBounds.minY, y2 = (tankBounds.minY + (tankHeight * percent));
if (tank.getFluid().getFluid().getAttributes().isLighterThanAir()) {
double yOff = tankBounds.maxY - y2; // lighter than air fluids move to the top of the tank
y1 += yOff;
y2 += yOff;
}
return new AxisAlignedBB(tankBounds.minX, y1, tankBounds.minZ, tankBounds.maxX, y2, tankBounds.maxZ);
}
private Collection<TankRenderInfo> getTanksToRender(FluidTankTileEntity te) {
boolean up = te.getBlockState().get(FluidTankBlock.TOP);
boolean down = te.getBlockState().get(FluidTankBlock.BOTTOM);
// bounds.shrink(16f);
return Collections.singletonList(new FluidTankRenderInfo(te.getTank(), up, down, ((FluidTankBlock) te.getBlockState().getBlock()).getTankBodyShape(te.getWorld(), te.getPos())));
}
private static class FluidTankRenderInfo extends TankRenderInfo {
private final boolean up;
private final boolean down;
FluidTankRenderInfo(IFluidTank tank, boolean up, boolean down, AxisAlignedBB bounds) {
super(tank, bounds);
this.up = up;
this.down = down;
}
@Override
public boolean shouldRender(Direction face) {
switch (face) {
case UP:
return up
|| getTank().getFluid().getAmount() < getTank().getCapacity()
&& !getTank().getFluid().getFluid().getAttributes().isLighterThanAir();
case DOWN:
return down
|| getTank().getFluid().getAmount() < getTank().getCapacity()
&& getTank().getFluid().getFluid().getAttributes().isLighterThanAir();
default:
return true;
}
}
}
}

View file

@ -0,0 +1,59 @@
package com.simibubi.create.content.contraptions.fluids;
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.tileentity.TileEntityType;
import net.minecraft.util.Direction;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.fluids.IFluidTank;
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
import net.minecraftforge.fluids.capability.templates.FluidTank;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.List;
public class FluidTankTileEntity extends SmartTileEntity {
LazyOptional<FluidTank> fluid = LazyOptional.of(this::createFluidHandler);
public FluidTankTileEntity(TileEntityType<?> tileEntityTypeIn) {
super(tileEntityTypeIn);
}
@Nonnull
@Override
public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, @Nullable Direction side) {
if (cap == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) {
return fluid.cast();
}
return super.getCapability(cap, side);
}
@Override
public void read(CompoundNBT tag) {
fluid.ifPresent(h -> h.readFromNBT(tag));
super.read(tag);
}
@Override
public CompoundNBT write(CompoundNBT tag) {
fluid.ifPresent(h -> h.writeToNBT(tag));
return super.write(tag);
}
@Override
public void addBehaviours(List<TileEntityBehaviour> behaviours) {
}
@Nonnull
public FluidTank createFluidHandler() {
return new FluidTank(16);
}
public IFluidTank getTank() {
return fluid.orElseGet(this::createFluidHandler);
}
}

View file

@ -0,0 +1,54 @@
package com.simibubi.create.content.contraptions.fluids;
import net.minecraft.util.Direction;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.IFluidTank;
import net.minecraftforge.fluids.capability.templates.FluidTank;
import java.util.BitSet;
public class TankRenderInfo {
private final IFluidTank tank;
private final AxisAlignedBB bounds;
private final BitSet faces = new BitSet(6);
public TankRenderInfo(FluidStack stack, int capacity, AxisAlignedBB bounds, Direction... renderFaces) {
FluidTank tank = new FluidTank(capacity);
tank.setFluid(stack);
this.tank = tank;
this.bounds = bounds;
if (renderFaces.length == 0) {
faces.set(0, 6, true);
} else {
for (Direction face : renderFaces) {
faces.set(face.getIndex(), true);
}
}
}
public TankRenderInfo(IFluidTank tank, AxisAlignedBB bounds, Direction... renderFaces) {
this(tank.getFluid(), tank.getCapacity(), bounds, renderFaces);
}
public TankRenderInfo without(Direction face) {
faces.clear(face.getIndex());
return this;
}
public boolean shouldRender(Direction face) {
return faces.get(face.getIndex());
}
public IFluidTank getTank() {
return tank;
}
public AxisAlignedBB getBounds() {
return bounds;
}
public BitSet getFaces() {
return faces;
}
}