Tanks, Obama

- Reworked fluid tanks to incorporate new assets and functionality
This commit is contained in:
simibubi 2020-07-19 00:22:14 +02:00
parent e276302cee
commit 217138255e
75 changed files with 3637 additions and 958 deletions

View file

@ -125,7 +125,7 @@ fc9ac0a7e7191b93516719455a17177fa6524ecc assets\create\blockstates\fancy_weather
b2a7c321b1795f20e7433f81a55ce4683de081b8 assets\create\blockstates\fancy_weathered_limestone_bricks_stairs.json b2a7c321b1795f20e7433f81a55ce4683de081b8 assets\create\blockstates\fancy_weathered_limestone_bricks_stairs.json
6372fe02ba0065acb0758121c45a15a1a8fdc5de assets\create\blockstates\fancy_weathered_limestone_bricks_wall.json 6372fe02ba0065acb0758121c45a15a1a8fdc5de assets\create\blockstates\fancy_weathered_limestone_bricks_wall.json
4cbd66ed3da77d1caad6ef4e657a86b1b4017a39 assets\create\blockstates\fluid_pipe.json 4cbd66ed3da77d1caad6ef4e657a86b1b4017a39 assets\create\blockstates\fluid_pipe.json
9d0e78a4d6d0ccac37c06d0f5810a800a04844b2 assets\create\blockstates\fluid_tank.json f0eaab18e16c4f3f65ebf3b55b08f0dc445720fe assets\create\blockstates\fluid_tank.json
e9da1794b6ece7f9aa8bcb43d42c23a55446133b assets\create\blockstates\flywheel.json e9da1794b6ece7f9aa8bcb43d42c23a55446133b assets\create\blockstates\flywheel.json
ac00d40e1ef50a37041c0481afa1a23a14dea78e assets\create\blockstates\framed_glass.json ac00d40e1ef50a37041c0481afa1a23a14dea78e assets\create\blockstates\framed_glass.json
61df7769fa61f6dd2868a4377e54320fdd473b4e assets\create\blockstates\framed_glass_pane.json 61df7769fa61f6dd2868a4377e54320fdd473b4e assets\create\blockstates\framed_glass_pane.json
@ -1110,7 +1110,7 @@ ce6ee1fe4a92e26af75c2eaebd5055efdbdff169 assets\create\models\item\fancy_scoria_
7c1ed1241d55b105f7acb997d7c0e24b4b945293 assets\create\models\item\fancy_weathered_limestone_bricks_stairs.json 7c1ed1241d55b105f7acb997d7c0e24b4b945293 assets\create\models\item\fancy_weathered_limestone_bricks_stairs.json
7bdb3d8a59586654df0c2a84d73a346b898d247b assets\create\models\item\fancy_weathered_limestone_bricks_wall.json 7bdb3d8a59586654df0c2a84d73a346b898d247b assets\create\models\item\fancy_weathered_limestone_bricks_wall.json
e5e6fb6eb182b85b977e1025a7fe84d46de59320 assets\create\models\item\fluid_pipe.json e5e6fb6eb182b85b977e1025a7fe84d46de59320 assets\create\models\item\fluid_pipe.json
04b679a9342b0b5164c9fc8026b8fce5a067d511 assets\create\models\item\fluid_tank.json e7d2097256fed545064a37d233e7b810b04c26a4 assets\create\models\item\fluid_tank.json
8707332c0cb6ee123e7962d08536a60725c64ce8 assets\create\models\item\flywheel.json 8707332c0cb6ee123e7962d08536a60725c64ce8 assets\create\models\item\flywheel.json
d62b93d3c274d280f3eec22a28b5175943411d25 assets\create\models\item\framed_glass.json d62b93d3c274d280f3eec22a28b5175943411d25 assets\create\models\item\framed_glass.json
1041d462c6e856f7f3f2365c299c0599703d1ed7 assets\create\models\item\framed_glass_pane.json 1041d462c6e856f7f3f2365c299c0599703d1ed7 assets\create\models\item\framed_glass_pane.json

View file

@ -1,25 +1,76 @@
{ {
"multipart": [ "variants": {
{ "bottom=false,shape=plain,top=false": {
"when": { "model": "create:block/fluid_tank/block_middle"
"top": "true"
},
"apply": {
"model": "create:block/fluid_tank/block_top"
}
}, },
{ "bottom=true,shape=plain,top=false": {
"apply": { "model": "create:block/fluid_tank/block_bottom"
"model": "create:block/fluid_tank/block_windows"
}
}, },
{ "bottom=false,shape=window,top=false": {
"when": { "model": "create:block/fluid_tank/block_middle_window"
"bottom": "true" },
}, "bottom=true,shape=window,top=false": {
"apply": { "model": "create:block/fluid_tank/block_bottom_window"
"model": "create:block/fluid_tank/block_bottom" },
} "bottom=false,shape=window_nw,top=false": {
"model": "create:block/fluid_tank/block_middle_window_nw"
},
"bottom=true,shape=window_nw,top=false": {
"model": "create:block/fluid_tank/block_bottom_window_nw"
},
"bottom=false,shape=window_sw,top=false": {
"model": "create:block/fluid_tank/block_middle_window_sw"
},
"bottom=true,shape=window_sw,top=false": {
"model": "create:block/fluid_tank/block_bottom_window_sw"
},
"bottom=false,shape=window_ne,top=false": {
"model": "create:block/fluid_tank/block_middle_window_ne"
},
"bottom=true,shape=window_ne,top=false": {
"model": "create:block/fluid_tank/block_bottom_window_ne"
},
"bottom=false,shape=window_se,top=false": {
"model": "create:block/fluid_tank/block_middle_window_se"
},
"bottom=true,shape=window_se,top=false": {
"model": "create:block/fluid_tank/block_bottom_window_se"
},
"bottom=false,shape=plain,top=true": {
"model": "create:block/fluid_tank/block_top"
},
"bottom=true,shape=plain,top=true": {
"model": "create:block/fluid_tank/block_single"
},
"bottom=false,shape=window,top=true": {
"model": "create:block/fluid_tank/block_top_window"
},
"bottom=true,shape=window,top=true": {
"model": "create:block/fluid_tank/block_single_window"
},
"bottom=false,shape=window_nw,top=true": {
"model": "create:block/fluid_tank/block_top_window_nw"
},
"bottom=true,shape=window_nw,top=true": {
"model": "create:block/fluid_tank/block_single_window_nw"
},
"bottom=false,shape=window_sw,top=true": {
"model": "create:block/fluid_tank/block_top_window_sw"
},
"bottom=true,shape=window_sw,top=true": {
"model": "create:block/fluid_tank/block_single_window_sw"
},
"bottom=false,shape=window_ne,top=true": {
"model": "create:block/fluid_tank/block_top_window_ne"
},
"bottom=true,shape=window_ne,top=true": {
"model": "create:block/fluid_tank/block_single_window_ne"
},
"bottom=false,shape=window_se,top=true": {
"model": "create:block/fluid_tank/block_top_window_se"
},
"bottom=true,shape=window_se,top=true": {
"model": "create:block/fluid_tank/block_single_window_se"
} }
] }
} }

View file

@ -1,3 +1,3 @@
{ {
"parent": "create:block/fluid_tank/item" "parent": "create:block/fluid_tank/block_single_window"
} }

View file

@ -8,8 +8,6 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.apache.commons.lang3.tuple.Pair;
import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.matrix.MatrixStack;
import com.simibubi.create.foundation.utility.AngleHelper; import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.Iterate;
@ -99,8 +97,6 @@ public class AllBlockPartials {
FLUID_PIPE_CASING = get("fluid_pipe/casing"); FLUID_PIPE_CASING = get("fluid_pipe/casing");
public static final Map<Direction, AllBlockPartials> PIPE_RIMS = map(); public static final Map<Direction, AllBlockPartials> PIPE_RIMS = map();
public static final Map<Pair<Boolean, Direction>, AllBlockPartials> TANK_LID_FILLERS = map();
public static final Map<Pair<Boolean, Boolean>, AllBlockPartials> TANK_DIAGONAL_FILLERS = map();
static { static {
populateMaps(); populateMaps();
@ -115,22 +111,8 @@ public class AllBlockPartials {
private static void populateMaps() { private static void populateMaps() {
for (Direction d : Iterate.directions) { for (Direction d : Iterate.directions) {
boolean horizontal = d.getAxis()
.isHorizontal();
PIPE_RIMS.put(d, get("fluid_pipe/rim/" + d.getName())); PIPE_RIMS.put(d, get("fluid_pipe/rim/" + d.getName()));
if (horizontal) {
for (boolean top : Iterate.trueAndFalse)
TANK_LID_FILLERS.put(Pair.of(top, d),
get("fluid_tank/lid_fillers/" + (top ? "top" : "bottom") + "_" + d.getName()));
}
} }
for (boolean north : Iterate.trueAndFalse)
for (boolean east : Iterate.trueAndFalse)
TANK_DIAGONAL_FILLERS.put(Pair.of(north, east),
get("fluid_tank/diagonal_fillers/" + (north ? "north" : "south") + "_" + (east ? "east" : "west")));
} }
private static <T, U> Map<T, U> map() { private static <T, U> Map<T, U> map() {

View file

@ -53,6 +53,8 @@ import com.simibubi.create.content.contraptions.components.waterwheel.WaterWheel
import com.simibubi.create.content.contraptions.fluids.FluidPipeBlock; import com.simibubi.create.content.contraptions.fluids.FluidPipeBlock;
import com.simibubi.create.content.contraptions.fluids.FluidPipeModel; import com.simibubi.create.content.contraptions.fluids.FluidPipeModel;
import com.simibubi.create.content.contraptions.fluids.FluidTankBlock; import com.simibubi.create.content.contraptions.fluids.FluidTankBlock;
import com.simibubi.create.content.contraptions.fluids.FluidTankGenerator;
import com.simibubi.create.content.contraptions.fluids.FluidTankItem;
import com.simibubi.create.content.contraptions.fluids.FluidTankModel; import com.simibubi.create.content.contraptions.fluids.FluidTankModel;
import com.simibubi.create.content.contraptions.fluids.PumpBlock; import com.simibubi.create.content.contraptions.fluids.PumpBlock;
import com.simibubi.create.content.contraptions.processing.BasinBlock; import com.simibubi.create.content.contraptions.processing.BasinBlock;
@ -146,7 +148,6 @@ import net.minecraft.util.ResourceLocation;
import net.minecraftforge.client.model.generators.ConfiguredModel; import net.minecraftforge.client.model.generators.ConfiguredModel;
import net.minecraftforge.common.ToolType; import net.minecraftforge.common.ToolType;
@SuppressWarnings("unused")
public class AllBlocks { public class AllBlocks {
private static final CreateRegistrate REGISTRATE = Create.registrate() private static final CreateRegistrate REGISTRATE = Create.registrate()
@ -462,11 +463,13 @@ public class AllBlocks {
public static final BlockEntry<FluidTankBlock> FLUID_TANK = REGISTRATE.block("fluid_tank", FluidTankBlock::new) public static final BlockEntry<FluidTankBlock> FLUID_TANK = REGISTRATE.block("fluid_tank", FluidTankBlock::new)
.initialProperties(SharedProperties::softMetal) .initialProperties(SharedProperties::softMetal)
.blockstate(BlockStateGen.tank()) .properties(Block.Properties::nonOpaque)
.blockstate(new FluidTankGenerator()::generate)
.onRegister(CreateRegistrate.blockModel(() -> FluidTankModel::new)) .onRegister(CreateRegistrate.blockModel(() -> FluidTankModel::new))
.addLayer(() -> RenderType::getCutoutMipped) .addLayer(() -> RenderType::getCutoutMipped)
.item() .item(FluidTankItem::new)
.transform(customItemModel()) .model(AssetLookup.customItemModel("_", "block_single_window"))
.build()
.register(); .register();
// Contraptions // Contraptions

View file

@ -18,7 +18,12 @@ import com.simibubi.create.content.contraptions.relays.belt.item.BeltConnectorIt
import com.simibubi.create.content.contraptions.relays.gearbox.VerticalGearboxItem; import com.simibubi.create.content.contraptions.relays.gearbox.VerticalGearboxItem;
import com.simibubi.create.content.contraptions.wrench.WrenchItem; import com.simibubi.create.content.contraptions.wrench.WrenchItem;
import com.simibubi.create.content.contraptions.wrench.WrenchModel; import com.simibubi.create.content.contraptions.wrench.WrenchModel;
import com.simibubi.create.content.curiosities.*; import com.simibubi.create.content.curiosities.ChromaticCompoundColor;
import com.simibubi.create.content.curiosities.ChromaticCompoundItem;
import com.simibubi.create.content.curiosities.CombustibleItem;
import com.simibubi.create.content.curiosities.RefinedRadianceItem;
import com.simibubi.create.content.curiosities.ShadowSteelItem;
import com.simibubi.create.content.curiosities.TreeFertilizerItem;
import com.simibubi.create.content.curiosities.symmetry.SymmetryWandItem; import com.simibubi.create.content.curiosities.symmetry.SymmetryWandItem;
import com.simibubi.create.content.curiosities.symmetry.client.SymmetryWandModel; import com.simibubi.create.content.curiosities.symmetry.client.SymmetryWandModel;
import com.simibubi.create.content.curiosities.tools.DeforesterItem; import com.simibubi.create.content.curiosities.tools.DeforesterItem;
@ -42,7 +47,6 @@ import net.minecraft.item.Item;
import net.minecraft.item.Rarity; import net.minecraft.item.Rarity;
import net.minecraft.tags.Tag; import net.minecraft.tags.Tag;
@SuppressWarnings("unused")
public class AllItems { public class AllItems {
private static final CreateRegistrate REGISTRATE = Create.registrate() private static final CreateRegistrate REGISTRATE = Create.registrate()

View file

@ -113,8 +113,7 @@ public class AllShapes {
BASIN_BLOCK_SHAPE = shape(0, 2, 0, 16, 13, 16).erase(2, 5, 2, 14, 14, 14) BASIN_BLOCK_SHAPE = shape(0, 2, 0, 16, 13, 16).erase(2, 5, 2, 14, 14, 14)
.add(2, 0, 2, 14, 2, 14) .add(2, 0, 2, 14, 2, 14)
.build(), .build(), HEATER_BLOCK_SHAPE =
HEATER_BLOCK_SHAPE =
shape(2, 0, 2, 14, 16, 14).add(0, 0, 0, 16, 2, 16) shape(2, 0, 2, 14, 16, 14).add(0, 0, 0, 16, 2, 16)
.erase(3, 5, 3, 13, 16, 13) .erase(3, 5, 3, 13, 16, 13)
.build(), .build(),

View file

@ -48,7 +48,7 @@ public class AllSpriteShifts {
public static final CTSpriteShiftEntry public static final CTSpriteShiftEntry
BRASS_TUNNEL_TOP = vertical("brass_tunnel_top"), BRASS_TUNNEL_TOP = vertical("brass_tunnel_top"),
FLUID_TANK = getCT(CTType.OMNIDIRECTIONAL, "fluid_tank"); FLUID_TANK = getCT(CTType.CROSS, "fluid_tank");
public static final SpriteShiftEntry public static final SpriteShiftEntry
BELT = SpriteShifter.get("block/belt", "block/belt_animated"), BELT = SpriteShifter.get("block/belt", "block/belt_animated"),

View file

@ -108,11 +108,14 @@ public class DeployerFakePlayer extends FakePlayer {
if (trueSource != null && trueSource instanceof DeployerFakePlayer) { if (trueSource != null && trueSource instanceof DeployerFakePlayer) {
DeployerFakePlayer fakePlayer = (DeployerFakePlayer) trueSource; DeployerFakePlayer fakePlayer = (DeployerFakePlayer) trueSource;
event.getDrops() event.getDrops()
.forEach(stack -> fakePlayer.inventory.placeItemBackInInventory(trueSource.world, stack.getItem())); .forEach(stack -> fakePlayer.inventory.placeItemBackInInventory(trueSource.world, stack.getItem()));
event.setCanceled(true); event.setCanceled(true);
} }
} }
@Override
protected void playEquipSound(ItemStack p_184606_1_) {}
@Override @Override
public void remove(boolean keepData) { public void remove(boolean keepData) {
if (blockBreakingProgress != null && !world.isRemote) if (blockBreakingProgress != null && !world.isRemote)
@ -156,13 +159,11 @@ public class DeployerFakePlayer extends FakePlayer {
} }
@Override @Override
public void sendPacket(IPacket<?> packetIn) { public void sendPacket(IPacket<?> packetIn) {}
}
@Override @Override
public void sendPacket(IPacket<?> packetIn, public void sendPacket(IPacket<?> packetIn,
GenericFutureListener<? extends Future<? super Void>> futureListeners) { GenericFutureListener<? extends Future<? super Void>> futureListeners) {}
}
} }
} }

View file

@ -1,140 +1,194 @@
package com.simibubi.create.content.contraptions.fluids; package com.simibubi.create.content.contraptions.fluids;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllShapes;
import com.simibubi.create.AllTileEntities; import com.simibubi.create.AllTileEntities;
import com.simibubi.create.content.contraptions.wrench.IWrenchable;
import com.simibubi.create.foundation.block.ITE;
import com.simibubi.create.foundation.fluid.FluidHelper;
import com.simibubi.create.foundation.fluid.FluidHelper.FluidExchange;
import com.simibubi.create.foundation.utility.Lang;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.item.BlockItemUseContext; import net.minecraft.block.SoundType;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.fluid.Fluid;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemUseContext;
import net.minecraft.particles.BlockParticleData;
import net.minecraft.particles.ParticleTypes;
import net.minecraft.state.BooleanProperty; import net.minecraft.state.BooleanProperty;
import net.minecraft.state.EnumProperty;
import net.minecraft.state.StateContainer.Builder; import net.minecraft.state.StateContainer.Builder;
import net.minecraft.tags.FluidTags;
import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Direction; import net.minecraft.util.ActionResultType;
import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.Hand;
import net.minecraft.util.IStringSerializable;
import net.minecraft.util.SoundCategory;
import net.minecraft.util.SoundEvent;
import net.minecraft.util.SoundEvents;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.shapes.ISelectionContext; import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.util.math.shapes.VoxelShape; import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.shapes.VoxelShapes; import net.minecraft.util.math.Vec3d;
import net.minecraft.world.IBlockReader; import net.minecraft.world.IBlockReader;
import net.minecraft.world.ILightReader; import net.minecraft.world.IWorldReader;
import net.minecraft.world.IWorld;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.fluids.FluidAttributes;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
import net.minecraftforge.fluids.capability.IFluidHandler;
import net.minecraftforge.fluids.capability.IFluidHandlerItem;
public class FluidTankBlock extends Block { public class FluidTankBlock extends Block implements IWrenchable, ITE<FluidTankTileEntity> {
public static final BooleanProperty TOP = BooleanProperty.create("top"); public static final BooleanProperty TOP = BooleanProperty.create("top");
public static final BooleanProperty BOTTOM = BooleanProperty.create("bottom"); public static final BooleanProperty BOTTOM = BooleanProperty.create("bottom");
public static final EnumProperty<Shape> SHAPE = EnumProperty.create("shape", Shape.class);
public FluidTankBlock(Properties p_i48440_1_) { public FluidTankBlock(Properties p_i48440_1_) {
super(p_i48440_1_); super(p_i48440_1_);
setDefaultState(getDefaultState().with(TOP, true) setDefaultState(getDefaultState().with(TOP, true)
.with(BOTTOM, true)); .with(BOTTOM, true)
} .with(SHAPE, Shape.WINDOW));
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)));
}
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);
} }
public static boolean isTank(BlockState state) { public static boolean isTank(BlockState state) {
return state.getBlock() instanceof FluidTankBlock; return state.getBlock() instanceof FluidTankBlock;
} }
@Override
public void onBlockAdded(BlockState state, World world, BlockPos pos, BlockState oldState, boolean p_220082_5_) {
if (oldState.getBlock() == state.getBlock())
return;
withTileEntityDo(world, pos, FluidTankTileEntity::updateConnectivity);
}
@Override @Override
protected void fillStateContainer(Builder<Block, BlockState> p_206840_1_) { protected void fillStateContainer(Builder<Block, BlockState> p_206840_1_) {
p_206840_1_.add(TOP, BOTTOM); p_206840_1_.add(TOP, BOTTOM, SHAPE);
} }
@Override @Override
public BlockState getStateForPlacement(BlockItemUseContext p_196258_1_) { public int getLightValue(BlockState state, IBlockReader world, BlockPos pos) {
World world = p_196258_1_.getWorld(); FluidTankTileEntity tankAt = FluidTankConnectivityHandler.tankAt(world, pos);
BlockPos pos = p_196258_1_.getPos(); if (tankAt == null)
BlockState state = super.getStateForPlacement(p_196258_1_); return 0;
state = updateState(state, world, pos, Direction.UP); FluidTankTileEntity controllerTE = tankAt.getControllerTE();
state = updateState(state, world, pos, Direction.DOWN); if (controllerTE == null || !controllerTE.window)
return state; return 0;
} return tankAt.luminosity;
private boolean isTankToDirection(IBlockReader world, BlockPos pos, Direction direction) {
return world.getBlockState(pos.offset(direction)).getBlock() instanceof FluidTankBlock;
}
public AxisAlignedBB getTankShape(IBlockReader world, BlockPos pos) {
return new AxisAlignedBB((isTankToDirection(world, pos, Direction.WEST) ? 0 : 2) / 16f,
(isTankToDirection(world, pos, Direction.DOWN) ? 0 : 4) / 16f,
(isTankToDirection(world, pos, Direction.NORTH) ? 0 : 2) / 16f,
(isTankToDirection(world, pos, Direction.EAST) ? 16 : 14) / 16f,
(isTankToDirection(world, pos, Direction.UP) ? 16 : 12) / 16f,
(isTankToDirection(world, pos, Direction.SOUTH) ? 16 : 14) / 16f);
}
public AxisAlignedBB getBodyShape(IBlockReader world, BlockPos pos) {
return new AxisAlignedBB((isTankToDirection(world, pos, Direction.WEST) ? 0 : 1) / 16f,
0,
(isTankToDirection(world, pos, Direction.NORTH) ? 0 : 1) / 16f,
(isTankToDirection(world, pos, Direction.EAST) ? 16 : 15) / 16f,
1,
(isTankToDirection(world, pos, Direction.SOUTH) ? 16 : 15) / 16f);
} }
@Override @Override
public VoxelShape getShape(BlockState state, IBlockReader world, BlockPos pos, public ActionResultType onWrenched(BlockState state, ItemUseContext context) {
ISelectionContext p_220053_4_) { withTileEntityDo(context.getWorld(), context.getPos(), FluidTankTileEntity::toggleWindows);
boolean top = state.get(TOP); return ActionResultType.SUCCESS;
boolean bottom = state.get(BOTTOM);
return VoxelShapes.or(top ? bottom ? AllShapes.TANK_TOP_BOTTOM : AllShapes.TANK_TOP
: bottom ? AllShapes.TANK_BOTTOM : AllShapes.TANK, VoxelShapes.create(getBodyShape(world, pos)));
} }
@Override @Override
public BlockState updatePostPlacement(BlockState state, Direction direction, BlockState p_196271_3_, IWorld world, public ActionResultType onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand,
BlockPos pos, BlockPos p_196271_6_) { BlockRayTraceResult ray) {
return updateState(state, world, pos, direction); ItemStack heldItem = player.getHeldItem(hand);
}
private BlockState updateState(BlockState state, ILightReader reader, BlockPos pos, Direction direction) { ItemStack copy = heldItem.copy();
if (direction.getAxis() copy.setCount(1);
.isHorizontal()) LazyOptional<IFluidHandlerItem> capability =
return state; copy.getCapability(CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY);
return state.with(direction == Direction.UP ? TOP : BOTTOM, if (!capability.isPresent())
!AllBlocks.FLUID_TANK.has(reader.getBlockState(pos.offset(direction)))); return ActionResultType.PASS;
}
@Override TileEntity te = world.getTileEntity(pos);
@OnlyIn(Dist.CLIENT) LazyOptional<IFluidHandler> tankCapability =
public boolean isSideInvisible(BlockState state, BlockState adjacentBlockState, Direction side) { te.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, ray.getFace());
return adjacentBlockState.getBlock() == this; if (!tankCapability.isPresent())
return ActionResultType.PASS;
boolean onClient = world.isRemote;
IFluidHandlerItem fluidItem = capability.orElse(null);
IFluidHandler fluidTank = tankCapability.orElse(null);
FluidStack prevFluidInTank = fluidTank.getFluidInTank(0)
.copy();
FluidExchange exchange = FluidHelper.exchange(fluidTank, fluidItem, FluidExchange.TANK_TO_ITEM, 1000);
FluidStack fluidInTank = fluidTank.getFluidInTank(0);
if (!player.isCreative() && !onClient) {
if (heldItem.getCount() > 1) {
heldItem.shrink(1);
player.addItemStackToInventory(fluidItem.getContainer());
} else {
player.setHeldItem(hand, fluidItem.getContainer());
}
}
SoundEvent soundevent = null;
BlockState fluidState = null;
if (exchange == FluidExchange.ITEM_TO_TANK) {
Fluid fluid = fluidInTank.getFluid();
fluidState = fluid.getDefaultState()
.getBlockState();
FluidAttributes attributes = fluid.getAttributes();
soundevent = attributes.getEmptySound();
if (soundevent == null)
soundevent =
fluid.isIn(FluidTags.LAVA) ? SoundEvents.ITEM_BUCKET_EMPTY_LAVA : SoundEvents.ITEM_BUCKET_EMPTY;
}
if (exchange == FluidExchange.TANK_TO_ITEM) {
Fluid fluid = prevFluidInTank.getFluid();
fluidState = fluid.getDefaultState()
.getBlockState();
soundevent = fluid.getAttributes()
.getFillSound();
if (soundevent == null)
soundevent =
fluid.isIn(FluidTags.LAVA) ? SoundEvents.ITEM_BUCKET_FILL_LAVA : SoundEvents.ITEM_BUCKET_FILL;
}
if (soundevent != null && !onClient) {
float pitch = MathHelper
.clamp(1 - (1f * fluidInTank.getAmount() / (FluidTankTileEntity.getCapacityMultiplier() * 16)), 0, 1);
pitch /= 1.5f;
pitch += .5f;
pitch += (world.rand.nextFloat() - .5f) / 4f;
world.playSound(null, pos, soundevent, SoundCategory.BLOCKS, .5f, pitch);
}
if (!fluidInTank.isFluidStackIdentical(prevFluidInTank)) {
if (te instanceof FluidTankTileEntity) {
FluidTankTileEntity controllerTE = ((FluidTankTileEntity) te).getControllerTE();
if (controllerTE != null) {
if (fluidState != null && onClient) {
BlockParticleData blockParticleData = new BlockParticleData(ParticleTypes.BLOCK, fluidState);
float level = (float) fluidInTank.getAmount() / fluidTank.getTankCapacity(0);
boolean reversed = fluidInTank.getFluid()
.getAttributes()
.isLighterThanAir();
if (reversed)
level = 1 - level;
Vec3d vec = ray.getHitVec();
vec = new Vec3d(vec.x, controllerTE.getPos()
.getY() + level * (controllerTE.height - .5f) + .25f, vec.z);
Vec3d motion = player.getPositionVec()
.subtract(vec)
.scale(1 / 20f);
vec = vec.add(motion);
world.addParticle(blockParticleData, vec.x, vec.y, vec.z, motion.x, motion.y, motion.z);
return ActionResultType.SUCCESS;
}
controllerTE.sendData();
controllerTE.markDirty();
}
}
}
return ActionResultType.SUCCESS;
} }
@Override @Override
@ -142,8 +196,48 @@ public class FluidTankBlock extends Block {
return true; return true;
} }
@Override
public void onReplaced(BlockState state, World world, BlockPos pos, BlockState newState, boolean isMoving) {
if (state.hasTileEntity() && (state.getBlock() != newState.getBlock() || !newState.hasTileEntity())) {
TileEntity te = world.getTileEntity(pos);
if (!(te instanceof FluidTankTileEntity))
return;
FluidTankTileEntity tankTE = (FluidTankTileEntity) te;
world.removeTileEntity(pos);
FluidTankConnectivityHandler.splitTank(tankTE);
}
}
@Override @Override
public TileEntity createTileEntity(BlockState state, IBlockReader world) { public TileEntity createTileEntity(BlockState state, IBlockReader world) {
return AllTileEntities.FLUID_TANK.create(); return AllTileEntities.FLUID_TANK.create();
} }
@Override
public Class<FluidTankTileEntity> getTileEntityClass() {
return FluidTankTileEntity.class;
}
public enum Shape implements IStringSerializable {
PLAIN, WINDOW, WINDOW_NW, WINDOW_SW, WINDOW_NE, WINDOW_SE;
@Override
public String getName() {
return Lang.asId(name());
}
}
// Tanks are less noisy when placed in batch
public static final SoundType SILENCED_METAL =
new SoundType(0.1F, 1.5F, SoundEvents.BLOCK_METAL_BREAK, SoundEvents.BLOCK_METAL_STEP,
SoundEvents.BLOCK_METAL_PLACE, SoundEvents.BLOCK_METAL_HIT, SoundEvents.BLOCK_METAL_FALL);
@Override
public SoundType getSoundType(BlockState state, IWorldReader world, BlockPos pos, Entity entity) {
SoundType soundType = super.getSoundType(state, world, pos, entity);
if (entity != null && entity.getPersistentData()
.contains("SilenceTankSound"))
return SILENCED_METAL;
return soundType;
}
} }

