Skip to content

Commit

Permalink
feat: make Storage Sac Block directional and water loggable
Browse files Browse the repository at this point in the history
  • Loading branch information
Elenterius committed Jun 16, 2023
1 parent bf44438 commit 0f7afe5
Show file tree
Hide file tree
Showing 4 changed files with 135 additions and 52 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,12 @@ public void fleshSpikes(Block block) {
simpleBlockItem(block, models[0]);
}

public void storageSac(Block block) {
ModelFile.ExistingModelFile existingModel = models().getExistingFile(blockModel(block));
directionalBlock(block, blockState -> existingModel, BlockStateProperties.WATERLOGGED);
simpleBlockItem(block, existingModel);
}

private void geoBlockItem(Block block, Vector3f modelBounds) {
String path = path(block);

Expand Down Expand Up @@ -236,20 +242,6 @@ public void directionalSlabBlock(DirectionalSlabBlock block, ModelFile half, Mod
);
}

public void storageSac(Block block) {
ModelFile.ExistingModelFile existingModel = models().getExistingFile(blockModel(block));
getVariantBuilder(block)
.forAllStates(state -> {
Direction dir = state.getValue(BlockStateProperties.HORIZONTAL_FACING);
return ConfiguredModel.builder()
.modelFile(existingModel)
.rotationY(((int) dir.toYRot() + 180) % 360)
.build();
});

simpleBlockItem(block, existingModel);
}