View file

@ -14,7 +14,6 @@ public class FluidTankCTBehaviour extends HorizontalCTBehaviour {
super(layerShift, topShift); super(layerShift, topShift);
} }
@Override
public boolean buildContextForOccludedDirections() { public boolean buildContextForOccludedDirections() {
return true; return true;
} }
@ -22,7 +21,6 @@ public class FluidTankCTBehaviour extends HorizontalCTBehaviour {
@Override @Override
public boolean connectsTo(BlockState state, BlockState other, ILightReader reader, BlockPos pos, BlockPos otherPos, public boolean connectsTo(BlockState state, BlockState other, ILightReader reader, BlockPos pos, BlockPos otherPos,
Direction face) { Direction face) {
// TODO only if TEs are actually connected return state.getBlock() == other.getBlock() && FluidTankConnectivityHandler.isConnected(reader, pos, otherPos);
return state.getBlock() == other.getBlock();
} }
} }

View file

@ -0,0 +1,347 @@
package com.simibubi.create.content.contraptions.fluids;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.PriorityQueue;
import java.util.Set;
import javax.annotation.Nullable;
import org.apache.commons.lang3.tuple.Pair;
import com.simibubi.create.foundation.utility.Iterate;
import net.minecraft.block.BlockState;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Direction;
import net.minecraft.util.Direction.Axis;
import net.minecraft.util.Direction.AxisDirection;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockReader;
import net.minecraft.world.World;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.capability.IFluidHandler.FluidAction;
public class FluidTankConnectivityHandler {
public static void formTanks(FluidTankTileEntity te) {
TankSearchCache cache = new TankSearchCache();
List<FluidTankTileEntity> frontier = new ArrayList<>();
frontier.add(te);
formTanks(te.getWorld(), cache, frontier);
}
private static void formTanks(IBlockReader world, TankSearchCache cache, List<FluidTankTileEntity> frontier) {
PriorityQueue<Pair<Integer, FluidTankTileEntity>> creationQueue = makeCreationQueue();
Set<BlockPos> visited = new HashSet<>();
int minX = Integer.MAX_VALUE;
int minZ = Integer.MAX_VALUE;
for (FluidTankTileEntity fluidTankTileEntity : frontier) {
BlockPos pos = fluidTankTileEntity.getPos();
minX = Math.min(pos.getX(), minX);
minZ = Math.min(pos.getZ(), minZ);
}
minX -= FluidTankTileEntity.getMaxSize();
minZ -= FluidTankTileEntity.getMaxSize();
while (!frontier.isEmpty()) {
FluidTankTileEntity tank = frontier.remove(0);
BlockPos tankPos = tank.getPos();
if (visited.contains(tankPos))
continue;
visited.add(tankPos);
int amount = tryToFormNewTank(tank, cache, true);
if (amount > 1)
creationQueue.add(Pair.of(amount, tank));
for (Axis axis : Iterate.axes) {
Direction d = Direction.getFacingFromAxis(AxisDirection.NEGATIVE, axis);
BlockPos next = tankPos.offset(d);
if (next.getX() <= minX || next.getZ() <= minZ)
continue;
if (visited.contains(next))
continue;
FluidTankTileEntity nextTank = tankAt(world, next);
if (nextTank == null)
continue;
if (nextTank.isRemoved())
continue;
frontier.add(nextTank);
}
}
visited.clear();
while (!creationQueue.isEmpty()) {
Pair<Integer, FluidTankTileEntity> next = creationQueue.poll();
FluidTankTileEntity toCreate = next.getValue();
if (visited.contains(toCreate.getPos()))
continue;
visited.add(toCreate.getPos());
tryToFormNewTank(toCreate, cache, false);
}
}
public static void splitTank(FluidTankTileEntity te) {
splitTankAndInvalidate(te, null, false);
}
private static int tryToFormNewTank(FluidTankTileEntity te, TankSearchCache cache, boolean simulate) {
int bestWidth = 1;
int bestAmount = -1;
if (!te.isController())
return 0;
for (int w = 1; w <= FluidTankTileEntity.getMaxSize(); w++) {
int amount = tryToFormNewTankOfWidth(te, w, cache, true);
if (amount < bestAmount)
continue;
bestWidth = w;
bestAmount = amount;
}
if (!simulate) {
if (te.width == bestWidth && te.width * te.width * te.height == bestAmount)
return bestAmount;
splitTankAndInvalidate(te, cache, false);
te.applyFluidTankSize(bestAmount);
tryToFormNewTankOfWidth(te, bestWidth, cache, simulate);
te.updateConnectivity = false;
te.width = bestWidth;
te.height = bestAmount / bestWidth / bestWidth;
BlockState state = te.getBlockState();
if (FluidTankBlock.isTank(state)) {
state = state.with(FluidTankBlock.BOTTOM, true);
state = state.with(FluidTankBlock.TOP, te.height == 1);
te.getWorld()
.setBlockState(te.getPos(), state, 22);
}
te.setWindows(te.window);
te.onFluidStackChanged(te.tankInventory.getFluid());
te.markDirty();
}
return bestAmount;
}
private static int tryToFormNewTankOfWidth(FluidTankTileEntity te, int width, TankSearchCache cache,
boolean simulate) {
int amount = 0;
int height = 0;
World world = te.getWorld();
BlockPos origin = te.getPos();
FluidStack fluid = te.getTankInventory()
.getFluid();
Search:
for (int yOffset = 0; yOffset < FluidTankTileEntity.getMaxHeight(); yOffset++) {
for (int xOffset = 0; xOffset < width; xOffset++) {
for (int zOffset = 0; zOffset < width; zOffset++) {
BlockPos pos = origin.add(xOffset, yOffset, zOffset);
Optional<FluidTankTileEntity> tank = cache.getOrCache(world, pos);
if (!tank.isPresent())
break Search;
FluidTankTileEntity controller = tank.get();
int otherWidth = controller.width;
if (otherWidth > width)
break Search;
BlockPos controllerPos = controller.getPos();
if (!controllerPos.equals(origin)) {
if (controllerPos.getX() < origin.getX())
break Search;
if (controllerPos.getZ() < origin.getZ())
break Search;
if (controllerPos.getX() + otherWidth > origin.getX() + width)
break Search;
if (controllerPos.getZ() + otherWidth > origin.getZ() + width)
break Search;
}
FluidStack otherFluid = controller.getTankInventory()
.getFluid();
if (!fluid.isEmpty() && !otherFluid.isEmpty() && !fluid.isFluidEqual(otherFluid))
break Search;
}
}
amount += width * width;
height++;
}
if (simulate)
return amount;
for (int yOffset = 0; yOffset < height; yOffset++) {
for (int xOffset = 0; xOffset < width; xOffset++) {
for (int zOffset = 0; zOffset < width; zOffset++) {
BlockPos pos = origin.add(xOffset, yOffset, zOffset);
FluidTankTileEntity tank = tankAt(world, pos);
if (tank == te)
continue;
if (tank.isController()) {
te.tankInventory.fill(tank.tankInventory.getFluid(), FluidAction.EXECUTE);
tank.tankInventory.setFluid(FluidStack.EMPTY);
}
splitTankAndInvalidate(tank, cache, false);
tank.setController(origin);
tank.updateConnectivity = false;
cache.put(pos, te);
BlockState state = world.getBlockState(pos);
if (!FluidTankBlock.isTank(state))
continue;
state = state.with(FluidTankBlock.BOTTOM, yOffset == 0);
state = state.with(FluidTankBlock.TOP, yOffset == height - 1);
world.setBlockState(pos, state, 22);
}
}
}
return amount;
}
private static void splitTankAndInvalidate(FluidTankTileEntity te, @Nullable TankSearchCache cache,
boolean tryReconnect) {
// tryReconnect helps whenever only few tanks have been removed
te = te.getControllerTE();
if (te == null)
return;
int height = te.height;
int width = te.width;
if (width == 1 && height == 1)
return;
World world = te.getWorld();
BlockPos origin = te.getPos();
List<FluidTankTileEntity> frontier = new ArrayList<>();
FluidStack toDistribute = te.tankInventory.getFluid()
.copy();
int maxCapacity = FluidTankTileEntity.getCapacityMultiplier();
if (!toDistribute.isEmpty())
toDistribute.shrink(maxCapacity);
for (int yOffset = 0; yOffset < height; yOffset++) {
for (int xOffset = 0; xOffset < width; xOffset++) {
for (int zOffset = 0; zOffset < width; zOffset++) {
BlockPos pos = origin.add(xOffset, yOffset, zOffset);
FluidTankTileEntity tankAt = tankAt(world, pos);
if (tankAt == null)
continue;
if (!tankAt.getController()
.equals(origin))
continue;
FluidTankTileEntity controllerTE = tankAt.getControllerTE();
tankAt.window = controllerTE == null || controllerTE.window;
tankAt.removeController();
if (!toDistribute.isEmpty() && tankAt != te) {
int split = Math.min(maxCapacity, toDistribute.getAmount());
FluidStack copy = toDistribute.copy();
copy.setAmount(split);
toDistribute.shrink(split);
tankAt.tankInventory.fill(copy, FluidAction.EXECUTE);
}
if (tryReconnect) {
frontier.add(tankAt);
tankAt.updateConnectivity = false;
}
if (cache != null)
cache.put(pos, tankAt);
}
}
}
if (tryReconnect)
formTanks(world, cache == null ? new TankSearchCache() : cache, frontier);
}
private static PriorityQueue<Pair<Integer, FluidTankTileEntity>> makeCreationQueue() {
return new PriorityQueue<>(new Comparator<Pair<Integer, FluidTankTileEntity>>() {
@Override
public int compare(Pair<Integer, FluidTankTileEntity> o1, Pair<Integer, FluidTankTileEntity> o2) {
return o2.getKey() - o1.getKey();
}
});
}
@Nullable
public static FluidTankTileEntity tankAt(IBlockReader world, BlockPos pos) {
TileEntity te = world.getTileEntity(pos);
if (te instanceof FluidTankTileEntity)
return (FluidTankTileEntity) te;
return null;
}
private static class TankSearchCache {
Map<BlockPos, Optional<FluidTankTileEntity>> controllerMap;
public TankSearchCache() {
controllerMap = new HashMap<>();
}
void put(BlockPos pos, FluidTankTileEntity target) {
controllerMap.put(pos, Optional.of(target));
}
void putEmpty(BlockPos pos) {
controllerMap.put(pos, Optional.empty());
}
boolean hasVisited(BlockPos pos) {
return controllerMap.containsKey(pos);
}
Optional<FluidTankTileEntity> getOrCache(IBlockReader world, BlockPos pos) {
if (hasVisited(pos))
return controllerMap.get(pos);
FluidTankTileEntity tankAt = tankAt(world, pos);
if (tankAt == null) {
putEmpty(pos);
return Optional.empty();
}
FluidTankTileEntity controller = tankAt.getControllerTE();
if (controller == null) {
putEmpty(pos);
return Optional.empty();
}
put(pos, controller);
return Optional.of(controller);
}
}
public static boolean isConnected(IBlockReader world, BlockPos tankPos, BlockPos otherTankPos) {
TileEntity te1 = world.getTileEntity(tankPos);
TileEntity te2 = world.getTileEntity(otherTankPos);
if (!(te1 instanceof FluidTankTileEntity) || !(te2 instanceof FluidTankTileEntity))
return false;
return ((FluidTankTileEntity) te1).getController()
.equals(((FluidTankTileEntity) te2).getController());
}
}

View file

@ -0,0 +1,44 @@
package com.simibubi.create.content.contraptions.fluids;
import com.simibubi.create.content.contraptions.fluids.FluidTankBlock.Shape;
import com.simibubi.create.foundation.data.AssetLookup;
import com.simibubi.create.foundation.data.SpecialBlockStateGen;
import com.tterrag.registrate.providers.DataGenContext;
import com.tterrag.registrate.providers.RegistrateBlockstateProvider;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraftforge.client.model.generators.ModelFile;
public class FluidTankGenerator extends SpecialBlockStateGen {
@Override
protected int getXRotation(BlockState state) {
return 0;
}
@Override
protected int getYRotation(BlockState state) {
return 0;
}
@Override
public <T extends Block> ModelFile getModel(DataGenContext<Block, T> ctx, RegistrateBlockstateProvider prov,
BlockState state) {
Boolean top = state.get(FluidTankBlock.TOP);
Boolean bottom = state.get(FluidTankBlock.BOTTOM);
Shape shape = state.get(FluidTankBlock.SHAPE);
String shapeName = "middle";
if (top && bottom)
shapeName = "single";
else if (top)
shapeName = "top";
else if (bottom)
shapeName = "bottom";
return AssetLookup.partialBaseModel(ctx, prov,
shapeName + (shape == Shape.PLAIN ? "" : "_" + shape.getName()));
}
}

View file

@ -0,0 +1,97 @@
package com.simibubi.create.content.contraptions.fluids;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.BlockItem;
import net.minecraft.item.BlockItemUseContext;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ActionResultType;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
public class FluidTankItem extends BlockItem {
public FluidTankItem(Block p_i48527_1_, Properties p_i48527_2_) {
super(p_i48527_1_, p_i48527_2_);
}
@Override
public ActionResultType tryPlace(BlockItemUseContext ctx) {
ActionResultType initialResult = super.tryPlace(ctx);
if (initialResult != ActionResultType.SUCCESS)
return initialResult;
tryMultiPlace(ctx);
return initialResult;
}
private void tryMultiPlace(BlockItemUseContext ctx) {
PlayerEntity player = ctx.getPlayer();
if (player == null)
return;
if (player.isSneaking())
return;
Direction face = ctx.getFace();
if (!face.getAxis()
.isVertical())
return;
ItemStack stack = ctx.getItem();
World world = ctx.getWorld();
BlockPos pos = ctx.getPos();
BlockPos placedOnPos = pos.offset(face.getOpposite());
BlockState placedOnState = world.getBlockState(placedOnPos);
if (!FluidTankBlock.isTank(placedOnState))
return;
FluidTankTileEntity tankAt = FluidTankConnectivityHandler.tankAt(world, placedOnPos);
if (tankAt == null)
return;
FluidTankTileEntity controllerTE = tankAt.getControllerTE();
if (controllerTE == null)
return;
int width = controllerTE.width;
if (width == 1)
return;
int tanksToPlace = 0;
BlockPos startPos = face == Direction.DOWN ? controllerTE.getPos()
.down()
: controllerTE.getPos()
.up(controllerTE.height);
if (startPos.getY() != pos.getY())
return;
for (int xOffset = 0; xOffset < width; xOffset++) {
for (int zOffset = 0; zOffset < width; zOffset++) {
BlockPos offsetPos = startPos.add(xOffset, 0, zOffset);
BlockState blockState = world.getBlockState(offsetPos);
if (FluidTankBlock.isTank(blockState))
continue;
if (!blockState.getMaterial()
.isReplaceable())
return;
tanksToPlace++;
}
}
if (!player.isCreative() && stack.getCount() < tanksToPlace)
return;
for (int xOffset = 0; xOffset < width; xOffset++) {
for (int zOffset = 0; zOffset < width; zOffset++) {
BlockPos offsetPos = startPos.add(xOffset, 0, zOffset);
BlockState blockState = world.getBlockState(offsetPos);
if (FluidTankBlock.isTank(blockState))
continue;
BlockItemUseContext context = BlockItemUseContext.func_221536_a(ctx, offsetPos, face);
player.getPersistentData().putBoolean("SilenceTankSound", true);
super.tryPlace(context);
player.getPersistentData().remove("SilenceTankSound");
}
}
}
}

View file

@ -1,12 +1,11 @@
package com.simibubi.create.content.contraptions.fluids; package com.simibubi.create.content.contraptions.fluids;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Random; import java.util.Random;
import org.apache.commons.lang3.tuple.Pair;
import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.AllSpriteShifts; import com.simibubi.create.AllSpriteShifts;
import com.simibubi.create.foundation.block.connected.CTModel; import com.simibubi.create.foundation.block.connected.CTModel;
import com.simibubi.create.foundation.block.connected.ConnectedTextureBehaviour; import com.simibubi.create.foundation.block.connected.ConnectedTextureBehaviour;
@ -19,86 +18,63 @@ import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.ILightReader; import net.minecraft.world.ILightReader;
import net.minecraftforge.client.model.data.IModelData; import net.minecraftforge.client.model.data.IModelData;
import net.minecraftforge.client.model.data.ModelDataMap;
import net.minecraftforge.client.model.data.ModelProperty; import net.minecraftforge.client.model.data.ModelProperty;
public class FluidTankModel extends CTModel { public class FluidTankModel extends CTModel {
private static ModelProperty<TankModelData> TANK_PROPERTY = new ModelProperty<>(); protected static ModelProperty<CullData> CULL_PROPERTY = new ModelProperty<>();
private static ConnectedTextureBehaviour ctBehaviour = static ConnectedTextureBehaviour CT_BEHAVIOUR =
new FluidTankCTBehaviour(AllSpriteShifts.FLUID_TANK, AllSpriteShifts.COPPER_CASING); new FluidTankCTBehaviour(AllSpriteShifts.FLUID_TANK, AllSpriteShifts.COPPER_CASING);
public FluidTankModel(IBakedModel model) { public FluidTankModel(IBakedModel originalModel) {
super(model, ctBehaviour); super(originalModel, CT_BEHAVIOUR);
} }
@Override @Override
public IModelData getModelData(ILightReader world, BlockPos pos, BlockState state, IModelData tileData) { public IModelData getModelData(ILightReader world, BlockPos pos, BlockState state, IModelData tileData) {
TankModelData data = new TankModelData(); CullData cullData = new CullData();
for (boolean top : Iterate.trueAndFalse) for (Direction d : Iterate.horizontalDirections)
for (Direction d : Iterate.horizontalDirections) cullData.setCulled(d, FluidTankConnectivityHandler.isConnected(world, pos, pos.offset(d)));
data.setCapFiller(d, top, FluidTankBlock.shouldDrawCapFiller(world, pos, state, d, top)); return getCTDataMapBuilder(world, pos, state).withInitial(CULL_PROPERTY, cullData)
for (boolean north : Iterate.trueAndFalse)
for (boolean east : Iterate.trueAndFalse)
data.setDiagonalFiller(north, east,
FluidTankBlock.shouldDrawDiagonalFiller(world, pos, state, north, east));
return new ModelDataMap.Builder().withInitial(CT_PROPERTY, createCTData(world, pos, state))
.withInitial(TANK_PROPERTY, data)
.build(); .build();
} }
@Override @Override
public List<BakedQuad> getQuads(BlockState state, Direction side, Random rand, IModelData data) { public List<BakedQuad> getQuads(BlockState state, Direction side, Random rand, IModelData extraData) {
List<BakedQuad> quads = super.getQuads(state, side, rand, data); if (side != null)
if (data instanceof ModelDataMap) { return Collections.emptyList();
ModelDataMap modelDataMap = (ModelDataMap) data;
if (modelDataMap.hasProperty(TANK_PROPERTY)) List<BakedQuad> quads = new ArrayList<>();
addQuads(quads, state, side, rand, modelDataMap, modelDataMap.getData(TANK_PROPERTY)); for (Direction d : Iterate.directions) {
if (extraData.hasProperty(CULL_PROPERTY) && extraData.getData(CULL_PROPERTY)
.isCulled(d))
continue;
quads.addAll(super.getQuads(state, d, rand, extraData));
} }
quads.addAll(super.getQuads(state, null, rand, extraData));
return quads; return quads;
} }
private void addQuads(List<BakedQuad> quads, BlockState state, Direction side, Random rand, IModelData data, private class CullData {
TankModelData pipeData) { boolean[] culledFaces;
for (boolean top : Iterate.trueAndFalse)
for (Direction d : Iterate.horizontalDirections)
if (pipeData.getCapFiller(d, top))
quads.addAll(AllBlockPartials.TANK_LID_FILLERS.get(Pair.of(top, d))
.get()
.getQuads(state, side, rand, data));
for (boolean north : Iterate.trueAndFalse)
for (boolean east : Iterate.trueAndFalse)
if (pipeData.getDiagonalFiller(north, east))
quads.addAll(AllBlockPartials.TANK_DIAGONAL_FILLERS.get(Pair.of(north, east))
.get()
.getQuads(state, side, rand, data));
}
private class TankModelData { public CullData() {
boolean[] capFillers; culledFaces = new boolean[4];
boolean[] diagonalFillers; Arrays.fill(culledFaces, false);
public TankModelData() {
capFillers = new boolean[2 * 4];
diagonalFillers = new boolean[2 * 2];
Arrays.fill(capFillers, false);
Arrays.fill(diagonalFillers, false);
} }
public void setCapFiller(Direction face, boolean top, boolean filler) { void setCulled(Direction face, boolean cull) {
capFillers[(top ? 0 : 4) + face.getHorizontalIndex()] = filler; if (face.getAxis()
.isVertical())
return;
culledFaces[face.getHorizontalIndex()] = cull;
} }
public void setDiagonalFiller(boolean north, boolean east, boolean filler) { boolean isCulled(Direction face) {
diagonalFillers[(north ? 0 : 2) + (east ? 0 : 1)] = filler; if (face.getAxis()
} .isVertical())
return false;
public boolean getCapFiller(Direction face, boolean top) { return culledFaces[face.getHorizontalIndex()];
return capFillers[(top ? 0 : 4) + face.getHorizontalIndex()];
}
public boolean getDiagonalFiller(boolean north, boolean east) {
return diagonalFillers[(north ? 0 : 2) + (east ? 0 : 1)];
} }
} }

View file

@ -1,216 +1,68 @@
package com.simibubi.create.content.contraptions.fluids; package com.simibubi.create.content.contraptions.fluids;
import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.vertex.IVertexBuilder; import com.simibubi.create.foundation.fluid.FluidRenderer;
import com.simibubi.create.foundation.gui.widgets.InterpolatedChasingValue;
import com.simibubi.create.foundation.tileEntity.renderer.SafeTileEntityRenderer; 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.Collections; import net.minecraft.client.renderer.IRenderTypeBuffer;
import java.util.List; import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
import net.minecraft.util.math.MathHelper;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.capability.templates.FluidTank;
public class FluidTankRenderer extends SafeTileEntityRenderer<FluidTankTileEntity> { public class FluidTankRenderer extends SafeTileEntityRenderer<FluidTankTileEntity> {
public FluidTankRenderer(TileEntityRendererDispatcher dispatcher) { public FluidTankRenderer(TileEntityRendererDispatcher dispatcher) {
super(dispatcher); super(dispatcher);
} }
private static int[] decomposeColor(int color) { @Override
int[] res = new int[4]; protected void renderSafe(FluidTankTileEntity te, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer,
res[0] = color >> 24 & 0xff; int light, int overlay) {
res[1] = color >> 16 & 0xff; if (!te.isController())
res[2] = color >> 8 & 0xff; return;
res[3] = color & 0xff; if (!te.window)
return res; return;
}
@Override InterpolatedChasingValue fluidLevel = te.fluidLevel;
protected void renderSafe(FluidTankTileEntity te, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer, if (fluidLevel == null)
int light, int overlay) { return;
renderFluid(te, ms, buffer, light);
}
private void renderFluid(FluidTankTileEntity te, MatrixStack ms, IRenderTypeBuffer buffer, float capHeight = 1 / 4f;
int light) { float tankHullWidth = 1 / 16f + 1 / 128f;
if (te.getWorld() != null && te.getWorld().isAreaLoaded(te.getPos(), 0)) { float minPuddleHeight = 1 / 16f;
IVertexBuilder builder = buffer.getBuffer(RenderType.getTranslucent()); float totalHeight = te.height - 2 * capHeight - minPuddleHeight;
Matrix4f posMat = ms.peek().getModel(); float level = fluidLevel.get(partialTicks);
for (FluidTankRenderInfo tankRenderInfo : getTanksToRender(te)) { if (level < 1 / (512f * totalHeight))
doRender(builder, tankRenderInfo, posMat, light); return;
} float clamp = MathHelper.clamp(level * totalHeight, 0, totalHeight);
}
}
private void doRender(IVertexBuilder builder, FluidTankRenderInfo tankRenderInfo, Matrix4f posMat, int combinedLight) { FluidTank tank = te.tankInventory;
IFluidTank tank = tankRenderInfo.getTank(); FluidStack fluidStack = tank.getFluid();
if (tank.getFluidAmount() == 0) return;
Fluid fluid = tank.getFluid().getFluid(); boolean top = fluidStack.getFluid()
ResourceLocation texture = fluid.getAttributes().getStillTexture(tank.getFluid()); .getAttributes()
.isLighterThanAir();
@SuppressWarnings("deprecation") float xMin = tankHullWidth;
TextureAtlasSprite still = Minecraft.getInstance().getSpriteAtlas(AtlasTexture.LOCATION_BLOCKS_TEXTURE).apply(texture); float xMax = xMin + te.width - 2 * tankHullWidth;
int[] cols = decomposeColor(fluid.getAttributes().getColor(tank.getFluid())); float yMin = totalHeight + capHeight + minPuddleHeight - clamp;
float yMax = yMin + clamp;
AxisAlignedBB bounds = getRenderBounds(tank, tankRenderInfo.getBounds()); if (top) {
float x1 = (float) bounds.minX; yMin += totalHeight - clamp;
float x2 = (float) bounds.maxX; yMax += totalHeight - clamp;
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 zMin = tankHullWidth;
float u1 = still.getInterpolatedU(bx1); float zMax = zMin + te.width - 2 * tankHullWidth;
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)) { ms.push();
float u1 = still.getInterpolatedU(bx1); ms.translate(0, clamp - totalHeight, 0);
float u2 = still.getInterpolatedU(bx2); FluidRenderer.renderTiledFluidBB(fluidStack, xMin, yMin, zMin, xMax, yMax, zMax, buffer, ms, light, false);
float v1 = still.getInterpolatedV(bz1); ms.pop();
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) {
double percent = (double) tank.getFluidAmount() / (double) tank.getCapacity();
double y1 = tankBounds.minY;
double y2 = tank.getFluidAmount() < tank.getCapacity() ? (4 + 8 * percent) / 16f : 1f;
if (tank.getFluid().getFluid().getAttributes().isLighterThanAir()) {
double yOff = tankBounds.maxY - y2; // FIXME: lighter than air fluids move to the top of the tank, add behavior in TE
y1 += yOff;
y2 += yOff;
}
return new AxisAlignedBB(tankBounds.minX, y1, tankBounds.minZ, tankBounds.maxX, y2, tankBounds.maxZ);
}
private List<FluidTankRenderInfo> getTanksToRender(FluidTankTileEntity te) {
return Collections.singletonList(new FluidTankRenderInfo(te, ((FluidTankBlock) te.getBlockState().getBlock()).getTankShape(te.getWorld(), te.getPos())));
}
private static class FluidTankRenderInfo {
private final IFluidTank tank;
private final AxisAlignedBB bounds;
private final FluidTankTileEntity te;
FluidTankRenderInfo(FluidTankTileEntity te, AxisAlignedBB bounds) {
this.te = te;
this.bounds = bounds;
this.tank = te.getTank();
}
public boolean shouldRender(Direction face) {
FluidTankTileEntity offsetTE = te.getOtherFluidTankTileEntity(face);
switch (face) {
case UP:
return (offsetTE != null && (offsetTE.getTank().getFluidAmount() == 0 || te.getTank().getFluid().getRawFluid() != offsetTE.getTank().getFluid().getRawFluid()))
|| getTank().getFluidAmount() < getTank().getCapacity()
&& !getTank().getFluid().getFluid().getAttributes().isLighterThanAir();
case DOWN:
return (offsetTE != null && (offsetTE.getTank().getFluidAmount() < offsetTE.getTank().getCapacity() || te.getTank().getFluid().getRawFluid() != offsetTE.getTank().getFluid().getRawFluid()))
|| getTank().getFluidAmount() < getTank().getCapacity()
&& getTank().getFluid().getFluid().getAttributes().isLighterThanAir();
default:
return offsetTE == null || te.getTank().getFluid().getRawFluid() != offsetTE.getTank().getFluid().getRawFluid();
}
}
public IFluidTank getTank() {
return tank;
}
public AxisAlignedBB getBounds() {
return bounds;
}
}
} }

View file

@ -1,158 +1,361 @@
package com.simibubi.create.content.contraptions.fluids; package com.simibubi.create.content.contraptions.fluids;
import com.simibubi.create.foundation.tileEntity.SmartTileEntity; import static java.lang.Math.abs;
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
import net.minecraft.nbt.CompoundNBT; import java.util.List;
import net.minecraft.tileentity.TileEntity;
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.IFluidHandler.FluidAction;
import net.minecraftforge.fluids.capability.templates.FluidTank;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.List;
import com.simibubi.create.content.contraptions.fluids.FluidTankBlock.Shape;
import com.simibubi.create.foundation.config.AllConfigs;
import com.simibubi.create.foundation.fluid.SmartFluidTank;
import com.simibubi.create.foundation.gui.widgets.InterpolatedChasingValue;
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
import net.minecraft.block.BlockState;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.nbt.NBTUtil;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.tileentity.TileEntityType;
import net.minecraft.util.Direction;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.fluids.FluidAttributes;
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.IFluidHandler.FluidAction;
import net.minecraftforge.fluids.capability.templates.FluidTank;
public class FluidTankTileEntity extends SmartTileEntity { public class FluidTankTileEntity extends SmartTileEntity {
LazyOptional<FluidTank> fluid = LazyOptional.of(this::createFluidHandler); private static final int MAX_SIZE = 3;
private int priority = 1000;
public FluidTankTileEntity(TileEntityType<?> tileEntityTypeIn) { protected LazyOptional<IFluidHandler> fluidCapability;
super(tileEntityTypeIn); protected boolean forceFluidLevelUpdate;
} protected FluidTank tankInventory;
protected BlockPos controller;
protected boolean updateConnectivity;
protected boolean window;
protected int luminosity;
protected int width;
protected int height;
private int calculateDrainAmount(FluidTankTileEntity other, int delta) { // For rendering purposes only
boolean roundDirection = other.getPriority() < this.getPriority(); InterpolatedChasingValue fluidLevel;
return (int) Math.abs(roundDirection ? Math.floor(delta / 2f) : Math.ceil(delta / 2f));
}
@Override public FluidTankTileEntity(TileEntityType<?> tileEntityTypeIn) {
public void tick() { super(tileEntityTypeIn);
super.tick(); tankInventory = new SmartFluidTank(getCapacityMultiplier(), this::onFluidStackChanged);
updatePriority(); fluidCapability = LazyOptional.of(() -> tankInventory);
forceFluidLevelUpdate = true;
updateConnectivity = false;
window = true;
height = 1;
width = 1;
}
FluidTankTileEntity other; protected void updateConnectivity() {
updateConnectivity = false;
if (world.isRemote)
return;
if (!isController())
return;
FluidTankConnectivityHandler.formTanks(this);
}
other = getOtherFluidTankTileEntity(Direction.NORTH); @Override
public void tick() {
super.tick();
if (updateConnectivity)
updateConnectivity();
if (fluidLevel != null)
fluidLevel.tick();
}
if (other != null && other.getTank().isFluidValid(this.getTank().getFluid())) { public boolean isController() {
int delta = other.getTank().getFluidAmount() - this.getTank().getFluidAmount(); return controller == null || controller.equals(pos);
if (delta > 0) { }
this.getTank().fill(other.getTank().drain(calculateDrainAmount(other, delta), FluidAction.EXECUTE), FluidAction.EXECUTE);
other.markDirty();
this.markDirty();
other.sendData();
sendData();
} else if (delta < 0) {
other.getTank().fill(this.getTank().drain(calculateDrainAmount(other, delta), FluidAction.EXECUTE), FluidAction.EXECUTE);
other.markDirty();
this.markDirty();
other.sendData();
sendData();
}
}
@Override
public void initialize() {
super.initialize();
sendData();
}
other = getOtherFluidTankTileEntity(Direction.WEST); protected void onFluidStackChanged(FluidStack newFluidStack) {
if (other != null && other.getTank().isFluidValid(this.getTank().getFluid())) { if (!hasWorld())
int delta = other.getTank().getFluidAmount() - this.getTank().getFluidAmount(); return;
if (delta > 0) {
this.getTank().fill(other.getTank().drain(calculateDrainAmount(other, delta), FluidAction.EXECUTE), FluidAction.EXECUTE);
other.markDirty();
this.markDirty();
other.sendData();
sendData();
} else if (delta < 0) {
other.getTank().fill(this.getTank().drain(calculateDrainAmount(other, delta), FluidAction.EXECUTE), FluidAction.EXECUTE);
other.markDirty();
this.markDirty();
other.sendData();
sendData();
}
}
other = getOtherFluidTankTileEntity(Direction.UP); FluidAttributes attributes = newFluidStack.getFluid()
if (other != null && other.getTank().isFluidValid(this.getTank().getFluid())) { .getAttributes();
int space = this.getTank().getCapacity() - this.getTank().getFluidAmount(); int luminosity = attributes.getLuminosity(newFluidStack) / 2;
if (space > 0 && other.getTank().getFluidAmount() > 0) { boolean reversed = attributes.isLighterThanAir();
this.getTank().fill(other.getTank().drain(space, FluidAction.EXECUTE), FluidAction.EXECUTE); int maxY = (int) ((getFillState() * height) + 1);
other.markDirty();
this.markDirty();
other.sendData();
sendData();
}
}
}
@Nullable for (int yOffset = 0; yOffset < height; yOffset++) {
public FluidTankTileEntity getOtherFluidTankTileEntity(Direction direction) { boolean isBright = reversed ? (height - yOffset <= maxY) : (yOffset < maxY);
TileEntity otherTE = world.getTileEntity(pos.offset(direction)); int actualLuminosity = isBright ? luminosity : luminosity > 0 ? 1 : 0;
if (otherTE instanceof FluidTankTileEntity)
return (FluidTankTileEntity) otherTE;
return null;
}
@Nonnull for (int xOffset = 0; xOffset < width; xOffset++) {
@Override for (int zOffset = 0; zOffset < width; zOffset++) {
public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, @Nullable Direction side) { BlockPos pos = this.pos.add(xOffset, yOffset, zOffset);
if (cap == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) { FluidTankTileEntity tankAt = FluidTankConnectivityHandler.tankAt(world, pos);
return fluid.cast(); if (tankAt == null)
} continue;
return super.getCapability(cap, side); if (tankAt.luminosity == actualLuminosity)
} continue;
tankAt.setLuminosity(actualLuminosity);
}
}
}
}
@Override protected void setLuminosity(int luminosity) {
public void read(CompoundNBT tag) { if (world.isRemote)
fluid.ifPresent(h -> h.readFromNBT(tag)); return;
super.read(tag); if (this.luminosity == luminosity)
} return;
this.luminosity = luminosity;
sendData();
}
@Override public FluidTankTileEntity getControllerTE() {
public CompoundNBT write(CompoundNBT tag) { if (isController())
fluid.ifPresent(h -> h.writeToNBT(tag)); return this;
return super.write(tag); TileEntity tileEntity = world.getTileEntity(controller);
} if (tileEntity instanceof FluidTankTileEntity)
return (FluidTankTileEntity) tileEntity;
return null;
}
@Override public void applyFluidTankSize(int blocks) {
public void addBehaviours(List<TileEntityBehaviour> behaviours) { tankInventory.setCapacity(blocks * getCapacityMultiplier());
} int overflow = tankInventory.getFluidAmount() - tankInventory.getCapacity();
if (overflow > 0)
tankInventory.drain(overflow, FluidAction.EXECUTE);
forceFluidLevelUpdate = true;
}
@Nonnull public void removeController() {
public FluidTank createFluidHandler() { if (world.isRemote)
return new FluidTank(16000); return;
} updateConnectivity = true;
applyFluidTankSize(1);
controller = null;
width = 1;
height = 1;
onFluidStackChanged(tankInventory.getFluid());
public IFluidTank getTank() { BlockState state = getBlockState();
return fluid.orElseGet(this::createFluidHandler); if (FluidTankBlock.isTank(state)) {
} state = state.with(FluidTankBlock.BOTTOM, true);
state = state.with(FluidTankBlock.TOP, true);
state = state.with(FluidTankBlock.SHAPE, window ? Shape.WINDOW : Shape.PLAIN);
getWorld().setBlockState(pos, state, 22);
}
private void updatePriority() { markDirty();
FluidTankTileEntity other = getOtherFluidTankTileEntity(Direction.DOWN); sendData();
priority = 1000; }
if (other != null) {
priority = 0;
return;
}
updatePriorityFrom(Direction.SOUTH); public void toggleWindows() {
updatePriorityFrom(Direction.NORTH); FluidTankTileEntity te = getControllerTE();
updatePriorityFrom(Direction.WEST); if (te == null)
updatePriorityFrom(Direction.EAST); return;
} te.setWindows(!te.window);
}
private void updatePriorityFrom(Direction direction) { public void setWindows(boolean window) {
FluidTankTileEntity other = getOtherFluidTankTileEntity(direction); this.window = window;
if (other != null && other.getPriority() + 1 < priority) { for (int yOffset = 0; yOffset < height; yOffset++) {
priority = other.getPriority() + 1; for (int xOffset = 0; xOffset < width; xOffset++) {
} for (int zOffset = 0; zOffset < width; zOffset++) {
}
BlockPos pos = this.pos.add(xOffset, yOffset, zOffset);
BlockState blockState = world.getBlockState(pos);
if (!FluidTankBlock.isTank(blockState))
continue;
Shape shape = Shape.PLAIN;
if (window) {
// SIZE 1: Every tank has a window
if (width == 1)
shape = Shape.WINDOW;
// SIZE 2: Every tank has a corner window
if (width == 2)
shape = xOffset == 0 ? zOffset == 0 ? Shape.WINDOW_NW : Shape.WINDOW_SW
: zOffset == 0 ? Shape.WINDOW_NE : Shape.WINDOW_SE;
// SIZE 3: Tanks in the center have a window
if (width == 3 && abs(abs(xOffset) - abs(zOffset)) == 1)
shape = Shape.WINDOW;
}
world.setBlockState(pos, blockState.with(FluidTankBlock.SHAPE, shape), 22);
world.getChunkProvider()
.getLightManager()
.checkBlock(pos);
}
}
}
}
public void setController(BlockPos controller) {
if (world.isRemote)
return;
if (controller.equals(this.controller))
return;
this.controller = controller;
markDirty();
sendData();
}
public BlockPos getController() {
return isController() ? pos : controller;
}
@Override
@OnlyIn(Dist.CLIENT)
public AxisAlignedBB getRenderBoundingBox() {
return super.getRenderBoundingBox().expand(width - 1, height - 1, width - 1);
}
@Nullable
public FluidTankTileEntity getOtherFluidTankTileEntity(Direction direction) {
TileEntity otherTE = world.getTileEntity(pos.offset(direction));
if (otherTE instanceof FluidTankTileEntity)
return (FluidTankTileEntity) otherTE;
return null;
}
@Override
public void read(CompoundNBT tag) {
super.read(tag);
updateConnectivity = tag.contains("Uninitialized");
luminosity = tag.getInt("Luminosity");
controller = null;
if (tag.contains("Controller"))
controller = NBTUtil.readBlockPos(tag.getCompound("Controller"));
if (isController()) {
window = tag.getBoolean("Window");
width = tag.getInt("Size");
height = tag.getInt("Height");
tankInventory.setCapacity(getTotalTankSize() * getCapacityMultiplier());
tankInventory.readFromNBT(tag.getCompound("TankContent"));
if (tankInventory.getSpace() < 0)
tankInventory.drain(-tankInventory.getSpace(), FluidAction.EXECUTE);
}
if (tag.contains("ForceFluidLevel") || fluidLevel == null)
fluidLevel = new InterpolatedChasingValue().start(getFillState())
.withSpeed(1 / 2f);
}
@Override
public void readClientUpdate(CompoundNBT tag) {
BlockPos controllerBefore = controller;
int prevSize = width;
int prevHeight = height;
int prevLum = luminosity;
super.readClientUpdate(tag);
boolean changeOfController =
controllerBefore == null ? controller != null : !controllerBefore.equals(controller);
if (changeOfController || prevSize != width || prevHeight != height) {
if (hasWorld())
world.notifyBlockUpdate(getPos(), getBlockState(), getBlockState(), 16);
if (isController())
tankInventory.setCapacity(getCapacityMultiplier() * getTotalTankSize());
}
if (isController()) {
float fillState = getFillState();
if (tag.contains("ForceFluidLevel") || fluidLevel == null)
fluidLevel = new InterpolatedChasingValue().start(fillState)
.withSpeed(1 / 2f);
fluidLevel.target(fillState);
}
if (luminosity != prevLum && hasWorld())
world.getChunkProvider()
.getLightManager()
.checkBlock(pos);
}
protected float getFillState() {
return (float) tankInventory.getFluidAmount() / tankInventory.getCapacity();
}
@Override
public CompoundNBT write(CompoundNBT tag) {
if (updateConnectivity)
tag.putBoolean("Uninitialized", true);
if (!isController())
tag.put("Controller", NBTUtil.writeBlockPos(controller));
if (isController()) {
tag.putBoolean("Window", window);
tag.put("TankContent", tankInventory.writeToNBT(new CompoundNBT()));
tag.putInt("Size", width);
tag.putInt("Height", height);
}
tag.putInt("Luminosity", luminosity);
return super.write(tag);
}
@Override
public CompoundNBT writeToClient(CompoundNBT compound) {
if (forceFluidLevelUpdate)
compound.putBoolean("ForceFluidLevel", true);
forceFluidLevelUpdate = false;
return super.writeToClient(compound);
}
@Nonnull
@Override
public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, @Nullable Direction side) {
if (cap == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) {
FluidTankTileEntity controller = getControllerTE();
if (controller != null)
return controller.fluidCapability.cast();
}
return super.getCapability(cap, side);
}
@Override
public void remove() {
super.remove();
fluidCapability.invalidate();
}
@Override
public void addBehaviours(List<TileEntityBehaviour> behaviours) {}
public IFluidTank getTankInventory() {
return tankInventory;
}
public int getTotalTankSize() {
return width * width * height;
}
public static int getMaxSize() {
return MAX_SIZE;
}
protected static int getCapacityMultiplier() {
return AllConfigs.SERVER.fluids.fluidTankCapacity.get() * 1000;
}
public static int getMaxHeight() {
return AllConfigs.SERVER.fluids.fluidTankMaxHeight.get();
}
public int getPriority() {
return priority;
}
} }

View file

@ -19,6 +19,7 @@ import net.minecraft.world.ILightReader;
import net.minecraftforge.client.model.BakedModelWrapper; import net.minecraftforge.client.model.BakedModelWrapper;
import net.minecraftforge.client.model.data.IModelData; import net.minecraftforge.client.model.data.IModelData;
import net.minecraftforge.client.model.data.ModelDataMap; import net.minecraftforge.client.model.data.ModelDataMap;
import net.minecraftforge.client.model.data.ModelDataMap.Builder;
import net.minecraftforge.client.model.data.ModelProperty; import net.minecraftforge.client.model.data.ModelProperty;
public class CTModel extends BakedModelWrapper<IBakedModel> { public class CTModel extends BakedModelWrapper<IBakedModel> {
@ -50,8 +51,11 @@ public class CTModel extends BakedModelWrapper<IBakedModel> {
@Override @Override
public IModelData getModelData(ILightReader world, BlockPos pos, BlockState state, IModelData tileData) { public IModelData getModelData(ILightReader world, BlockPos pos, BlockState state, IModelData tileData) {
return new ModelDataMap.Builder().withInitial(CT_PROPERTY, createCTData(world, pos, state)) return getCTDataMapBuilder(world, pos, state).build();
.build(); }
protected Builder getCTDataMapBuilder(ILightReader world, BlockPos pos, BlockState state) {
return new ModelDataMap.Builder().withInitial(CT_PROPERTY, createCTData(world, pos, state));
} }
protected CTData createCTData(ILightReader world, BlockPos pos, BlockState state) { protected CTData createCTData(ILightReader world, BlockPos pos, BlockState state) {

View file

@ -16,16 +16,17 @@ public abstract class CTSpriteShiftEntry extends SpriteShiftEntry {
public float getTargetU(float localU, int index) { public float getTargetU(float localU, int index) {
float uOffset = (index % textureSheetSize); float uOffset = (index % textureSheetSize);
return getTarget().getInterpolatedU( return getTarget().getInterpolatedU(
(SuperByteBuffer.getUnInterpolatedU(getOriginal(), localU) + (uOffset * 16)) / ((float) textureSheetSize)); (SuperByteBuffer.getUnInterpolatedU(getOriginal(), localU) + (uOffset * 16)) / ((float) textureSheetSize));
} }
public float getTargetV(float localV, int index) { public float getTargetV(float localV, int index) {
float vOffset = (index / textureSheetSize); float vOffset = (index / textureSheetSize);
return getTarget().getInterpolatedV( return getTarget().getInterpolatedV(
(SuperByteBuffer.getUnInterpolatedV(getOriginal(), localV) + (vOffset * 16)) / ((float) textureSheetSize)); (SuperByteBuffer.getUnInterpolatedV(getOriginal(), localV) + (vOffset * 16)) / ((float) textureSheetSize));
} }
public abstract int getTextureIndex(CTContext context); public abstract int getTextureIndex(CTContext context);
public abstract CTType getType(); public abstract CTType getType();
public static class Horizontal extends CTSpriteShiftEntry { public static class Horizontal extends CTSpriteShiftEntry {
@ -64,6 +65,24 @@ public abstract class CTSpriteShiftEntry extends SpriteShiftEntry {
} }
public static class Cross extends CTSpriteShiftEntry {
public Cross() {
super(4);
}
@Override
public int getTextureIndex(CTContext context) {
return (context.up ? 1 : 0) + (context.down ? 2 : 0) + (context.left ? 4 : 0) + (context.right ? 8 : 0);
}
@Override
public CTType getType() {
return CTType.CROSS;
}
}
public static class Omnidirectional extends CTSpriteShiftEntry { public static class Omnidirectional extends CTSpriteShiftEntry {
public Omnidirectional() { public Omnidirectional() {
@ -125,7 +144,7 @@ public abstract class CTSpriteShiftEntry extends SpriteShiftEntry {
if (borders == 2) { if (borders == 2) {
if ((c.up && c.left && c.topLeft) || (c.down && c.left && c.bottomLeft) if ((c.up && c.left && c.topLeft) || (c.down && c.left && c.bottomLeft)
|| (c.up && c.right && c.topRight) || (c.down && c.right && c.bottomRight)) || (c.up && c.right && c.topRight) || (c.down && c.right && c.bottomRight))
tileX += 3; tileX += 3;
} }

View file

@ -8,7 +8,7 @@ import net.minecraft.util.ResourceLocation;
public class CTSpriteShifter extends SpriteShifter { public class CTSpriteShifter extends SpriteShifter {
public enum CTType { public enum CTType {
OMNIDIRECTIONAL, HORIZONTAL, VERTICAL; OMNIDIRECTIONAL, HORIZONTAL, VERTICAL, CROSS;
} }
public static CTSpriteShiftEntry getCT(CTType type, String blockTextureName) { public static CTSpriteShiftEntry getCT(CTType type, String blockTextureName) {
@ -42,6 +42,8 @@ public class CTSpriteShifter extends SpriteShifter {
return new CTSpriteShiftEntry.Omnidirectional(); return new CTSpriteShiftEntry.Omnidirectional();
case VERTICAL: case VERTICAL:
return new CTSpriteShiftEntry.Vertical(); return new CTSpriteShiftEntry.Vertical();
case CROSS:
return new CTSpriteShiftEntry.Cross();
default: default:
return null; return null;
} }

View file

@ -0,0 +1,20 @@
package com.simibubi.create.foundation.config;
public class CFluids extends ConfigBase {
public ConfigInt fluidTankCapacity = i(8, 1, "fluidTankCapacity", Comments.buckets, Comments.fluidTankCapacity);
public ConfigInt fluidTankMaxHeight = i(32, 1, "fluidTankMaxHeight", Comments.blocks, Comments.fluidTankMaxHeight);
@Override
public String getName() {
return "fluids";
}
private static class Comments {
static String blocks = "[in Blocks]";
static String buckets = "[in Buckets]";
static String fluidTankCapacity = "The amount of liquid a tank can hold per block.";
static String fluidTankMaxHeight = "The maximum height a fluid tank can reach.";
}
}

View file

@ -7,6 +7,7 @@ public class CServer extends ConfigBase {
i(20, 5, "tickrateSyncTimer", "[in Ticks]", Comments.tickrateSyncTimer, Comments.tickrateSyncTimer2); i(20, 5, "tickrateSyncTimer", "[in Ticks]", Comments.tickrateSyncTimer, Comments.tickrateSyncTimer2);
public CKinetics kinetics = nested(0, CKinetics::new, Comments.kinetics); public CKinetics kinetics = nested(0, CKinetics::new, Comments.kinetics);
public CFluids fluids = nested(0, CFluids::new, Comments.fluids);
public CLogistics logistics = nested(0, CLogistics::new, Comments.logistics); public CLogistics logistics = nested(0, CLogistics::new, Comments.logistics);
public CSchematics schematics = nested(0, CSchematics::new, Comments.schematics); public CSchematics schematics = nested(0, CSchematics::new, Comments.schematics);
public CCuriosities curiosities = nested(0, CCuriosities::new, Comments.curiosities); public CCuriosities curiosities = nested(0, CCuriosities::new, Comments.curiosities);
@ -20,6 +21,7 @@ public class CServer extends ConfigBase {
private static class Comments { private static class Comments {
static String schematics = "Everything related to Schematic tools"; static String schematics = "Everything related to Schematic tools";
static String kinetics = "Parameters and abilities of Create's kinetic mechanisms"; static String kinetics = "Parameters and abilities of Create's kinetic mechanisms";
static String fluids = "Create's liquid manipulation tools";
static String logistics = "Tweaks for logistical components"; static String logistics = "Tweaks for logistical components";
static String curiosities = "Gadgets and other Shenanigans added by Create"; static String curiosities = "Gadgets and other Shenanigans added by Create";
static String control = "You can try inhibiting related game mechanics for troubleshooting repeated crashes."; static String control = "You can try inhibiting related game mechanics for troubleshooting repeated crashes.";

View file

@ -20,7 +20,6 @@ import com.simibubi.create.content.contraptions.components.structureMovement.mou
import com.simibubi.create.content.contraptions.components.structureMovement.mounted.CartAssemblerBlock; import com.simibubi.create.content.contraptions.components.structureMovement.mounted.CartAssemblerBlock;
import com.simibubi.create.content.contraptions.components.tracks.ReinforcedRailBlock; import com.simibubi.create.content.contraptions.components.tracks.ReinforcedRailBlock;
import com.simibubi.create.content.contraptions.fluids.FluidPipeBlock; import com.simibubi.create.content.contraptions.fluids.FluidPipeBlock;
import com.simibubi.create.content.contraptions.fluids.FluidTankBlock;
import com.simibubi.create.content.contraptions.processing.HeaterBlock; import com.simibubi.create.content.contraptions.processing.HeaterBlock;
import com.simibubi.create.content.logistics.block.belts.observer.BeltObserverBlock; import com.simibubi.create.content.logistics.block.belts.observer.BeltObserverBlock;
import com.simibubi.create.content.palettes.PavedBlock; import com.simibubi.create.content.palettes.PavedBlock;
@ -475,23 +474,4 @@ public class BlockStateGen {
.end(); .end();
} }
public static <P extends FluidTankBlock> NonNullBiConsumer<DataGenContext<Block, P>, RegistrateBlockstateProvider> tank() {
return (c, p) -> {
p.getMultipartBuilder(c.get())
.part()
.modelFile(AssetLookup.partialBaseModel(c, p, "top"))
.addModel()
.condition(FluidTankBlock.TOP, true)
.end()
.part()
.modelFile(AssetLookup.partialBaseModel(c, p, "windows"))
.addModel()
.end()
.part()
.modelFile(AssetLookup.partialBaseModel(c, p, "bottom"))
.addModel()
.condition(FluidTankBlock.BOTTOM, true)
.end();
};
}
} }

View file

@ -0,0 +1,91 @@
package com.simibubi.create.foundation.fluid;
import javax.annotation.Nullable;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.capability.IFluidHandler;
import net.minecraftforge.fluids.capability.IFluidHandler.FluidAction;
import net.minecraftforge.fluids.capability.IFluidHandlerItem;
public class FluidHelper {
public static enum FluidExchange {
ITEM_TO_TANK, TANK_TO_ITEM;
}
@Nullable
public static FluidExchange exchange(IFluidHandler fluidTank, IFluidHandlerItem fluidItem, FluidExchange preferred,
int maxAmount) {
return exchange(fluidTank, fluidItem, preferred, true, maxAmount);
}
@Nullable
public static FluidExchange exchangeAll(IFluidHandler fluidTank, IFluidHandlerItem fluidItem,
FluidExchange preferred) {
return exchange(fluidTank, fluidItem, preferred, false, Integer.MAX_VALUE);
}
@Nullable
private static FluidExchange exchange(IFluidHandler fluidTank, IFluidHandlerItem fluidItem, FluidExchange preferred,
boolean singleOp, int maxTransferAmountPerTank) {
// Locks in the transfer direction of this operation
FluidExchange lockedExchange = null;
for (int tankSlot = 0; tankSlot < fluidTank.getTanks(); tankSlot++) {
for (int slot = 0; slot < fluidItem.getTanks(); slot++) {
FluidStack fluidInTank = fluidTank.getFluidInTank(tankSlot);
int tankCapacity = fluidTank.getTankCapacity(tankSlot) - fluidInTank.getAmount();
boolean tankEmpty = fluidInTank.isEmpty();
FluidStack fluidInItem = fluidItem.getFluidInTank(tankSlot);
int itemCapacity = fluidItem.getTankCapacity(tankSlot) - fluidInItem.getAmount();
boolean itemEmpty = fluidInItem.isEmpty();
boolean undecided = lockedExchange == null;
boolean canMoveToTank = (undecided || lockedExchange == FluidExchange.ITEM_TO_TANK) && tankCapacity > 0;
boolean canMoveToItem = (undecided || lockedExchange == FluidExchange.TANK_TO_ITEM) && itemCapacity > 0;
// Incompatible Liquids
if (!tankEmpty && !itemEmpty && !fluidInItem.isFluidEqual(fluidInTank))
continue;
// Transfer liquid to tank
if (((tankEmpty || itemCapacity <= 0) && canMoveToTank)
|| undecided && preferred == FluidExchange.ITEM_TO_TANK) {
int amount = fluidTank.fill(
fluidItem.drain(Math.min(maxTransferAmountPerTank, tankCapacity), FluidAction.EXECUTE),
FluidAction.EXECUTE);
if (amount > 0) {
lockedExchange = FluidExchange.ITEM_TO_TANK;
if (singleOp)
return lockedExchange;
continue;
}
}
// Transfer liquid from tank
if (((itemEmpty || tankCapacity <= 0) && canMoveToItem)
|| undecided && preferred == FluidExchange.TANK_TO_ITEM) {
int amount = fluidItem.fill(
fluidTank.drain(Math.min(maxTransferAmountPerTank, itemCapacity), FluidAction.EXECUTE),
FluidAction.EXECUTE);
if (amount > 0) {
lockedExchange = FluidExchange.TANK_TO_ITEM;
if (singleOp)
return lockedExchange;
continue;
}
}
}
}
return null;
}
}

View file

@ -0,0 +1,157 @@
package com.simibubi.create.foundation.fluid;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.matrix.MatrixStack.Entry;
import com.mojang.blaze3d.vertex.IVertexBuilder;
import com.simibubi.create.foundation.utility.Iterate;
import com.simibubi.create.foundation.utility.MatrixStacker;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.IRenderTypeBuffer;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.fluid.Fluid;
import net.minecraft.inventory.container.PlayerContainer;
import net.minecraft.util.Direction;
import net.minecraft.util.Direction.Axis;
import net.minecraft.util.Direction.AxisDirection;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.math.Vec3i;
import net.minecraftforge.fluids.FluidAttributes;
import net.minecraftforge.fluids.FluidStack;
public class FluidRenderer {
public static void renderTiledFluidBB(FluidStack fluidStack, float xMin, float yMin, float zMin, float xMax,
float yMax, float zMax, IRenderTypeBuffer buffer, MatrixStack ms, int light, boolean renderBottom) {
Fluid fluid = fluidStack.getFluid();
FluidAttributes fluidAttributes = fluid.getAttributes();
TextureAtlasSprite fluidTexture = Minecraft.getInstance()
.getSpriteAtlas(PlayerContainer.BLOCK_ATLAS_TEXTURE)
.apply(fluidAttributes.getStillTexture(fluidStack));
int color = fluidAttributes.getColor(fluidStack);
IVertexBuilder builder = buffer.getBuffer(RenderType.getTranslucent());
MatrixStacker msr = MatrixStacker.of(ms);
Vec3d center = new Vec3d(xMin + (xMax - xMin) / 2, yMin + (yMax - yMin) / 2, zMin + (zMax - zMin) / 2);
int blockLightIn = (light >> 4) & 0xf;
int luminosity = Math.max(blockLightIn, fluidAttributes.getLuminosity(fluidStack));
light = (light & 0xf00000) | luminosity << 4;
ms.push();
if (fluidStack.getFluid()
.getAttributes()
.isLighterThanAir())
MatrixStacker.of(ms)
.translate(center)
.rotateX(180)
.translateBack(center);
for (Direction side : Iterate.directions) {
if (side == Direction.DOWN && !renderBottom)
continue;
if (side.getAxis()
.isHorizontal()) {
ms.push();
if (side.getAxisDirection() == AxisDirection.NEGATIVE)
msr.translate(center)
.rotateY(180)
.translateBack(center);
boolean X = side.getAxis() == Axis.X;
renderTiledHorizontalFace(X ? xMax : zMax, side, X ? zMin : xMin, yMin, X ? zMax : xMax, yMax, builder,
ms, light, color, fluidTexture);
ms.pop();
continue;
}
renderTiledVerticalFace(side == Direction.UP ? yMax : yMin, side, xMin, zMin, xMax, zMax, builder, ms,
light, color, fluidTexture);
}
ms.pop();
}
private static void renderTiledVerticalFace(float y, Direction face, float xMin, float zMin, float xMax, float zMax,
IVertexBuilder builder, MatrixStack ms, int light, int color, TextureAtlasSprite texture) {
float x2 = 0;
float z2 = 0;
for (float x1 = xMin; x1 < xMax; x1 = x2) {
x2 = Math.min((int) (x1 + 1), xMax);
for (float z1 = zMin; z1 < zMax; z1 = z2) {
z2 = Math.min((int) (z1 + 1), zMax);
float u1 = texture.getInterpolatedU(local(x1) * 16);
float v1 = texture.getInterpolatedV(local(z1) * 16);
float u2 = texture.getInterpolatedU(x2 == xMax ? local(x2) * 16 : 16);
float v2 = texture.getInterpolatedV(z2 == zMax ? local(z2) * 16 : 16);
putVertex(builder, ms, x1, y, z2, color, u1, v2, face, light);
putVertex(builder, ms, x2, y, z2, color, u2, v2, face, light);
putVertex(builder, ms, x2, y, z1, color, u2, v1, face, light);
putVertex(builder, ms, x1, y, z1, color, u1, v1, face, light);
}
}
}
private static void renderTiledHorizontalFace(float h, Direction face, float hMin, float yMin, float hMax,
float yMax, IVertexBuilder builder, MatrixStack ms, int light, int color, TextureAtlasSprite texture) {
boolean X = face.getAxis() == Axis.X;
float h2 = 0;
float y2 = 0;
for (float h1 = hMin; h1 < hMax; h1 = h2) {
h2 = Math.min((int) (h1 + 1), hMax);
for (float y1 = yMin; y1 < yMax; y1 = y2) {
y2 = Math.min((int) (y1 + 1), yMax);
float u1 = texture.getInterpolatedU(local(h1) * 16);
float v1 = texture.getInterpolatedV(local(y1) * 16);
float u2 = texture.getInterpolatedU(h2 == hMax ? local(h2) * 16 : 16);
float v2 = texture.getInterpolatedV(y2 == yMax ? local(y2) * 16 : 16);
float x1 = X ? h : h1;
float x2 = X ? h : h2;
float z1 = X ? h1 : h;
float z2 = X ? h2 : h;
putVertex(builder, ms, x2, y2, z1, color, u1, v2, face, light);
putVertex(builder, ms, x1, y2, z2, color, u2, v2, face, light);
putVertex(builder, ms, x1, y1, z2, color, u2, v1, face, light);
putVertex(builder, ms, x2, y1, z1, color, u1, v1, face, light);
}
}
}
private static float local(float f) {
if (f < 0)
f += 10;
return f - ((int) f);
}
private static void putVertex(IVertexBuilder builder, MatrixStack ms, float x, float y, float z, int color, float u,
float v, Direction face, int light) {
Vec3i n = face.getDirectionVec();
Entry peek = ms.peek();
int ff = 0xff;
int a = color >> 24 & ff;
int r = color >> 16 & ff;
int g = color >> 8 & ff;
int b = color & ff;
builder.vertex(peek.getModel(), x, y, z)
.color(r, g, b, a)
.texture(u, v)
.light(light)
.normal(n.getX(), n.getY(), n.getZ())
.endVertex();
}
}

View file

@ -0,0 +1,29 @@
package com.simibubi.create.foundation.fluid;
import java.util.function.Consumer;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.capability.templates.FluidTank;
public class SmartFluidTank extends FluidTank {
private Consumer<FluidStack> updateCallback;
public SmartFluidTank(int capacity, Consumer<FluidStack> updateCallback) {
super(capacity);
this.updateCallback = updateCallback;
}
@Override
protected void onContentsChanged() {
super.onContentsChanged();
updateCallback.accept(getFluid());
}
@Override
public void setFluid(FluidStack stack) {
super.setFluid(stack);
updateCallback.accept(stack);
}
}

View file

@ -6,8 +6,8 @@
}, },
"elements": [ "elements": [
{ {
"from": [3, -1, 3], "from": [3.1, -1.1, 3.1],
"to": [13, 1, 13], "to": [12.9, 1, 12.9],
"faces": { "faces": {
"north": {"uv": [6, 6, 11, 5], "texture": "#0"}, "north": {"uv": [6, 6, 11, 5], "texture": "#0"},
"east": {"uv": [11, 5, 6, 6], "rotation": 180, "texture": "#0"}, "east": {"uv": [11, 5, 6, 6], "rotation": 180, "texture": "#0"},

View file

@ -6,8 +6,8 @@
}, },
"elements": [ "elements": [
{ {
"from": [15, 3, 3], "from": [15, 3.1, 3.1],
"to": [17, 13, 13], "to": [17.1, 12.9, 12.9],
"faces": { "faces": {
"north": {"uv": [6, 6, 11, 5], "rotation": 90, "texture": "#0"}, "north": {"uv": [6, 6, 11, 5], "rotation": 90, "texture": "#0"},
"east": {"uv": [11, 0, 6, 5], "texture": "#0"}, "east": {"uv": [11, 0, 6, 5], "texture": "#0"},

View file

@ -6,8 +6,8 @@
}, },
"elements": [ "elements": [
{ {
"from": [3, 3, -1], "from": [3.1, 3.1, -1.1],
"to": [13, 13, 1], "to": [12.9, 12.9, 1],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, -5]}, "rotation": {"angle": 0, "axis": "y", "origin": [8, 8, -5]},
"faces": { "faces": {
"north": {"uv": [6, 0, 11, 5], "texture": "#0"}, "north": {"uv": [6, 0, 11, 5], "texture": "#0"},

View file

@ -6,8 +6,8 @@
}, },
"elements": [ "elements": [
{ {
"from": [3, 3, 15], "from": [3.1, 3.1, 15],
"to": [13, 13, 17], "to": [12.9, 12.9, 17.1],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 21]}, "rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 21]},
"faces": { "faces": {
"north": {"uv": [6, 0, 11, 5], "texture": "#0"}, "north": {"uv": [6, 0, 11, 5], "texture": "#0"},

View file

@ -6,8 +6,8 @@
}, },
"elements": [ "elements": [
{ {
"from": [3, 15, 3], "from": [3.1, 15, 3.1],
"to": [13, 17, 13], "to": [12.9, 17.1, 12.9],
"faces": { "faces": {
"north": {"uv": [6, 5, 11, 6], "texture": "#0"}, "north": {"uv": [6, 5, 11, 6], "texture": "#0"},
"east": {"uv": [11, 6, 6, 5], "rotation": 180, "texture": "#0"}, "east": {"uv": [11, 6, 6, 5], "rotation": 180, "texture": "#0"},

View file

@ -6,8 +6,8 @@
}, },
"elements": [ "elements": [
{ {
"from": [-1, 3, 3], "from": [-1.1, 3.1, 3.1],
"to": [1, 13, 13], "to": [1, 12.9, 12.9],
"faces": { "faces": {
"north": {"uv": [6, 5, 11, 6], "rotation": 90, "texture": "#0"}, "north": {"uv": [6, 5, 11, 6], "rotation": 90, "texture": "#0"},
"east": {"uv": [6, 0, 11, 5], "texture": "#0"}, "east": {"uv": [6, 0, 11, 5], "texture": "#0"},

View file

@ -3,23 +3,70 @@
"parent": "block/block", "parent": "block/block",
"textures": { "textures": {
"0": "create:block/copper_casing", "0": "create:block/copper_casing",
"2": "create:block/fluid_tank", "1": "create:block/fluid_tank",
"3": "create:block/oxidized/copper_block_0", "particle": "create:block/fluid_tank"
"particle": "create:block/copper_casing"
}, },
"elements": [ "elements": [
{ {
"name": "bottom", "name": "Lid",
"from": [0, 0, 0], "from": [0, 0, 0],
"to": [16, 4, 16], "to": [16, 4, 16],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, -23]},
"faces": { "faces": {
"north": {"uv": [0, 12, 16, 16], "texture": "#2"}, "north": {"uv": [0, 12, 16, 16], "texture": "#1", "cullface": "north"},
"east": {"uv": [0, 12, 16, 16], "texture": "#2"}, "east": {"uv": [0, 12, 16, 16], "texture": "#1", "cullface": "east"},
"south": {"uv": [0, 12, 16, 16], "texture": "#2"}, "south": {"uv": [0, 12, 16, 16], "texture": "#1", "cullface": "south"},
"west": {"uv": [0, 12, 16, 16], "texture": "#2"}, "west": {"uv": [0, 12, 16, 16], "texture": "#1", "cullface": "west"},
"up": {"uv": [0, 0, 16, 16], "texture": "#0"}, "up": {"uv": [0, 0, 16, 16], "texture": "#0"},
"down": {"uv": [0, 0, 16, 16], "texture": "#3"} "down": {"uv": [0, 0, 16, 16], "texture": "#0", "cullface": "down"}
} }
},
{
"name": "SideRight",
"from": [0, 4, 0],
"to": [16, 16, 1],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 12, -23]},
"faces": {
"north": {"uv": [0, 0, 16, 12], "texture": "#1", "cullface": "north"},
"south": {"uv": [0, 0, 16, 12], "texture": "#1", "cullface": "north"}
}
},
{
"name": "SideRight",
"from": [15, 4, 0],
"to": [16, 16, 16],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 12, 8]},
"faces": {
"east": {"uv": [0, 0, 16, 12], "texture": "#1", "cullface": "east"},
"west": {"uv": [0, 0, 16, 12], "texture": "#1", "cullface": "east"}
}
},
{
"name": "SideRight",
"from": [0, 4, 15],
"to": [16, 16, 16],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 12, 8]},
"faces": {
"north": {"uv": [0, 0, 16, 12], "texture": "#1", "cullface": "south"},
"south": {"uv": [0, 0, 16, 12], "texture": "#1", "cullface": "south"}
}
},
{
"name": "SideRight",
"from": [0, 4, 0],
"to": [1, 16, 16],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 12, 8]},
"faces": {
"east": {"uv": [0, 0, 16, 12], "texture": "#1", "cullface": "west"},
"west": {"uv": [0, 0, 16, 12], "texture": "#1", "cullface": "west"}
}
}
],
"groups": [
{
"name": "tank",
"origin": [8, 8, -23],
"children": [0, 1, 2, 3, 4]
} }
] ]
} }

View file

@ -0,0 +1,152 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"0": "create:block/copper_casing",
"1": "create:block/fluid_tank",
"3": "create:block/fluid_tank_window",
"particle": "create:block/fluid_tank"
},
"elements": [
{
"name": "SideRight",
"from": [0, 4, 0],
"to": [4, 16, 1],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, -23]},
"faces": {
"north": {"uv": [12, 0, 16, 12], "texture": "#1", "cullface": "north"},
"east": {"uv": [12, 0, 13, 12], "texture": "#1", "cullface": "north"},
"south": {"uv": [0, 0, 4, 12], "texture": "#1", "cullface": "north"}
}
},
{
"name": "SideRight",
"from": [15, 4, 0],
"to": [16, 16, 4],
"faces": {
"east": {"uv": [12, 0, 16, 12], "texture": "#1", "cullface": "east"},
"south": {"uv": [12, 0, 13, 12], "texture": "#1", "cullface": "east"},
"west": {"uv": [0, 0, 4, 12], "texture": "#1", "cullface": "east"}
}
},
{
"name": "SideRight",
"from": [12, 4, 15],
"to": [16, 16, 16],
"faces": {
"north": {"uv": [0, 0, 4, 12], "texture": "#1", "cullface": "south"},
"south": {"uv": [12, 0, 16, 12], "texture": "#1", "cullface": "south"},
"west": {"uv": [12, 0, 13, 12], "texture": "#1", "cullface": "south"}
}
},
{
"name": "SideRight",
"from": [0, 4, 12],
"to": [1, 16, 16],
"faces": {
"north": {"uv": [12, 0, 13, 12], "texture": "#1", "cullface": "west"},
"east": {"uv": [0, 0, 4, 12], "texture": "#1", "cullface": "west"},
"west": {"uv": [12, 0, 16, 12], "texture": "#1", "cullface": "west"}
}
},
{
"name": "Window",
"from": [4, 4, 1],
"to": [12, 16, 1],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, -23]},
"faces": {
"north": {"uv": [0, 4, 8, 16], "texture": "#3", "cullface": "north"},
"south": {"uv": [0, 4, 8, 16], "texture": "#3", "cullface": "north"}
}
},
{
"name": "Window",
"from": [15, 4, 4],
"to": [15, 16, 12],
"faces": {
"east": {"uv": [0, 4, 8, 16], "texture": "#3", "cullface": "east"},
"west": {"uv": [0, 4, 8, 16], "texture": "#3", "cullface": "east"}
}
},
{
"name": "Window",
"from": [4, 4, 15],
"to": [12, 16, 15],
"faces": {
"north": {"uv": [0, 4, 8, 16], "texture": "#3", "cullface": "south"},
"south": {"uv": [0, 4, 8, 16], "texture": "#3", "cullface": "south"}
}
},
{
"name": "Window",
"from": [1, 4, 4],
"to": [1, 16, 12],
"faces": {
"east": {"uv": [0, 4, 8, 16], "texture": "#3", "cullface": "west"},
"west": {"uv": [0, 4, 8, 16], "texture": "#3", "cullface": "west"}
}
},
{
"name": "SideLeft",
"from": [12, 4, 0],
"to": [16, 16, 1],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, -23]},
"faces": {
"north": {"uv": [0, 0, 4, 12], "texture": "#1", "cullface": "north"},
"south": {"uv": [12, 0, 16, 12], "texture": "#1", "cullface": "north"},
"west": {"uv": [3, 0, 4, 12], "texture": "#1", "cullface": "north"}
}
},
{
"name": "SideLeft",
"from": [15, 4, 12],
"to": [16, 16, 16],
"faces": {
"north": {"uv": [3, 0, 4, 12], "texture": "#1", "cullface": "east"},
"east": {"uv": [0, 0, 4, 12], "texture": "#1", "cullface": "east"},
"west": {"uv": [12, 0, 16, 12], "texture": "#1", "cullface": "east"}
}
},
{
"name": "SideLeft",
"from": [0, 4, 15],
"to": [4, 16, 16],
"faces": {
"north": {"uv": [12, 0, 16, 12], "texture": "#1", "cullface": "south"},
"east": {"uv": [3, 0, 4, 12], "texture": "#1", "cullface": "south"},
"south": {"uv": [0, 0, 4, 12], "texture": "#1", "cullface": "south"}
}
},
{
"name": "SideLeft",
"from": [0, 4, 0],
"to": [1, 16, 4],
"faces": {
"east": {"uv": [12, 0, 16, 12], "texture": "#1", "cullface": "west"},
"south": {"uv": [3, 0, 4, 12], "texture": "#1", "cullface": "west"},
"west": {"uv": [0, 0, 4, 12], "texture": "#1", "cullface": "west"}
}
},
{
"name": "Bottom",
"from": [0, 0, 0],
"to": [16, 4, 16],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, -23]},
"faces": {
"north": {"uv": [0, 12, 16, 16], "texture": "#1", "cullface": "north"},
"east": {"uv": [0, 12, 16, 16], "texture": "#1", "cullface": "east"},
"south": {"uv": [0, 12, 16, 16], "texture": "#1", "cullface": "south"},
"west": {"uv": [0, 12, 16, 16], "texture": "#1", "cullface": "west"},
"up": {"uv": [0, 0, 16, 16], "texture": "#0"},
"down": {"uv": [0, 0, 16, 16], "texture": "#0", "cullface": "down"}
}
}
],
"groups": [
{
"name": "tank",
"origin": [8, 8, -23],
"children": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
}
]
}

View file

@ -0,0 +1,71 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"0": "create:block/copper_casing",
"1": "create:block/fluid_tank",
"3": "create:block/fluid_tank_window",
"particle": "create:block/fluid_tank"
},
"elements": [
{
"name": "SideRight",
"from": [15, 4, 0],
"to": [16, 16, 12],
"faces": {
"east": {"uv": [4, 0, 16, 12], "texture": "#1"},
"south": {"uv": [12, 0, 13, 12], "texture": "#1"},
"west": {"uv": [0, 0, 12, 12], "texture": "#1"}
}
},
{
"name": "Window",
"from": [0, 4, 1],
"to": [4, 16, 1],
"faces": {
"north": {"uv": [0, 4, 4, 16], "texture": "#3"},
"south": {"uv": [4, 4, 8, 16], "texture": "#3"}
}
},
{
"name": "Window",
"from": [15, 4, 12],
"to": [15, 16, 16],
"faces": {
"east": {"uv": [4, 4, 8, 16], "texture": "#3"},
"west": {"uv": [0, 4, 4, 16], "texture": "#3"}
}
},
{
"name": "SideLeft",
"from": [4, 4, 0],
"to": [16, 16, 1],
"faces": {
"north": {"uv": [0, 0, 12, 12], "texture": "#1"},
"south": {"uv": [4, 0, 16, 12], "texture": "#1"},
"west": {"uv": [3, 0, 4, 12], "texture": "#1"}
}
},
{
"name": "Bottom",
"from": [0, 0, 0],
"to": [16, 4, 16],
"rotation": {"angle": 0, "axis": "y", "origin": [-23, 8, 8]},
"faces": {
"north": {"uv": [0, 12, 16, 16], "texture": "#1"},
"east": {"uv": [0, 12, 16, 16], "texture": "#1"},
"south": {"uv": [0, 12, 16, 16], "texture": "#1"},
"west": {"uv": [0, 12, 16, 16], "texture": "#1"},
"up": {"uv": [0, 0, 16, 16], "texture": "#0"},
"down": {"uv": [0, 0, 16, 16], "texture": "#0", "cullface": "down"}
}
}
],
"groups": [
{
"name": "tank",
"origin": [8, 8, -23],
"children": [0, 1, 2, 3, 4]
}
]
}

View file

@ -0,0 +1,71 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"0": "create:block/copper_casing",
"1": "create:block/fluid_tank",
"3": "create:block/fluid_tank_window",
"particle": "create:block/fluid_tank"
},
"elements": [
{
"name": "SideRight",
"from": [0, 4, 0],
"to": [12, 16, 1],
"faces": {
"north": {"uv": [4, 0, 16, 12], "texture": "#1"},
"east": {"uv": [12, 0, 13, 12], "texture": "#1"},
"south": {"uv": [0, 0, 12, 12], "texture": "#1"}
}
},
{
"name": "Window",
"from": [1, 4, 12],
"to": [1, 16, 16],
"faces": {
"east": {"uv": [4, 4, 8, 16], "texture": "#3"},
"west": {"uv": [0, 4, 4, 16], "texture": "#3"}
}
},
{
"name": "Window",
"from": [12, 4, 1],
"to": [16, 16, 1],
"faces": {
"north": {"uv": [4, 4, 8, 16], "texture": "#3"},
"south": {"uv": [0, 4, 4, 16], "texture": "#3"}
}
},
{
"name": "SideLeft",
"from": [0, 4, 0],
"to": [1, 16, 12],
"faces": {
"east": {"uv": [4, 0, 16, 12], "texture": "#1"},
"south": {"uv": [3, 0, 4, 12], "texture": "#1"},
"west": {"uv": [0, 0, 12, 12], "texture": "#1"}
}
},
{
"name": "Bottom",
"from": [0, 0, 0],
"to": [16, 4, 16],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 39]},
"faces": {
"north": {"uv": [0, 12, 16, 16], "texture": "#1"},
"east": {"uv": [0, 12, 16, 16], "texture": "#1"},
"south": {"uv": [0, 12, 16, 16], "texture": "#1"},
"west": {"uv": [0, 12, 16, 16], "texture": "#1"},
"up": {"uv": [0, 0, 16, 16], "texture": "#0"},
"down": {"uv": [0, 0, 16, 16], "texture": "#0", "cullface": "down"}
}
}
],
"groups": [
{
"name": "tank",
"origin": [8, 8, -23],
"children": [0, 1, 2, 3, 4]
}
]
}

View file

@ -0,0 +1,71 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"0": "create:block/copper_casing",
"1": "create:block/fluid_tank",
"3": "create:block/fluid_tank_window",
"particle": "create:block/fluid_tank"
},
"elements": [
{
"name": "SideRight",
"from": [4, 4, 15],
"to": [16, 16, 16],
"faces": {
"north": {"uv": [0, 0, 12, 12], "texture": "#1"},
"south": {"uv": [4, 0, 16, 12], "texture": "#1"},
"west": {"uv": [12, 0, 13, 12], "texture": "#1"}
}
},
{
"name": "Window",
"from": [15, 4, 0],
"to": [15, 16, 4],
"faces": {
"east": {"uv": [0, 4, 4, 16], "texture": "#3"},
"west": {"uv": [4, 4, 8, 16], "texture": "#3"}
}
},
{
"name": "Window",
"from": [0, 4, 15],
"to": [4, 16, 15],
"faces": {
"north": {"uv": [0, 4, 4, 16], "texture": "#3"},
"south": {"uv": [4, 4, 8, 16], "texture": "#3"}
}
},
{
"name": "SideLeft",
"from": [15, 4, 4],
"to": [16, 16, 16],
"faces": {
"north": {"uv": [3, 0, 4, 12], "texture": "#1"},
"east": {"uv": [0, 0, 12, 12], "texture": "#1"},
"west": {"uv": [4, 0, 16, 12], "texture": "#1"}
}
},
{
"name": "Bottom",
"from": [0, 0, 0],
"to": [16, 4, 16],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, -23]},
"faces": {
"north": {"uv": [0, 12, 16, 16], "texture": "#1"},
"east": {"uv": [0, 12, 16, 16], "texture": "#1"},
"south": {"uv": [0, 12, 16, 16], "texture": "#1"},
"west": {"uv": [0, 12, 16, 16], "texture": "#1"},
"up": {"uv": [0, 0, 16, 16], "texture": "#0"},
"down": {"uv": [0, 0, 16, 16], "texture": "#0", "cullface": "down"}
}
}
],
"groups": [
{
"name": "tank",
"origin": [8, 8, -23],
"children": [0, 1, 2, 3, 4]
}
]
}

View file

@ -0,0 +1,71 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"0": "create:block/copper_casing",
"1": "create:block/fluid_tank",
"3": "create:block/fluid_tank_window",
"particle": "create:block/fluid_tank"
},
"elements": [
{
"name": "SideRight",
"from": [0, 4, 4],
"to": [1, 16, 16],
"faces": {
"north": {"uv": [12, 0, 13, 12], "texture": "#1"},
"east": {"uv": [0, 0, 12, 12], "texture": "#1"},
"west": {"uv": [4, 0, 16, 12], "texture": "#1"}
}
},
{
"name": "Window",
"from": [12, 4, 15],
"to": [16, 16, 15],
"faces": {
"north": {"uv": [4, 4, 8, 16], "texture": "#3"},
"south": {"uv": [0, 4, 4, 16], "texture": "#3"}
}
},
{
"name": "Window",
"from": [1, 4, 0],
"to": [1, 16, 4],
"faces": {
"east": {"uv": [0, 4, 4, 16], "texture": "#3"},
"west": {"uv": [4, 4, 8, 16], "texture": "#3"}
}
},
{
"name": "SideLeft",
"from": [0, 4, 15],
"to": [12, 16, 16],
"faces": {
"north": {"uv": [4, 0, 16, 12], "texture": "#1"},
"east": {"uv": [3, 0, 4, 12], "texture": "#1"},
"south": {"uv": [0, 0, 12, 12], "texture": "#1"}
}
},
{
"name": "Bottom",
"from": [0, 0, 0],
"to": [16, 4, 16],
"rotation": {"angle": 0, "axis": "y", "origin": [39, 8, 8]},
"faces": {
"north": {"uv": [0, 12, 16, 16], "texture": "#1"},
"east": {"uv": [0, 12, 16, 16], "texture": "#1"},
"south": {"uv": [0, 12, 16, 16], "texture": "#1"},
"west": {"uv": [0, 12, 16, 16], "texture": "#1"},
"up": {"uv": [0, 0, 16, 16], "texture": "#0"},
"down": {"uv": [0, 0, 16, 16], "texture": "#0", "cullface": "down"}
}
}
],
"groups": [
{
"name": "tank",
"origin": [8, 8, -23],
"children": [0, 1, 2, 3, 4]
}
]
}

View file

@ -0,0 +1,57 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"1": "create:block/fluid_tank",
"particle": "create:block/fluid_tank"
},
"elements": [
{
"name": "SideRight",
"from": [0, 0, 0],
"to": [16, 16, 1],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 12, -23]},
"faces": {
"north": {"uv": [0, 0, 16, 16], "texture": "#1", "cullface": "north"},
"south": {"uv": [0, 0, 16, 16], "texture": "#1", "cullface": "north"}
}
},
{
"name": "SideRight",
"from": [15, 0, 0],
"to": [16, 16, 16],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 12, 8]},
"faces": {
"east": {"uv": [0, 0, 16, 16], "texture": "#1", "cullface": "east"},
"west": {"uv": [0, 0, 16, 16], "texture": "#1", "cullface": "east"}
}
},
{
"name": "SideRight",
"from": [0, 0, 15],
"to": [16, 16, 16],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 12, 8]},
"faces": {
"north": {"uv": [0, 0, 16, 16], "texture": "#1", "cullface": "south"},
"south": {"uv": [0, 0, 16, 16], "texture": "#1", "cullface": "south"}
}
},
{
"name": "SideRight",
"from": [0, 0, 0],
"to": [1, 16, 16],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 12, 8]},
"faces": {
"east": {"uv": [0, 0, 16, 16], "texture": "#1", "cullface": "west"},
"west": {"uv": [0, 0, 16, 16], "texture": "#1", "cullface": "west"}
}
}
],
"groups": [
{
"name": "tank",
"origin": [8, 8, -23],
"children": [0, 1, 2, 3]
}
]
}