public void tendonChain(FleshChainBlock block) {
ResourceLocation file = blockModel(block);
ModelFile.ExistingModelFile model = models().getExistingFile(file);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

import com.github.elenterius.biomancy.init.ModSoundEvents;
import com.github.elenterius.biomancy.util.SoundUtil;
import com.github.elenterius.biomancy.util.VoxelShapeUtil;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.InteractionHand;
Expand All @@ -14,14 +16,16 @@
import net.minecraft.world.item.context.BlockPlaceContext;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.BaseEntityBlock;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.RenderShape;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.block.*;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.StateDefinition;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.world.level.block.state.properties.BooleanProperty;
import net.minecraft.world.level.block.state.properties.DirectionProperty;
import net.minecraft.world.level.material.FluidState;
import net.minecraft.world.level.material.Fluids;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.shapes.BooleanOp;
import net.minecraft.world.phys.shapes.CollisionContext;
Expand All @@ -30,31 +34,46 @@
import net.minecraftforge.network.NetworkHooks;
import org.jetbrains.annotations.Nullable;

public class StorageSacBlock extends BaseEntityBlock {
public class StorageSacBlock extends BaseEntityBlock implements SimpleWaterloggedBlock {

public static final DirectionProperty FACING = BlockStateProperties.HORIZONTAL_FACING;
public static final DirectionProperty FACING = BlockStateProperties.FACING;
public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED;
public static final VoxelShape SHAPE_UP = createShape(Direction.UP);
public static final VoxelShape SHAPE_DOWN = createShape(Direction.DOWN);
public static final VoxelShape SHAPE_NORTH = createShape(Direction.NORTH);
public static final VoxelShape SHAPE_SOUTH = createShape(Direction.SOUTH);
public static final VoxelShape SHAPE_WEST = createShape(Direction.WEST);
public static final VoxelShape SHAPE_EAST = createShape(Direction.EAST);

protected static final VoxelShape SHAPE = createShape();
public StorageSacBlock(Properties properties) {
super(properties);
registerDefaultState(defaultBlockState().setValue(FACING, Direction.UP).setValue(WATERLOGGED, Boolean.FALSE));
}

private static VoxelShape createShape() {
VoxelShape base = Block.box(2d, 0d, 2d, 14d, 14d, 14d);
VoxelShape lid = Block.box(4d, 14d, 4d, 12d, 16d, 12d);
return Shapes.join(base, lid, BooleanOp.OR);
private static VoxelShape createShape(Direction direction) {
return Shapes.join(
VoxelShapeUtil.createXZRotatedTowards(direction, 4, 0, 4, 12, 2, 12),
VoxelShapeUtil.createXZRotatedTowards(direction, 2, 2, 2, 14, 16, 14), BooleanOp.OR);
}

public StorageSacBlock(Properties properties) {
super(properties);
public static Direction getFacing(BlockState state) {
return state.getValue(FACING);
}

public static boolean isWaterlogged(BlockState state) {
return state.getValue(WATERLOGGED);
}

@Override
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
builder.add(FACING);
builder.add(FACING, WATERLOGGED);
}

@Nullable
@Override
public BlockState getStateForPlacement(BlockPlaceContext context) {
return defaultBlockState().setValue(FACING, context.getHorizontalDirection().getOpposite());
boolean isWaterlogged = context.getLevel().getFluidState(context.getClickedPos()).getType() == Fluids.WATER;
return defaultBlockState().setValue(FACING, context.getClickedFace()).setValue(WATERLOGGED, isWaterlogged);
}

@Nullable
Expand Down Expand Up @@ -97,9 +116,40 @@ public void playerWillDestroy(Level level, BlockPos pos, BlockState state, Playe
super.playerWillDestroy(level, pos, state, player);
}

@Override
public BlockState updateShape(BlockState state, Direction direction, BlockState neighborState, LevelAccessor level, BlockPos currentPos, BlockPos neighborPos) {
if (isWaterlogged(state)) {
level.scheduleTick(currentPos, Fluids.WATER, Fluids.WATER.getTickDelay(level));
}

return super.updateShape(state, direction, neighborState, level, currentPos, neighborPos);
}

@Override
public FluidState getFluidState(BlockState state) {
return isWaterlogged(state) ? Fluids.WATER.getSource(false) : super.getFluidState(state);
}

@Override
public VoxelShape getShape(BlockState state, BlockGetter level, BlockPos pos, CollisionContext context) {
return SHAPE;
return switch (getFacing(state)) {
case DOWN -> SHAPE_DOWN;
case NORTH -> SHAPE_NORTH;
case SOUTH -> SHAPE_SOUTH;
case WEST -> SHAPE_WEST;
case EAST -> SHAPE_EAST;
default -> SHAPE_UP;
};
}

@Override
public BlockState rotate(BlockState state, Rotation rotation) {
return state.setValue(FACING, rotation.rotate(getFacing(state)));
}

@Override
public BlockState mirror(BlockState state, Mirror mirror) {
return state.rotate(mirror.getRotation(getFacing(state)));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.github.elenterius.biomancy.client.render.block.storagesac;

import com.github.elenterius.biomancy.block.storagesac.StorageSacBlock;
import com.github.elenterius.biomancy.block.storagesac.StorageSacBlockEntity;
import com.github.elenterius.biomancy.util.ItemStackCounter;
import com.mojang.blaze3d.vertex.PoseStack;
Expand All @@ -8,6 +9,7 @@
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer;
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
import net.minecraft.client.renderer.entity.ItemRenderer;
import net.minecraft.core.Direction;
import net.minecraft.util.RandomSource;
import net.minecraft.world.item.ItemStack;

Expand All @@ -22,39 +24,78 @@ public StorageSacRenderer(BlockEntityRendererProvider.Context context) {
itemRenderer = context.getItemRenderer();
}

private float randomOffset(float amount) {
return (random.nextFloat() * 2f - 1) * amount;
}

@Override
public void render(StorageSacBlockEntity blockEntity, float partialTick, PoseStack poseStack, MultiBufferSource bufferSource, int packedLight, int packedOverlay) {
int seed = (int) blockEntity.getBlockPos().asLong() + blockEntity.getBlockPos().getX() - 1;
random.setSeed(seed);

List<ItemStackCounter.CountedItem> items = blockEntity.getItemsForRendering();
int size = items.size();
ItemTranslator itemTranslator = ItemTranslator.from(StorageSacBlock.getFacing(blockEntity.getBlockState()));
renderItemsOnAxis(poseStack, bufferSource, packedLight, packedOverlay, blockEntity.getItemsForRendering(), itemTranslator, 0.375f);
}

private void renderItemsOnAxis(PoseStack poseStack, MultiBufferSource bufferSource, int packedLight, int packedOverlay, List<ItemStackCounter.CountedItem> items, ItemTranslator itemTranslator, float itemScale) {
int numberOfItems = items.size();

for (int i = 0; i < numberOfItems; i++) {
ItemStack stack = items.get(i).stack();
if (stack.isEmpty()) continue;

poseStack.pushPose();

for (int i = 0; i < size; i++) {
ItemStackCounter.CountedItem countedItem = items.get(i);
ItemStack stack = countedItem.stack();
if (!stack.isEmpty()) {
float x = 0.5f + randomOffset(0.175f);
float y = 0.25f + ((i + 1f) / numberOfItems) * 0.5f;
float z = 0.5f + randomOffset(0.175f);
itemTranslator.translate(poseStack, x, y, z);

int amount = stack.getCount();
for (int j = 0; j < amount; j++) {
poseStack.pushPose();
float x = 0.5f + (random.nextFloat() * 2f - 1) * 0.15f;
float z = 0.5f + (random.nextFloat() * 2f - 1) * 0.15f;
poseStack.translate(x, 0.15f + ((float) (i + 1) / size) * 0.5f, z);

int amount = stack.getCount();
for (int j = 0; j < amount; j++) {
poseStack.pushPose();
if (j > 0) {
float x2 = (random.nextFloat() * 2f - 1) * 0.15f;
float y2 = (random.nextFloat() * 2f - 1) * 0.35f;
float z2 = (random.nextFloat() * 2f - 1) * 0.15f;
poseStack.translate(x2 * 0.5f, y2 * 0.5f, z2 * 0.5f);
}
poseStack.scale(0.375f, 0.375f, 0.375f);
itemRenderer.renderStatic(stack, ItemTransforms.TransformType.FIXED, packedLight, packedOverlay, poseStack, bufferSource, 0);
poseStack.popPose();
if (j > 0) {
float x2 = randomOffset(0.075f);
float y2 = randomOffset(0.1f);
float z2 = randomOffset(0.075f);
itemTranslator.translate(poseStack, x2, y2, z2);
}
poseStack.scale(itemScale, itemScale, itemScale);
itemRenderer.renderStatic(stack, ItemTransforms.TransformType.FIXED, packedLight, packedOverlay, poseStack, bufferSource, 0);
poseStack.popPose();
}

poseStack.popPose();
}
}


enum ItemTranslator {
X_AXIS((poseStack, x, y, z) -> poseStack.translate(y, x, z)),
Y_AXIS(PoseStack::translate),
Z_AXIS((poseStack, x, y, z) -> poseStack.translate(x, z, y));

private final TranslationFunc translationFunc;

ItemTranslator(TranslationFunc translationFunc) {
this.translationFunc = translationFunc;
}

static ItemTranslator from(Direction facing) {
Direction.Axis axis = facing.getAxis();
if (axis == Direction.Axis.X) return X_AXIS;
else if (axis == Direction.Axis.Y) return Y_AXIS;
return Z_AXIS;
}

void translate(PoseStack poseStack, float x, float y, float z) {
translationFunc.translate(poseStack, x, y, z);
}

interface TranslationFunc {
void translate(PoseStack poseStack, float x, float y, float z);
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ private static void setBlockRenderLayers() {
ItemBlockRenderTypes.setRenderLayer(ModBlocks.DIGESTER.get(), RenderType.cutout());

ItemBlockRenderTypes.setRenderLayer(ModBlocks.VOICE_BOX.get(), RenderType.translucent());
ItemBlockRenderTypes.setRenderLayer(ModBlocks.STORAGE_SAC.get(), RenderType.translucent());
// ItemBlockRenderTypes.setRenderLayer(ModBlocks.STORAGE_SAC.get(), RenderType.translucent());

ItemBlockRenderTypes.setRenderLayer(ModBlocks.FLESH_IRIS_DOOR.get(), RenderType.cutout());
ItemBlockRenderTypes.setRenderLayer(ModBlocks.FLESH_FENCE.get(), RenderType.cutout());
Expand Down

0 comments on commit 0f7afe5

Please sign in to comment.