View file

@ -0,0 +1,137 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"1": "create:block/fluid_tank",
"3": "create:block/fluid_tank_window",
"particle": "create:block/fluid_tank"
},
"elements": [
{
"name": "SideRight",
"from": [0, 0, 0],
"to": [4, 16, 1],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, -23]},
"faces": {
"north": {"uv": [12, 0, 16, 16], "texture": "#1", "cullface": "north"},
"east": {"uv": [12, 0, 13, 16], "texture": "#1", "cullface": "north"},
"south": {"uv": [0, 0, 4, 16], "texture": "#1", "cullface": "north"}
}
},
{
"name": "SideRight",
"from": [15, 0, 0],
"to": [16, 16, 4],
"faces": {
"east": {"uv": [12, 0, 16, 16], "texture": "#1", "cullface": "east"},
"south": {"uv": [12, 0, 13, 16], "texture": "#1", "cullface": "east"},
"west": {"uv": [0, 0, 4, 16], "texture": "#1", "cullface": "east"}
}
},
{
"name": "SideRight",
"from": [12, 0, 15],
"to": [16, 16, 16],
"faces": {
"north": {"uv": [0, 0, 4, 16], "texture": "#1", "cullface": "south"},
"south": {"uv": [12, 0, 16, 16], "texture": "#1", "cullface": "south"},
"west": {"uv": [12, 0, 13, 16], "texture": "#1", "cullface": "south"}
}
},
{
"name": "SideRight",
"from": [0, 0, 12],
"to": [1, 16, 16],
"faces": {
"north": {"uv": [12, 0, 13, 16], "texture": "#1", "cullface": "west"},
"east": {"uv": [0, 0, 4, 16], "texture": "#1", "cullface": "west"},
"west": {"uv": [12, 0, 16, 16], "texture": "#1", "cullface": "west"}
}
},
{
"name": "Window",
"from": [4, 0, 1],
"to": [12, 16, 1],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, -23]},
"faces": {
"north": {"uv": [8, 0, 16, 16], "texture": "#3", "cullface": "north"},
"south": {"uv": [8, 0, 16, 16], "texture": "#3", "cullface": "north"}
}
},
{
"name": "Window",
"from": [15, 0, 4],
"to": [15, 16, 12],
"faces": {
"east": {"uv": [8, 0, 16, 16], "texture": "#3", "cullface": "east"},
"west": {"uv": [8, 0, 16, 16], "texture": "#3", "cullface": "east"}
}
},
{
"name": "Window",
"from": [4, 0, 15],
"to": [12, 16, 15],
"faces": {
"north": {"uv": [8, 0, 16, 16], "texture": "#3", "cullface": "south"},
"south": {"uv": [8, 0, 16, 16], "texture": "#3", "cullface": "south"}
}
},
{
"name": "Window",
"from": [1, 0, 4],
"to": [1, 16, 12],
"faces": {
"east": {"uv": [8, 0, 16, 16], "texture": "#3", "cullface": "west"},
"west": {"uv": [8, 0, 16, 16], "texture": "#3", "cullface": "west"}
}
},
{
"name": "SideLeft",
"from": [12, 0, 0],
"to": [16, 16, 1],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, -23]},
"faces": {
"north": {"uv": [0, 0, 4, 16], "texture": "#1", "cullface": "north"},
"south": {"uv": [12, 0, 16, 16], "texture": "#1", "cullface": "north"},
"west": {"uv": [3, 0, 4, 16], "texture": "#1", "cullface": "north"}
}
},
{
"name": "SideLeft",
"from": [15, 0, 12],
"to": [16, 16, 16],
"faces": {
"north": {"uv": [3, 0, 4, 16], "texture": "#1", "cullface": "east"},
"east": {"uv": [0, 0, 4, 16], "texture": "#1", "cullface": "east"},
"west": {"uv": [12, 0, 16, 16], "texture": "#1", "cullface": "east"}
}
},
{
"name": "SideLeft",
"from": [0, 0, 15],
"to": [4, 16, 16],
"faces": {
"north": {"uv": [12, 0, 16, 16], "texture": "#1", "cullface": "south"},
"east": {"uv": [3, 0, 4, 16], "texture": "#1", "cullface": "south"},
"south": {"uv": [0, 0, 4, 16], "texture": "#1", "cullface": "south"}
}
},
{
"name": "SideLeft",
"from": [0, 0, 0],
"to": [1, 16, 4],
"faces": {
"east": {"uv": [12, 0, 16, 16], "texture": "#1", "cullface": "west"},
"south": {"uv": [3, 0, 4, 16], "texture": "#1", "cullface": "west"},
"west": {"uv": [0, 0, 4, 16], "texture": "#1", "cullface": "west"}
}
}
],
"groups": [
{
"name": "tank",
"origin": [8, 8, -23],
"children": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
}
]
}

View file

@ -0,0 +1,56 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"1": "create:block/fluid_tank",
"3": "create:block/fluid_tank_window",
"particle": "create:block/fluid_tank"
},
"elements": [
{
"name": "SideRight",
"from": [15, 0, 0],
"to": [16, 16, 12],
"faces": {
"east": {"uv": [4, 0, 16, 16], "texture": "#1"},
"south": {"uv": [12, 0, 13, 16], "texture": "#1"},
"west": {"uv": [0, 0, 12, 16], "texture": "#1"}
}
},
{
"name": "Window",
"from": [0, 0, 1],
"to": [4, 16, 1],
"faces": {
"north": {"uv": [8, 0, 12, 16], "texture": "#3"},
"south": {"uv": [12, 0, 16, 16], "texture": "#3"}
}
},
{
"name": "Window",
"from": [15, 0, 12],
"to": [15, 16, 16],
"faces": {
"east": {"uv": [12, 0, 16, 16], "texture": "#3"},
"west": {"uv": [8, 0, 12, 16], "texture": "#3"}
}
},
{
"name": "SideLeft",
"from": [4, 0, 0],
"to": [16, 16, 1],
"faces": {
"north": {"uv": [0, 0, 12, 16], "texture": "#1"},
"south": {"uv": [4, 0, 16, 16], "texture": "#1"},
"west": {"uv": [3, 0, 4, 16], "texture": "#1"}
}
}
],
"groups": [
{
"name": "tank",
"origin": [8, 8, -23],
"children": [0, 1, 2, 3]
}
]
}

View file

@ -0,0 +1,56 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"1": "create:block/fluid_tank",
"3": "create:block/fluid_tank_window",
"particle": "create:block/fluid_tank"
},
"elements": [
{
"name": "SideRight",
"from": [0, 0, 0],
"to": [12, 16, 1],
"faces": {
"north": {"uv": [4, 0, 16, 16], "texture": "#1"},
"east": {"uv": [12, 0, 13, 16], "texture": "#1"},
"south": {"uv": [0, 0, 12, 16], "texture": "#1"}
}
},
{
"name": "Window",
"from": [1, 0, 12],
"to": [1, 16, 16],
"faces": {
"east": {"uv": [12, 0, 16, 16], "texture": "#3"},
"west": {"uv": [8, 0, 12, 16], "texture": "#3"}
}
},
{
"name": "Window",
"from": [12, 0, 1],
"to": [16, 16, 1],
"faces": {
"north": {"uv": [12, 0, 16, 16], "texture": "#3"},
"south": {"uv": [8, 0, 12, 16], "texture": "#3"}
}
},
{
"name": "SideLeft",
"from": [0, 0, 0],
"to": [1, 16, 12],
"faces": {
"east": {"uv": [4, 0, 16, 16], "texture": "#1"},
"south": {"uv": [3, 0, 4, 16], "texture": "#1"},
"west": {"uv": [0, 0, 12, 16], "texture": "#1"}
}
}
],
"groups": [
{
"name": "tank",
"origin": [8, 8, -23],
"children": [0, 1, 2, 3]
}
]
}

View file

@ -0,0 +1,56 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"1": "create:block/fluid_tank",
"3": "create:block/fluid_tank_window",
"particle": "create:block/fluid_tank"
},
"elements": [
{
"name": "SideRight",
"from": [4, 0, 15],
"to": [16, 16, 16],
"faces": {
"north": {"uv": [0, 0, 12, 16], "texture": "#1"},
"south": {"uv": [4, 0, 16, 16], "texture": "#1"},
"west": {"uv": [12, 0, 13, 16], "texture": "#1"}
}
},
{
"name": "Window",
"from": [15, 0, 0],
"to": [15, 16, 4],
"faces": {
"east": {"uv": [8, 0, 12, 16], "texture": "#3"},
"west": {"uv": [12, 0, 16, 16], "texture": "#3"}
}
},
{
"name": "Window",
"from": [0, 0, 15],
"to": [4, 16, 15],
"faces": {
"north": {"uv": [8, 0, 12, 16], "texture": "#3"},
"south": {"uv": [12, 0, 16, 16], "texture": "#3"}
}
},
{
"name": "SideLeft",
"from": [15, 0, 4],
"to": [16, 16, 16],
"faces": {
"north": {"uv": [3, 0, 4, 16], "texture": "#1"},
"east": {"uv": [0, 0, 12, 16], "texture": "#1"},
"west": {"uv": [4, 0, 16, 16], "texture": "#1"}
}
}
],
"groups": [
{
"name": "tank",
"origin": [8, 8, -23],
"children": [0, 1, 2, 3]
}
]
}

View file

@ -0,0 +1,56 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"1": "create:block/fluid_tank",
"3": "create:block/fluid_tank_window",
"particle": "create:block/fluid_tank"
},
"elements": [
{
"name": "SideRight",
"from": [0, 0, 4],
"to": [1, 16, 16],
"faces": {
"north": {"uv": [12, 0, 13, 16], "texture": "#1"},
"east": {"uv": [0, 0, 12, 16], "texture": "#1"},
"west": {"uv": [4, 0, 16, 16], "texture": "#1"}
}
},
{
"name": "Window",
"from": [12, 0, 15],
"to": [16, 16, 15],
"faces": {
"north": {"uv": [12, 0, 16, 16], "texture": "#3"},
"south": {"uv": [8, 0, 12, 16], "texture": "#3"}
}
},
{
"name": "Window",
"from": [1, 0, 0],
"to": [1, 16, 4],
"faces": {
"east": {"uv": [8, 0, 12, 16], "texture": "#3"},
"west": {"uv": [12, 0, 16, 16], "texture": "#3"}
}
},
{
"name": "SideLeft",
"from": [0, 0, 15],
"to": [12, 16, 16],
"faces": {
"north": {"uv": [4, 0, 16, 16], "texture": "#1"},
"east": {"uv": [3, 0, 4, 16], "texture": "#1"},
"south": {"uv": [0, 0, 12, 16], "texture": "#1"}
}
}
],
"groups": [
{
"name": "tank",
"origin": [8, 8, -23],
"children": [0, 1, 2, 3]
}
]
}

View file

@ -0,0 +1,119 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"0": "create:block/copper_casing",
"1": "create:block/fluid_tank",
"particle": "create:block/fluid_tank"
},
"elements": [
{
"name": "Lid",
"from": [0, 0, 0],
"to": [16, 4, 16],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, -23]},
"faces": {
"north": {"uv": [0, 12, 16, 16], "texture": "#1", "cullface": "north"},
"east": {"uv": [0, 12, 16, 16], "texture": "#1", "cullface": "east"},
"south": {"uv": [0, 12, 16, 16], "texture": "#1", "cullface": "south"},
"west": {"uv": [0, 12, 16, 16], "texture": "#1", "cullface": "west"},
"up": {"uv": [0, 0, 16, 16], "texture": "#0"},
"down": {"uv": [0, 0, 16, 16], "texture": "#0", "cullface": "down"}
}
},
{
"name": "SideRight",
"from": [15, 4, 0],
"to": [16, 12, 16],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 12, 8]},
"faces": {
"east": {"uv": [0, 4, 16, 12], "texture": "#1", "cullface": "east"},
"west": {"uv": [0, 4, 16, 12], "texture": "#1", "cullface": "east"}
}
},
{
"name": "SideRight",
"from": [0, 4, 15],
"to": [16, 12, 16],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 12, 8]},
"faces": {
"north": {"uv": [0, 4, 16, 12], "texture": "#1", "cullface": "south"},
"south": {"uv": [0, 4, 16, 12], "texture": "#1", "cullface": "south"}
}
},
{
"name": "SideRight",
"from": [0, 4, 0],
"to": [1, 12, 16],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 12, 8]},
"faces": {
"east": {"uv": [0, 4, 16, 12], "texture": "#1", "cullface": "west"},
"west": {"uv": [0, 4, 16, 12], "texture": "#1", "cullface": "west"}
}
},
{
"name": "Lid",
"from": [0, 12, 0],
"to": [16, 16, 16],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, -23]},
"faces": {
"north": {"uv": [0, 0, 16, 4], "texture": "#1", "cullface": "north"},
"east": {"uv": [0, 0, 16, 4], "texture": "#1", "cullface": "east"},
"south": {"uv": [0, 0, 16, 4], "texture": "#1", "cullface": "south"},
"west": {"uv": [0, 0, 16, 4], "texture": "#1", "cullface": "west"},
"up": {"uv": [0, 0, 16, 16], "texture": "#0", "cullface": "up"},
"down": {"uv": [0, 0, 16, 16], "texture": "#0"}
}
},
{
"name": "SideRight",
"from": [0, 4, 0],
"to": [16, 12, 1],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, -23]},
"faces": {
"north": {"uv": [0, 4, 16, 12], "texture": "#1", "cullface": "north"},
"south": {"uv": [0, 4, 16, 12], "texture": "#1", "cullface": "north"}
}
}
],
"groups": [
{
"name": "tank",
"origin": [8, 8, -23],
"children": []
},
{
"name": "block_middle",
"origin": [8, 8, 8],
"children": [
{
"name": "tank",
"origin": [8, 8, -23],
"children": []
}
]
},
{
"name": "block_bottom",
"origin": [8, 8, 8],
"children": [
{
"name": "tank",
"origin": [8, 8, -23],
"children": [0, 1, 2, 3]
}
]
},
{
"name": "block_top",
"origin": [8, 8, 8],
"children": [
{
"name": "tank",
"origin": [8, 8, -23],
"children": [4, 5]
}
]
}
]
}

View file

@ -0,0 +1,166 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"0": "create:block/copper_casing",
"1": "create:block/fluid_tank",
"5": "create:block/fluid_tank_window_single",
"particle": "create:block/fluid_tank"
},
"elements": [
{
"name": "Lid",
"from": [0, 12, 0],
"to": [16, 16, 16],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, -23]},
"faces": {
"north": {"uv": [0, 0, 16, 4], "texture": "#1", "cullface": "north"},
"east": {"uv": [0, 0, 16, 4], "texture": "#1", "cullface": "east"},
"south": {"uv": [0, 0, 16, 4], "texture": "#1", "cullface": "south"},
"west": {"uv": [0, 0, 16, 4], "texture": "#1", "cullface": "west"},
"up": {"uv": [0, 0, 16, 16], "texture": "#0", "cullface": "up"},
"down": {"uv": [0, 0, 16, 16], "texture": "#0"}
}
},
{
"name": "SideRight",
"from": [0, 4, 0],
"to": [4, 12, 1],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, -23]},
"faces": {
"north": {"uv": [12, 4, 16, 12], "texture": "#1", "cullface": "north"},
"east": {"uv": [12, 4, 13, 12], "texture": "#1", "cullface": "north"},
"south": {"uv": [0, 4, 4, 12], "texture": "#1", "cullface": "north"}
}
},
{
"name": "SideRight",
"from": [15, 4, 0],
"to": [16, 12, 4],
"faces": {
"east": {"uv": [12, 4, 16, 12], "texture": "#1", "cullface": "east"},
"south": {"uv": [12, 4, 13, 12], "texture": "#1", "cullface": "east"},
"west": {"uv": [0, 4, 4, 12], "texture": "#1", "cullface": "east"}
}
},
{
"name": "SideRight",
"from": [12, 4, 15],
"to": [16, 12, 16],
"faces": {
"north": {"uv": [0, 4, 4, 12], "texture": "#1", "cullface": "south"},
"south": {"uv": [12, 4, 16, 12], "texture": "#1", "cullface": "south"},
"west": {"uv": [12, 4, 13, 12], "texture": "#1", "cullface": "south"}
}
},
{
"name": "SideRight",
"from": [0, 4, 12],
"to": [1, 12, 16],
"faces": {
"north": {"uv": [12, 4, 13, 12], "texture": "#1", "cullface": "west"},
"east": {"uv": [0, 4, 4, 12], "texture": "#1", "cullface": "west"},
"west": {"uv": [12, 4, 16, 12], "texture": "#1", "cullface": "west"}
}
},
{
"name": "Window",
"from": [4, 4, 1],
"to": [12, 12, 1],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, -23]},
"faces": {
"north": {"uv": [0, 0, 8, 8], "texture": "#5", "cullface": "north"},
"south": {"uv": [0, 0, 8, 8], "texture": "#5", "cullface": "north"}
}
},
{
"name": "Window",
"from": [15, 4, 4],
"to": [15, 12, 12],
"faces": {
"east": {"uv": [0, 0, 8, 8], "texture": "#5", "cullface": "east"},
"west": {"uv": [0, 0, 8, 8], "texture": "#5", "cullface": "east"}
}
},
{
"name": "Window",
"from": [4, 4, 15],
"to": [12, 12, 15],
"faces": {
"north": {"uv": [0, 0, 8, 8], "texture": "#5", "cullface": "south"},
"south": {"uv": [0, 0, 8, 8], "texture": "#5", "cullface": "south"}
}
},
{
"name": "Window",
"from": [1, 4, 4],
"to": [1, 12, 12],
"faces": {
"east": {"uv": [0, 0, 8, 8], "texture": "#5", "cullface": "west"},
"west": {"uv": [0, 0, 8, 8], "texture": "#5", "cullface": "west"}
}
},
{
"name": "SideLeft",
"from": [12, 4, 0],
"to": [16, 12, 1],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, -23]},
"faces": {
"north": {"uv": [0, 4, 4, 12], "texture": "#1", "cullface": "north"},
"south": {"uv": [12, 4, 16, 12], "texture": "#1", "cullface": "north"},
"west": {"uv": [3, 4, 4, 12], "texture": "#1", "cullface": "north"}
}
},
{
"name": "SideLeft",
"from": [15, 4, 12],
"to": [16, 12, 16],
"faces": {
"north": {"uv": [3, 4, 4, 12], "texture": "#1", "cullface": "east"},
"east": {"uv": [0, 4, 4, 12], "texture": "#1", "cullface": "east"},
"west": {"uv": [12, 4, 16, 12], "texture": "#1", "cullface": "east"}
}
},
{
"name": "SideLeft",
"from": [0, 4, 15],
"to": [4, 12, 16],
"faces": {
"north": {"uv": [12, 4, 16, 12], "texture": "#1", "cullface": "south"},
"east": {"uv": [3, 4, 4, 12], "texture": "#1", "cullface": "south"},
"south": {"uv": [0, 4, 4, 12], "texture": "#1", "cullface": "south"}
}
},
{
"name": "SideLeft",
"from": [0, 4, 0],
"to": [1, 12, 4],
"faces": {
"east": {"uv": [12, 4, 16, 12], "texture": "#1", "cullface": "west"},
"south": {"uv": [3, 4, 4, 12], "texture": "#1", "cullface": "west"},
"west": {"uv": [0, 4, 4, 12], "texture": "#1", "cullface": "west"}
}
},
{
"name": "Bottom",
"from": [0, 0, 0],
"to": [16, 4, 16],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, -23]},
"faces": {
"north": {"uv": [0, 12, 16, 16], "texture": "#1", "cullface": "north"},
"east": {"uv": [0, 12, 16, 16], "texture": "#1", "cullface": "east"},
"south": {"uv": [0, 12, 16, 16], "texture": "#1", "cullface": "south"},
"west": {"uv": [0, 12, 16, 16], "texture": "#1", "cullface": "west"},
"up": {"uv": [0, 0, 16, 16], "texture": "#0"},
"down": {"uv": [0, 0, 16, 16], "texture": "#0", "cullface": "down"}
}
}
],
"groups": [
{
"name": "tank",
"origin": [8, 8, -23],
"children": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
}
]
}

View file

@ -0,0 +1,100 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"0": "create:block/copper_casing",
"1": "create:block/fluid_tank",
"4": "create:block/fluid_tank_window_single",
"particle": "create:block/fluid_tank"
},
"elements": [
{
"name": "SideRight",
"from": [15, 4, 0],
"to": [16, 12, 12],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 4, 8]},
"faces": {
"east": {"uv": [4, 4, 16, 12], "texture": "#1"},
"south": {"uv": [12, 4, 13, 12], "texture": "#1"},
"west": {"uv": [0, 4, 12, 12], "texture": "#1"}
}
},
{
"name": "Window",
"from": [0, 4, 1],
"to": [4, 12, 1],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 4, 8]},
"faces": {
"north": {"uv": [0, 0, 4, 8], "texture": "#4"},
"south": {"uv": [4, 0, 8, 8], "texture": "#4"}
}
},
{
"name": "Window",
"from": [15, 4, 12],
"to": [15, 12, 16],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 4, 8]},
"faces": {
"east": {"uv": [4, 0, 8, 8], "texture": "#4"},
"west": {"uv": [0, 0, 4, 8], "texture": "#4"}
}
},
{
"name": "SideLeft",
"from": [4, 4, 0],
"to": [16, 12, 1],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 4, 8]},
"faces": {
"north": {"uv": [0, 4, 12, 12], "texture": "#1"},
"south": {"uv": [4, 4, 16, 12], "texture": "#1"},
"west": {"uv": [3, 4, 4, 12], "texture": "#1"}
}
},
{
"name": "Bottom",
"from": [0, 12, 0],
"to": [16, 16, 16],
"rotation": {"angle": 0, "axis": "y", "origin": [-23, 8, 8]},
"faces": {
"north": {"uv": [0, 0, 16, 4], "texture": "#1"},
"east": {"uv": [0, 0, 16, 4], "texture": "#1"},
"south": {"uv": [0, 0, 16, 4], "texture": "#1"},
"west": {"uv": [0, 0, 16, 4], "texture": "#1"},
"up": {"uv": [0, 0, 16, 16], "texture": "#0", "cullface": "up"},
"down": {"uv": [0, 0, 16, 16], "texture": "#0"}
}
},
{
"name": "Bottom",
"from": [0, 0, 0],
"to": [16, 4, 16],
"rotation": {"angle": 0, "axis": "y", "origin": [-23, 8, 8]},
"faces": {
"north": {"uv": [0, 12, 16, 16], "texture": "#1"},
"east": {"uv": [0, 12, 16, 16], "texture": "#1"},
"south": {"uv": [0, 12, 16, 16], "texture": "#1"},
"west": {"uv": [0, 12, 16, 16], "texture": "#1"},
"up": {"uv": [0, 0, 16, 16], "texture": "#0"},
"down": {"uv": [0, 0, 16, 16], "texture": "#0", "cullface": "down"}
}
}
],
"groups": [
{
"name": "tank",
"origin": [8, 8, -23],
"children": [0, 1, 2, 3, 4]
},
{
"name": "block_bottom_centered_window",
"origin": [8, 8, 8],
"children": [
{
"name": "tank",
"origin": [8, 8, -23],
"children": [5]
}
]
}
]
}

View file

@ -0,0 +1,100 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"0": "create:block/copper_casing",
"1": "create:block/fluid_tank",
"4": "create:block/fluid_tank_window_single",
"particle": "create:block/fluid_tank"
},
"elements": [
{
"name": "SideRight",
"from": [0, 4, 0],
"to": [12, 12, 1],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 4, 8]},
"faces": {
"north": {"uv": [4, 4, 16, 12], "texture": "#1"},
"east": {"uv": [12, 4, 13, 12], "texture": "#1"},
"south": {"uv": [0, 4, 12, 12], "texture": "#1"}
}
},
{
"name": "Window",
"from": [1, 4, 12],
"to": [1, 12, 16],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 4, 8]},
"faces": {
"east": {"uv": [4, 0, 8, 8], "texture": "#4"},
"west": {"uv": [0, 0, 4, 8], "texture": "#4"}
}
},
{
"name": "Window",
"from": [12, 4, 1],
"to": [16, 12, 1],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 4, 8]},
"faces": {
"north": {"uv": [4, 0, 8, 8], "texture": "#4"},
"south": {"uv": [0, 0, 4, 8], "texture": "#4"}
}
},
{
"name": "SideLeft",
"from": [0, 4, 0],
"to": [1, 12, 12],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 4, 8]},
"faces": {
"east": {"uv": [4, 4, 16, 12], "texture": "#1"},
"south": {"uv": [3, 4, 4, 12], "texture": "#1"},
"west": {"uv": [0, 4, 12, 12], "texture": "#1"}
}
},
{
"name": "Bottom",
"from": [0, 12, 0],
"to": [16, 16, 16],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 39]},
"faces": {
"north": {"uv": [0, 0, 16, 4], "texture": "#1"},
"east": {"uv": [0, 0, 16, 4], "texture": "#1"},
"south": {"uv": [0, 0, 16, 4], "texture": "#1"},
"west": {"uv": [0, 0, 16, 4], "texture": "#1"},
"up": {"uv": [0, 0, 16, 16], "texture": "#0", "cullface": "up"},
"down": {"uv": [0, 0, 16, 16], "texture": "#0"}
}
},
{
"name": "Bottom",
"from": [0, 0, 0],
"to": [16, 4, 16],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 39]},
"faces": {
"north": {"uv": [0, 12, 16, 16], "texture": "#1"},
"east": {"uv": [0, 12, 16, 16], "texture": "#1"},
"south": {"uv": [0, 12, 16, 16], "texture": "#1"},
"west": {"uv": [0, 12, 16, 16], "texture": "#1"},
"up": {"uv": [0, 0, 16, 16], "texture": "#0"},
"down": {"uv": [0, 0, 16, 16], "texture": "#0", "cullface": "down"}
}
}
],
"groups": [
{
"name": "tank",
"origin": [8, 8, -23],
"children": [0, 1, 2, 3, 4]
},
{
"name": "block_bottom_centered_window",
"origin": [8, 8, 8],
"children": [
{
"name": "tank",
"origin": [8, 8, -23],
"children": [5]
}
]
}
]
}

View file

@ -0,0 +1,100 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"0": "create:block/copper_casing",
"1": "create:block/fluid_tank",
"4": "create:block/fluid_tank_window_single",
"particle": "create:block/fluid_tank"
},
"elements": [
{
"name": "SideRight",
"from": [4, 4, 15],
"to": [16, 12, 16],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 4, 8]},
"faces": {
"north": {"uv": [0, 4, 12, 12], "texture": "#1"},
"south": {"uv": [4, 4, 16, 12], "texture": "#1"},
"west": {"uv": [12, 4, 13, 12], "texture": "#1"}
}
},
{
"name": "Window",
"from": [15, 4, 0],
"to": [15, 12, 4],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 4, 8]},
"faces": {
"east": {"uv": [0, 0, 4, 8], "texture": "#4"},
"west": {"uv": [4, 0, 8, 8], "texture": "#4"}
}
},
{
"name": "Window",
"from": [0, 4, 15],
"to": [4, 12, 15],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 4, 8]},
"faces": {
"north": {"uv": [0, 0, 4, 8], "texture": "#4"},
"south": {"uv": [4, 0, 8, 8], "texture": "#4"}
}
},
{
"name": "SideLeft",
"from": [15, 4, 4],
"to": [16, 12, 16],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 4, 8]},
"faces": {
"north": {"uv": [3, 4, 4, 12], "texture": "#1"},
"east": {"uv": [0, 4, 12, 12], "texture": "#1"},
"west": {"uv": [4, 4, 16, 12], "texture": "#1"}
}
},
{
"name": "Bottom",
"from": [0, 12, 0],
"to": [16, 16, 16],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, -23]},
"faces": {
"north": {"uv": [0, 0, 16, 4], "texture": "#1"},
"east": {"uv": [0, 0, 16, 4], "texture": "#1"},
"south": {"uv": [0, 0, 16, 4], "texture": "#1"},
"west": {"uv": [0, 0, 16, 4], "texture": "#1"},
"up": {"uv": [0, 0, 16, 16], "texture": "#0", "cullface": "up"},
"down": {"uv": [0, 0, 16, 16], "texture": "#0"}
}
},
{
"name": "Bottom",
"from": [0, 0, 0],
"to": [16, 4, 16],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, -23]},
"faces": {
"north": {"uv": [0, 12, 16, 16], "texture": "#1"},
"east": {"uv": [0, 12, 16, 16], "texture": "#1"},
"south": {"uv": [0, 12, 16, 16], "texture": "#1"},
"west": {"uv": [0, 12, 16, 16], "texture": "#1"},
"up": {"uv": [0, 0, 16, 16], "texture": "#0"},
"down": {"uv": [0, 0, 16, 16], "texture": "#0", "cullface": "down"}
}
}
],
"groups": [
{
"name": "tank",
"origin": [8, 8, -23],
"children": [0, 1, 2, 3, 4]
},
{
"name": "block_bottom_centered_window",
"origin": [8, 8, 8],
"children": [
{
"name": "tank",
"origin": [8, 8, -23],
"children": [5]
}
]
}
]
}

View file

@ -0,0 +1,100 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"0": "create:block/copper_casing",
"1": "create:block/fluid_tank",
"4": "create:block/fluid_tank_window_single",
"particle": "create:block/fluid_tank"
},
"elements": [
{
"name": "SideRight",
"from": [0, 4, 4],
"to": [1, 12, 16],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 4, 8]},
"faces": {
"north": {"uv": [12, 4, 13, 12], "texture": "#1"},
"east": {"uv": [0, 4, 12, 12], "texture": "#1"},
"west": {"uv": [4, 4, 16, 12], "texture": "#1"}
}
},
{
"name": "Window",
"from": [12, 4, 15],
"to": [16, 12, 15],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 4, 8]},
"faces": {
"north": {"uv": [4, 0, 8, 8], "texture": "#4"},
"south": {"uv": [0, 0, 4, 8], "texture": "#4"}
}
},
{
"name": "Window",
"from": [1, 4, 0],
"to": [1, 12, 4],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 4, 8]},
"faces": {
"east": {"uv": [0, 0, 4, 8], "texture": "#4"},
"west": {"uv": [4, 0, 8, 8], "texture": "#4"}
}
},
{
"name": "SideLeft",
"from": [0, 4, 15],
"to": [12, 12, 16],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 4, 8]},
"faces": {
"north": {"uv": [4, 4, 16, 12], "texture": "#1"},
"east": {"uv": [3, 4, 4, 12], "texture": "#1"},
"south": {"uv": [0, 4, 12, 12], "texture": "#1"}
}
},
{
"name": "Bottom",
"from": [0, 12, 0],
"to": [16, 16, 16],
"rotation": {"angle": 0, "axis": "y", "origin": [39, 8, 8]},
"faces": {
"north": {"uv": [0, 0, 16, 4], "texture": "#1"},
"east": {"uv": [0, 0, 16, 4], "texture": "#1"},
"south": {"uv": [0, 0, 16, 4], "texture": "#1"},
"west": {"uv": [0, 0, 16, 4], "texture": "#1"},
"up": {"uv": [0, 0, 16, 16], "texture": "#0", "cullface": "up"},
"down": {"uv": [0, 0, 16, 16], "texture": "#0"}
}
},
{
"name": "Bottom",
"from": [0, 0, 0],
"to": [16, 4, 16],
"rotation": {"angle": 0, "axis": "y", "origin": [39, 8, 8]},
"faces": {
"north": {"uv": [0, 12, 16, 16], "texture": "#1"},
"east": {"uv": [0, 12, 16, 16], "texture": "#1"},
"south": {"uv": [0, 12, 16, 16], "texture": "#1"},
"west": {"uv": [0, 12, 16, 16], "texture": "#1"},
"up": {"uv": [0, 0, 16, 16], "texture": "#0"},
"down": {"uv": [0, 0, 16, 16], "texture": "#0", "cullface": "down"}
}
}
],
"groups": [
{
"name": "tank",
"origin": [8, 8, -23],
"children": [0, 1, 2, 3, 4]
},
{
"name": "block_bottom_centered_window",
"origin": [8, 8, 8],
"children": [
{
"name": "tank",
"origin": [8, 8, -23],
"children": [5]
}
]
}
]
}

View file

@ -3,24 +3,67 @@
"parent": "block/block", "parent": "block/block",
"textures": { "textures": {
"0": "create:block/copper_casing", "0": "create:block/copper_casing",
"2": "create:block/fluid_tank", "1": "create:block/fluid_tank",
"3": "create:block/oxidized/copper_block_0", "particle": "create:block/fluid_tank"
"particle": "create:block/copper_casing"
}, },
"elements": [ "elements": [
{ {
"name": "top", "name": "Lid",
"from": [0, 12, 0], "from": [0, 12, 0],
"to": [16, 16, 16], "to": [16, 16, 16],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 20, 8]}, "rotation": {"angle": 0, "axis": "y", "origin": [8, 8, -23]},
"faces": { "faces": {
"north": {"uv": [0, 0, 16, 4], "texture": "#2"}, "north": {"uv": [0, 0, 16, 4], "texture": "#1", "cullface": "north"},
"east": {"uv": [0, 0, 16, 4], "texture": "#2"}, "east": {"uv": [0, 0, 16, 4], "texture": "#1", "cullface": "east"},
"south": {"uv": [0, 0, 16, 4], "texture": "#2"}, "south": {"uv": [0, 0, 16, 4], "texture": "#1", "cullface": "south"},
"west": {"uv": [0, 0, 16, 4], "texture": "#2"}, "west": {"uv": [0, 0, 16, 4], "texture": "#1", "cullface": "west"},
"up": {"uv": [0, 0, 16, 16], "texture": "#3"}, "up": {"uv": [0, 0, 16, 16], "texture": "#0", "cullface": "up"},
"down": {"uv": [0, 0, 16, 16], "texture": "#0"} "down": {"uv": [0, 0, 16, 16], "texture": "#0"}
} }
},
{
"name": "SideRight",
"from": [0, 0, 0],
"to": [16, 12, 1],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, -23]},
"faces": {
"north": {"uv": [0, 4, 16, 16], "texture": "#1", "cullface": "north"},
"south": {"uv": [0, 4, 16, 16], "texture": "#1", "cullface": "north"}
}
},
{
"name": "SideRight",
"from": [15, 0, 0],
"to": [16, 12, 16],
"faces": {
"east": {"uv": [0, 4, 16, 16], "texture": "#1", "cullface": "east"},
"west": {"uv": [0, 4, 16, 16], "texture": "#1", "cullface": "east"}
}
},
{
"name": "SideRight",
"from": [0, 0, 15],
"to": [16, 12, 16],
"faces": {
"north": {"uv": [0, 4, 16, 16], "texture": "#1", "cullface": "south"},
"south": {"uv": [0, 4, 16, 16], "texture": "#1", "cullface": "south"}
}
},
{
"name": "SideRight",
"from": [0, 0, 0],
"to": [1, 12, 16],
"faces": {
"east": {"uv": [0, 4, 16, 16], "texture": "#1", "cullface": "west"},
"west": {"uv": [0, 4, 16, 16], "texture": "#1", "cullface": "west"}
}
}
],
"groups": [
{
"name": "tank",
"origin": [8, 8, -23],
"children": [0, 1, 2, 3, 4]
} }
] ]
} }

View file

@ -0,0 +1,152 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"0": "create:block/copper_casing",
"1": "create:block/fluid_tank",
"3": "create:block/fluid_tank_window",
"particle": "create:block/fluid_tank"
},
"elements": [
{
"name": "Lid",
"from": [0, 12, 0],
"to": [16, 16, 16],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, -23]},
"faces": {
"north": {"uv": [0, 0, 16, 4], "texture": "#1", "cullface": "north"},
"east": {"uv": [0, 0, 16, 4], "texture": "#1", "cullface": "east"},
"south": {"uv": [0, 0, 16, 4], "texture": "#1", "cullface": "south"},
"west": {"uv": [0, 0, 16, 4], "texture": "#1", "cullface": "west"},
"up": {"uv": [0, 0, 16, 16], "texture": "#0", "cullface": "up"},
"down": {"uv": [0, 0, 16, 16], "texture": "#0"}
}
},
{
"name": "SideRight",
"from": [0, 0, 0],
"to": [4, 12, 1],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, -23]},
"faces": {
"north": {"uv": [12, 4, 16, 16], "texture": "#1", "cullface": "north"},
"east": {"uv": [12, 4, 13, 16], "texture": "#1", "cullface": "north"},
"south": {"uv": [0, 4, 4, 16], "texture": "#1", "cullface": "north"}
}
},
{
"name": "SideRight",
"from": [15, 0, 0],
"to": [16, 12, 4],
"faces": {
"east": {"uv": [12, 4, 16, 16], "texture": "#1", "cullface": "east"},
"south": {"uv": [12, 4, 13, 16], "texture": "#1", "cullface": "east"},
"west": {"uv": [0, 4, 4, 16], "texture": "#1", "cullface": "east"}
}
},
{
"name": "SideRight",
"from": [12, 0, 15],
"to": [16, 12, 16],
"faces": {
"north": {"uv": [0, 4, 4, 16], "texture": "#1", "cullface": "south"},
"south": {"uv": [12, 4, 16, 16], "texture": "#1", "cullface": "south"},
"west": {"uv": [12, 4, 13, 16], "texture": "#1", "cullface": "south"}
}
},
{
"name": "SideRight",
"from": [0, 0, 12],
"to": [1, 12, 16],
"faces": {
"north": {"uv": [12, 4, 13, 16], "texture": "#1", "cullface": "west"},
"east": {"uv": [0, 4, 4, 16], "texture": "#1", "cullface": "west"},
"west": {"uv": [12, 4, 16, 16], "texture": "#1", "cullface": "west"}
}
},
{
"name": "Window",
"from": [4, 0, 1],
"to": [12, 12, 1],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, -23]},
"faces": {
"north": {"uv": [0, 0, 8, 12], "texture": "#3", "cullface": "north"},
"south": {"uv": [0, 0, 8, 12], "texture": "#3", "cullface": "north"}
}
},
{
"name": "Window",
"from": [15, 0, 4],
"to": [15, 12, 12],
"faces": {
"east": {"uv": [0, 0, 8, 12], "texture": "#3", "cullface": "east"},
"west": {"uv": [0, 0, 8, 12], "texture": "#3", "cullface": "east"}
}
},
{
"name": "Window",
"from": [4, 0, 15],
"to": [12, 12, 15],
"faces": {
"north": {"uv": [0, 0, 8, 12], "texture": "#3", "cullface": "south"},
"south": {"uv": [0, 0, 8, 12], "texture": "#3", "cullface": "south"}
}
},
{
"name": "Window",
"from": [1, 0, 4],
"to": [1, 12, 12],
"faces": {
"east": {"uv": [0, 0, 8, 12], "texture": "#3", "cullface": "west"},
"west": {"uv": [0, 0, 8, 12], "texture": "#3", "cullface": "west"}
}
},
{
"name": "SideLeft",
"from": [12, 0, 0],
"to": [16, 12, 1],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, -23]},
"faces": {
"north": {"uv": [0, 4, 4, 16], "texture": "#1", "cullface": "north"},
"south": {"uv": [12, 4, 16, 16], "texture": "#1", "cullface": "north"},
"west": {"uv": [3, 4, 4, 16], "texture": "#1", "cullface": "north"}
}
},
{
"name": "SideLeft",
"from": [15, 0, 12],
"to": [16, 12, 16],
"faces": {
"north": {"uv": [3, 4, 4, 16], "texture": "#1", "cullface": "east"},
"east": {"uv": [0, 4, 4, 16], "texture": "#1", "cullface": "east"},
"west": {"uv": [12, 4, 16, 16], "texture": "#1", "cullface": "east"}
}
},
{
"name": "SideLeft",
"from": [0, 0, 15],
"to": [4, 12, 16],
"faces": {
"north": {"uv": [12, 4, 16, 16], "texture": "#1", "cullface": "south"},
"east": {"uv": [3, 4, 4, 16], "texture": "#1", "cullface": "south"},
"south": {"uv": [0, 4, 4, 16], "texture": "#1", "cullface": "south"}
}
},
{
"name": "SideLeft",
"from": [0, 0, 0],
"to": [1, 12, 4],
"faces": {
"east": {"uv": [12, 4, 16, 16], "texture": "#1", "cullface": "west"},
"south": {"uv": [3, 4, 4, 16], "texture": "#1", "cullface": "west"},
"west": {"uv": [0, 4, 4, 16], "texture": "#1", "cullface": "west"}
}
}
],
"groups": [
{
"name": "tank",
"origin": [8, 8, -23],
"children": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
}
]
}

View file

@ -0,0 +1,75 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"0": "create:block/copper_casing",
"1": "create:block/fluid_tank",
"3": "create:block/fluid_tank_window",
"particle": "create:block/fluid_tank"
},
"elements": [
{
"name": "SideRight",
"from": [15, 0, 0],
"to": [16, 12, 12],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 4, 8]},
"faces": {
"east": {"uv": [4, 4, 16, 16], "texture": "#1"},
"south": {"uv": [12, 4, 13, 16], "texture": "#1"},
"west": {"uv": [0, 4, 12, 16], "texture": "#1"}
}
},
{
"name": "Window",
"from": [0, 0, 1],
"to": [4, 12, 1],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 4, 8]},
"faces": {
"north": {"uv": [0, 0, 4, 12], "texture": "#3"},
"south": {"uv": [4, 0, 8, 12], "texture": "#3"}
}
},
{
"name": "Window",
"from": [15, 0, 12],
"to": [15, 12, 16],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 4, 8]},
"faces": {
"east": {"uv": [4, 0, 8, 12], "texture": "#3"},
"west": {"uv": [0, 0, 4, 12], "texture": "#3"}
}
},
{
"name": "SideLeft",
"from": [4, 0, 0],
"to": [16, 12, 1],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 4, 8]},
"faces": {
"north": {"uv": [0, 4, 12, 16], "texture": "#1"},
"south": {"uv": [4, 4, 16, 16], "texture": "#1"},
"west": {"uv": [3, 4, 4, 16], "texture": "#1"}
}
},
{
"name": "Bottom",
"from": [0, 12, 0],
"to": [16, 16, 16],
"rotation": {"angle": 0, "axis": "y", "origin": [-23, 8, 8]},
"faces": {
"north": {"uv": [0, 0, 16, 4], "texture": "#1"},
"east": {"uv": [0, 0, 16, 4], "texture": "#1"},
"south": {"uv": [0, 0, 16, 4], "texture": "#1"},
"west": {"uv": [0, 0, 16, 4], "texture": "#1"},
"up": {"uv": [0, 0, 16, 16], "texture": "#0", "cullface": "up"},
"down": {"uv": [0, 0, 16, 16], "texture": "#0"}
}
}
],
"groups": [
{
"name": "tank",
"origin": [8, 8, -23],
"children": [0, 1, 2, 3, 4]
}
]
}

View file

@ -0,0 +1,75 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"0": "create:block/copper_casing",
"1": "create:block/fluid_tank",
"3": "create:block/fluid_tank_window",
"particle": "create:block/fluid_tank"
},
"elements": [
{
"name": "SideRight",
"from": [0, 0, 0],
"to": [12, 12, 1],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 4, 8]},
"faces": {
"north": {"uv": [4, 4, 16, 16], "texture": "#1"},
"east": {"uv": [12, 4, 13, 16], "texture": "#1"},
"south": {"uv": [0, 4, 12, 16], "texture": "#1"}
}
},
{
"name": "Window",
"from": [1, 0, 12],
"to": [1, 12, 16],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 4, 8]},
"faces": {
"east": {"uv": [4, 0, 8, 12], "texture": "#3"},
"west": {"uv": [0, 0, 4, 12], "texture": "#3"}
}
},
{
"name": "Window",
"from": [12, 0, 1],
"to": [16, 12, 1],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 4, 8]},
"faces": {
"north": {"uv": [4, 0, 8, 12], "texture": "#3"},
"south": {"uv": [0, 0, 4, 12], "texture": "#3"}
}
},
{
"name": "SideLeft",
"from": [0, 0, 0],
"to": [1, 12, 12],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 4, 8]},
"faces": {
"east": {"uv": [4, 4, 16, 16], "texture": "#1"},
"south": {"uv": [3, 4, 4, 16], "texture": "#1"},
"west": {"uv": [0, 4, 12, 16], "texture": "#1"}
}
},
{
"name": "Bottom",
"from": [0, 12, 0],
"to": [16, 16, 16],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 39]},
"faces": {
"north": {"uv": [0, 0, 16, 4], "texture": "#1"},
"east": {"uv": [0, 0, 16, 4], "texture": "#1"},
"south": {"uv": [0, 0, 16, 4], "texture": "#1"},
"west": {"uv": [0, 0, 16, 4], "texture": "#1"},
"up": {"uv": [0, 0, 16, 16], "texture": "#0", "cullface": "up"},
"down": {"uv": [0, 0, 16, 16], "texture": "#0"}
}
}
],
"groups": [
{
"name": "tank",
"origin": [8, 8, -23],
"children": [0, 1, 2, 3, 4]
}
]
}

View file

@ -0,0 +1,75 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"0": "create:block/copper_casing",
"1": "create:block/fluid_tank",
"3": "create:block/fluid_tank_window",
"particle": "create:block/fluid_tank"
},
"elements": [
{
"name": "SideRight",
"from": [4, 0, 15],
"to": [16, 12, 16],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 4, 8]},
"faces": {
"north": {"uv": [0, 4, 12, 16], "texture": "#1"},
"south": {"uv": [4, 4, 16, 16], "texture": "#1"},
"west": {"uv": [12, 4, 13, 16], "texture": "#1"}
}
},
{
"name": "Window",
"from": [15, 0, 0],
"to": [15, 12, 4],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 4, 8]},
"faces": {
"east": {"uv": [0, 0, 4, 12], "texture": "#3"},
"west": {"uv": [4, 0, 8, 12], "texture": "#3"}
}
},
{
"name": "Window",
"from": [0, 0, 15],
"to": [4, 12, 15],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 4, 8]},
"faces": {
"north": {"uv": [0, 0, 4, 12], "texture": "#3"},
"south": {"uv": [4, 0, 8, 12], "texture": "#3"}
}
},
{
"name": "SideLeft",
"from": [15, 0, 4],
"to": [16, 12, 16],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 4, 8]},
"faces": {
"north": {"uv": [3, 4, 4, 16], "texture": "#1"},
"east": {"uv": [0, 4, 12, 16], "texture": "#1"},
"west": {"uv": [4, 4, 16, 16], "texture": "#1"}
}
},
{
"name": "Bottom",
"from": [0, 12, 0],
"to": [16, 16, 16],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, -23]},
"faces": {
"north": {"uv": [0, 0, 16, 4], "texture": "#1"},
"east": {"uv": [0, 0, 16, 4], "texture": "#1"},
"south": {"uv": [0, 0, 16, 4], "texture": "#1"},
"west": {"uv": [0, 0, 16, 4], "texture": "#1"},
"up": {"uv": [0, 0, 16, 16], "texture": "#0", "cullface": "up"},
"down": {"uv": [0, 0, 16, 16], "texture": "#0"}
}
}
],
"groups": [
{
"name": "tank",
"origin": [8, 8, -23],
"children": [0, 1, 2, 3, 4]
}
]
}

View file

@ -0,0 +1,75 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"0": "create:block/copper_casing",
"1": "create:block/fluid_tank",
"3": "create:block/fluid_tank_window",
"particle": "create:block/fluid_tank"
},
"elements": [
{
"name": "SideRight",
"from": [0, 0, 4],
"to": [1, 12, 16],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 4, 8]},
"faces": {
"north": {"uv": [12, 4, 13, 16], "texture": "#1"},
"east": {"uv": [0, 4, 12, 16], "texture": "#1"},
"west": {"uv": [4, 4, 16, 16], "texture": "#1"}
}
},
{
"name": "Window",
"from": [12, 0, 15],
"to": [16, 12, 15],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 4, 8]},
"faces": {
"north": {"uv": [4, 0, 8, 12], "texture": "#3"},
"south": {"uv": [0, 0, 4, 12], "texture": "#3"}
}
},
{
"name": "Window",
"from": [1, 0, 0],
"to": [1, 12, 4],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 4, 8]},
"faces": {
"east": {"uv": [0, 0, 4, 12], "texture": "#3"},
"west": {"uv": [4, 0, 8, 12], "texture": "#3"}
}
},
{
"name": "SideLeft",
"from": [0, 0, 15],
"to": [12, 12, 16],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 4, 8]},
"faces": {
"north": {"uv": [4, 4, 16, 16], "texture": "#1"},
"east": {"uv": [3, 4, 4, 16], "texture": "#1"},
"south": {"uv": [0, 4, 12, 16], "texture": "#1"}
}
},
{
"name": "Bottom",
"from": [0, 12, 0],
"to": [16, 16, 16],
"rotation": {"angle": 0, "axis": "y", "origin": [39, 8, 8]},
"faces": {
"north": {"uv": [0, 0, 16, 4], "texture": "#1"},
"east": {"uv": [0, 0, 16, 4], "texture": "#1"},
"south": {"uv": [0, 0, 16, 4], "texture": "#1"},
"west": {"uv": [0, 0, 16, 4], "texture": "#1"},
"up": {"uv": [0, 0, 16, 16], "texture": "#0", "cullface": "up"},
"down": {"uv": [0, 0, 16, 16], "texture": "#0"}
}
}
],
"groups": [
{
"name": "tank",
"origin": [8, 8, -23],
"children": [0, 1, 2, 3, 4]
}
]
}

View file

@ -1,27 +0,0 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"2": "create:block/fluid_tank",
"particle": "create:block/copper_casing"
},
"elements": [
{
"from": [1, 0, 0],
"to": [15, 16, 16],
"rotation": {"angle": 0, "axis": "y", "origin": [7, 12, 9]},
"faces": {
"east": {"uv": [0, 0, 16, 16], "texture": "#2", "cullface": "east"},
"west": {"uv": [0, 0, 16, 16], "texture": "#2", "cullface": "west"}
}
},
{
"from": [0, 0, 1],
"to": [16, 16, 15],
"faces": {
"north": {"uv": [0, 0, 16, 16], "texture": "#2", "cullface": "north"},
"south": {"uv": [0, 0, 16, 16], "texture": "#2", "cullface": "south"}
}
}
]
}

View file

@ -1,25 +0,0 @@
{
"credit": "Made with Blockbench",
"textures": {
"0": "create:block/fluid_tank",
"particle": "create:block/fluid_tank"
},
"elements": [
{
"from": [15, 0, 1],
"to": [16, 16, 2],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 9]},
"faces": {
"north": {"uv": [14, 0, 15, 16], "texture": "#0"}
}
},
{
"from": [14, 0, 0],
"to": [15, 16, 1],
"rotation": {"angle": 0, "axis": "y", "origin": [7, 8, 8]},
"faces": {
"east": {"uv": [14, 0, 15, 16], "texture": "#0"}
}
}
]
}

View file

@ -1,25 +0,0 @@
{
"credit": "Made with Blockbench",
"textures": {
"0": "create:block/fluid_tank",
"particle": "create:block/fluid_tank"
},
"elements": [
{
"from": [1, 0, 0],
"to": [2, 16, 1],
"rotation": {"angle": 0, "axis": "y", "origin": [9, 8, 8]},
"faces": {
"west": {"uv": [14, 0, 15, 16], "texture": "#0"}
}
},
{
"from": [0, 0, 1],
"to": [1, 16, 2],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 9]},
"faces": {
"north": {"uv": [14, 0, 15, 16], "texture": "#0"}
}
}
]
}

View file

@ -1,24 +0,0 @@
{
"credit": "Made with Blockbench",
"textures": {
"0": "create:block/fluid_tank",
"particle": "create:block/fluid_tank"
},
"elements": [
{
"from": [14, 0, 15],
"to": [15, 16, 16],
"faces": {
"east": {"uv": [14, 0, 15, 16], "texture": "#0"}
}
},
{
"from": [15, 0, 14],
"to": [16, 16, 15],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 7]},
"faces": {
"south": {"uv": [14, 0, 15, 16], "texture": "#0"}
}
}
]
}

View file

@ -1,24 +0,0 @@
{
"credit": "Made with Blockbench",
"textures": {
"0": "create:block/fluid_tank",
"particle": "create:block/fluid_tank"
},
"elements": [
{
"from": [0, 0, 14],
"to": [1, 16, 15],
"faces": {
"south": {"uv": [14, 0, 15, 16], "texture": "#0"}
}
},
{
"from": [1, 0, 15],
"to": [2, 16, 16],
"rotation": {"angle": 0, "axis": "y", "origin": [9, 8, 8]},
"faces": {
"west": {"uv": [14, 0, 15, 16], "texture": "#0"}
}
}
]
}

View file

@ -1,56 +0,0 @@
{
"credit": "Made with Blockbench",
"parent": "block/block",
"textures": {
"0": "create:block/copper_casing",
"2": "create:block/fluid_tank",
"3": "create:block/oxidized/copper_block_0",
"particle": "create:block/copper_casing"
},
"elements": [
{
"name": "bottom",
"from": [0, 0, 0],
"to": [16, 4, 16],
"faces": {
"north": {"uv": [0, 12, 16, 16], "texture": "#2"},
"east": {"uv": [0, 12, 16, 16], "texture": "#2"},
"south": {"uv": [0, 12, 16, 16], "texture": "#2"},
"west": {"uv": [0, 12, 16, 16], "texture": "#2"},
"up": {"uv": [0, 0, 16, 16], "texture": "#0"},
"down": {"uv": [0, 0, 16, 16], "texture": "#3"}
}
},
{
"name": "top",
"from": [0, 12, 0],
"to": [16, 16, 16],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 20, 8]},
"faces": {
"north": {"uv": [0, 0, 16, 4], "texture": "#2"},
"east": {"uv": [0, 0, 16, 4], "texture": "#2"},
"south": {"uv": [0, 0, 16, 4], "texture": "#2"},
"west": {"uv": [0, 0, 16, 4], "texture": "#2"},
"up": {"uv": [0, 0, 16, 16], "texture": "#3"},
"down": {"uv": [0, 0, 16, 16], "texture": "#0"}
}
},
{
"from": [1, 0, 0],
"to": [15, 16, 16],
"rotation": {"angle": 0, "axis": "y", "origin": [7, 12, 9]},
"faces": {
"east": {"uv": [0, 0, 16, 16], "texture": "#2"},
"west": {"uv": [0, 0, 16, 16], "texture": "#2"}
}
},
{
"from": [0, 0, 1],
"to": [16, 16, 15],
"faces": {
"north": {"uv": [0, 0, 16, 16], "texture": "#2"},
"south": {"uv": [0, 0, 16, 16], "texture": "#2"}
}
}
]
}

View file

@ -1,22 +0,0 @@
{
"credit": "Made with Blockbench",
"textures": {
"0": "create:block/fluid_tank",
"particle": "create:block/fluid_tank"
},
"elements": [
{
"from": [16, 0, 0],
"to": [17, 4, 16],
"rotation": {"angle": 0, "axis": "y", "origin": [9, 8, 8]},
"faces": {
"north": {"uv": [15, 12, 16, 16], "texture": "#0"},
"east": {"uv": [0, 12, 16, 16], "texture": "#0"},
"south": {"uv": [0, 12, 1, 16], "texture": "#0"},
"west": {"uv": [0, 12, 16, 16], "texture": "#0"},
"up": {"uv": [0, 12, 16, 13], "rotation": 90, "texture": "#0"},
"down": {"uv": [0, 15, 16, 16], "rotation": 270, "texture": "#0"}
}
}
]
}

View file

@ -1,22 +0,0 @@
{
"credit": "Made with Blockbench",
"textures": {
"0": "create:block/fluid_tank",
"particle": "create:block/fluid_tank"
},
"elements": [
{
"from": [0, 0, -1],
"to": [16, 4, 0],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 7]},
"faces": {
"north": {"uv": [0, 12, 16, 16], "texture": "#0"},
"east": {"uv": [0, 12, 1, 16], "texture": "#0"},
"south": {"uv": [0, 12, 16, 16], "texture": "#0"},
"west": {"uv": [15, 12, 16, 16], "texture": "#0"},
"up": {"uv": [0, 12, 16, 13], "texture": "#0"},
"down": {"uv": [0, 15, 16, 16], "texture": "#0"}
}
}
]
}

View file

@ -1,22 +0,0 @@
{
"credit": "Made with Blockbench",
"textures": {
"0": "create:block/fluid_tank",
"particle": "create:block/fluid_tank"
},
"elements": [
{
"from": [0, 0, 16],
"to": [16, 4, 17],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 9]},
"faces": {
"north": {"uv": [0, 12, 16, 16], "texture": "#0"},
"east": {"uv": [15, 12, 16, 16], "texture": "#0"},
"south": {"uv": [0, 12, 16, 16], "texture": "#0"},
"west": {"uv": [0, 12, 1, 16], "texture": "#0"},
"up": {"uv": [0, 12, 16, 13], "rotation": 180, "texture": "#0"},
"down": {"uv": [0, 15, 16, 16], "rotation": 180, "texture": "#0"}
}
}
]
}

View file

@ -1,22 +0,0 @@
{
"credit": "Made with Blockbench",
"textures": {
"0": "create:block/fluid_tank",
"particle": "create:block/fluid_tank"
},
"elements": [
{
"from": [-1, 0, 0],
"to": [0, 4, 16],
"rotation": {"angle": 0, "axis": "y", "origin": [7, 8, 8]},
"faces": {
"north": {"uv": [0, 12, 1, 16], "texture": "#0"},
"east": {"uv": [0, 12, 16, 16], "texture": "#0"},
"south": {"uv": [15, 12, 16, 16], "texture": "#0"},
"west": {"uv": [0, 12, 16, 16], "texture": "#0"},
"up": {"uv": [0, 12, 16, 13], "rotation": 270, "texture": "#0"},
"down": {"uv": [0, 15, 16, 16], "rotation": 90, "texture": "#0"}
}
}
]
}

View file

@ -1,22 +0,0 @@
{
"credit": "Made with Blockbench",
"textures": {
"0": "create:block/fluid_tank",
"particle": "create:block/fluid_tank"
},
"elements": [
{
"from": [16, 12, 0],
"to": [17, 16, 16],
"rotation": {"angle": 0, "axis": "y", "origin": [9, 20, 8]},
"faces": {
"north": {"uv": [15, 0, 16, 4], "texture": "#0"},
"east": {"uv": [0, 0, 16, 4], "texture": "#0"},
"south": {"uv": [0, 0, 1, 4], "texture": "#0"},
"west": {"uv": [0, 0, 16, 4], "texture": "#0"},
"up": {"uv": [0, 0, 16, 1], "rotation": 90, "texture": "#0"},
"down": {"uv": [0, 3, 16, 4], "rotation": 270, "texture": "#0"}
}
}
]
}

View file

@ -1,22 +0,0 @@
{
"credit": "Made with Blockbench",
"textures": {
"0": "create:block/fluid_tank",
"particle": "create:block/fluid_tank"
},
"elements": [
{
"from": [0, 12, -1],
"to": [16, 16, 0],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 20, 7]},
"faces": {
"north": {"uv": [0, 0, 16, 4], "texture": "#0"},
"east": {"uv": [0, 0, 1, 4], "texture": "#0"},
"south": {"uv": [0, 0, 16, 4], "texture": "#0"},
"west": {"uv": [15, 0, 16, 4], "texture": "#0"},
"up": {"uv": [0, 0, 16, 1], "texture": "#0"},
"down": {"uv": [0, 3, 16, 4], "texture": "#0"}
}
}
]
}

View file

@ -1,22 +0,0 @@
{
"credit": "Made with Blockbench",
"textures": {
"0": "create:block/fluid_tank",
"particle": "create:block/fluid_tank"
},
"elements": [
{
"from": [0, 12, 16],
"to": [16, 16, 17],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 20, 9]},
"faces": {
"north": {"uv": [0, 0, 16, 4], "texture": "#0"},
"east": {"uv": [15, 0, 16, 4], "texture": "#0"},
"south": {"uv": [0, 0, 16, 4], "texture": "#0"},
"west": {"uv": [0, 0, 1, 4], "texture": "#0"},
"up": {"uv": [0, 0, 16, 1], "rotation": 180, "texture": "#0"},
"down": {"uv": [0, 3, 16, 4], "rotation": 180, "texture": "#0"}
}
}
]
}

View file

@ -1,22 +0,0 @@
{
"credit": "Made with Blockbench",
"textures": {
"0": "create:block/fluid_tank",
"particle": "create:block/fluid_tank"
},
"elements": [
{
"from": [-1, 12, 0],
"to": [0, 16, 16],
"rotation": {"angle": 0, "axis": "y", "origin": [7, 20, 8]},
"faces": {
"north": {"uv": [0, 0, 1, 4], "texture": "#0"},
"east": {"uv": [0, 0, 16, 4], "texture": "#0"},
"south": {"uv": [15, 0, 16, 4], "texture": "#0"},
"west": {"uv": [0, 0, 16, 4], "texture": "#0"},
"up": {"uv": [0, 0, 16, 1], "rotation": 270, "texture": "#0"},
"down": {"uv": [0, 3, 16, 4], "rotation": 90, "texture": "#0"}
}
}
]
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 503 B

After

Width:  |  Height:  |  Size: 238 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 351 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 210 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 567 B

After

Width:  |  Height:  |  Size: 535 B