Items and Blocks registries (WIP)

This commit is contained in:
Aleksey 2021-05-27 18:01:31 +03:00
parent 41df84404b
commit a3e781b401
34 changed files with 313 additions and 1771 deletions

View file

@ -1,132 +1,10 @@
package ru.betterend.blocks.basis;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Random;
import org.jetbrains.annotations.Nullable;
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
import net.minecraft.client.renderer.block.model.BlockModel;
import net.minecraft.client.resources.model.BlockModelRotation;
import net.minecraft.client.resources.model.UnbakedModel;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.stats.Stats;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.monster.piglin.PiglinAi;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.BarrelBlock;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.RenderShape;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.storage.loot.LootContext;
import net.minecraft.world.phys.BlockHitResult;
import ru.betterend.blocks.entities.EBarrelBlockEntity;
import ru.betterend.client.models.BlockModelProvider;
import ru.betterend.client.models.ModelsHelper;
import ru.betterend.client.models.Patterns;
import ru.betterend.registry.EndBlockEntities;
import ru.bclib.blocks.BaseBarrelBlock;
public class EndBarrelBlock extends BarrelBlock implements BlockModelProvider {
public class EndBarrelBlock extends BaseBarrelBlock {
public EndBarrelBlock(Block source) {
super(FabricBlockSettings.copyOf(source).noOcclusion());
}
@Override
public BlockEntity newBlockEntity(BlockGetter world) {
return EndBlockEntities.BARREL.create();
}
@Override
public List<ItemStack> getDrops(BlockState state, LootContext.Builder builder) {
List<ItemStack> drop = super.getDrops(state, builder);
drop.add(new ItemStack(this.asItem()));
return drop;
}
@Override
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand,
BlockHitResult hit) {
if (world.isClientSide) {
return InteractionResult.SUCCESS;
} else {
BlockEntity blockEntity = world.getBlockEntity(pos);
if (blockEntity instanceof EBarrelBlockEntity) {
player.openMenu((EBarrelBlockEntity) blockEntity);
player.awardStat(Stats.OPEN_BARREL);
PiglinAi.angerNearbyPiglins(player, true);
}
return InteractionResult.CONSUME;
}
}
@Override
public void tick(BlockState state, ServerLevel world, BlockPos pos, Random random) {
BlockEntity blockEntity = world.getBlockEntity(pos);
if (blockEntity instanceof EBarrelBlockEntity) {
((EBarrelBlockEntity) blockEntity).tick();
}
}
@Override
public RenderShape getRenderShape(BlockState state) {
return RenderShape.MODEL;
}
@Override
public void setPlacedBy(Level world, BlockPos pos, BlockState state, LivingEntity placer,
ItemStack itemStack) {
if (itemStack.hasCustomHoverName()) {
BlockEntity blockEntity = world.getBlockEntity(pos);
if (blockEntity instanceof EBarrelBlockEntity) {
((EBarrelBlockEntity) blockEntity).setCustomName(itemStack.getHoverName());
}
}
}
@Override
public BlockModel getItemModel(ResourceLocation blockId) {
return getBlockModel(blockId, defaultBlockState());
}
@Override
public @Nullable BlockModel getBlockModel(ResourceLocation blockId, BlockState blockState) {
String texture = blockId.getPath();
Optional<String> pattern;
if (blockState.getValue(OPEN)) {
pattern = Patterns.createJson(Patterns.BLOCK_BARREL_OPEN, texture, texture);
} else {
pattern = Patterns.createJson(Patterns.BLOCK_BOTTOM_TOP, texture, texture);
}
return ModelsHelper.fromPattern(pattern);
}
@Override
public UnbakedModel getModelVariant(ResourceLocation stateId, BlockState blockState, Map<ResourceLocation, UnbakedModel> modelCache) {
String open = blockState.getValue(OPEN) ? "_open" : "";
ResourceLocation modelId = new ResourceLocation(stateId.getNamespace(), "block/" + stateId.getPath() + open);
registerBlockModel(stateId, modelId, blockState, modelCache);
Direction facing = blockState.getValue(FACING);
BlockModelRotation rotation = BlockModelRotation.X0_Y0;
switch (facing) {
case NORTH: rotation = BlockModelRotation.X90_Y0; break;
case EAST: rotation = BlockModelRotation.X90_Y90; break;
case SOUTH: rotation = BlockModelRotation.X90_Y180; break;
case WEST: rotation = BlockModelRotation.X90_Y270; break;
case DOWN: rotation = BlockModelRotation.X180_Y0; break;
default: break;
}
return ModelsHelper.createMultiVariant(modelId, rotation.getRotation(), false);
super(source);
}
}

View file

@ -16,42 +16,14 @@ import net.minecraft.world.level.block.ChestBlock;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.storage.loot.LootContext;
import ru.bclib.blocks.BaseChestBlock;
import ru.betterend.client.models.BlockModelProvider;
import ru.betterend.client.models.ModelsHelper;
import ru.betterend.client.models.Patterns;
import ru.betterend.registry.EndBlockEntities;
public class EndChestBlock extends ChestBlock implements BlockModelProvider {
private final Block parent;
public class EndChestBlock extends BaseChestBlock {
public EndChestBlock(Block source) {
super(FabricBlockSettings.copyOf(source).noOcclusion(), () -> EndBlockEntities.CHEST);
this.parent = source;
}
@Override
public BlockEntity newBlockEntity(BlockGetter world)
{
return EndBlockEntities.CHEST.create();
}
@Override
public List<ItemStack> getDrops(BlockState state, LootContext.Builder builder)
{
List<ItemStack> drop = super.getDrops(state, builder);
drop.add(new ItemStack(this.asItem()));
return drop;
}
@Override
public BlockModel getItemModel(ResourceLocation blockId) {
Optional<String> pattern = Patterns.createJson(Patterns.ITEM_CHEST, blockId.getPath());
return ModelsHelper.fromPattern(pattern);
}
@Override
public @Nullable BlockModel getBlockModel(ResourceLocation resourceLocation, BlockState blockState) {
ResourceLocation parentId = Registry.BLOCK.getKey(parent);
return ModelsHelper.createBlockEmpty(parentId);
super(source);
}
}

View file

@ -1,104 +1,10 @@
package ru.betterend.blocks.basis;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import org.jetbrains.annotations.Nullable;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
import net.minecraft.client.renderer.block.model.BlockModel;
import net.minecraft.client.resources.model.UnbakedModel;
import net.minecraft.core.BlockPos;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.stats.Stats;
import net.minecraft.world.MenuProvider;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.FurnaceBlock;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.storage.loot.LootContext;
import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
import ru.betterend.blocks.entities.EFurnaceBlockEntity;
import ru.betterend.client.models.BlockModelProvider;
import ru.betterend.client.models.ModelsHelper;
import ru.betterend.client.models.Patterns;
import ru.betterend.client.render.ERenderLayer;
import ru.betterend.interfaces.IRenderTypeable;
import ru.bclib.blocks.BaseFurnaceBlock;
public class EndFurnaceBlock extends FurnaceBlock implements BlockModelProvider, IRenderTypeable {
public class EndFurnaceBlock extends BaseFurnaceBlock {
public EndFurnaceBlock(Block source) {
super(FabricBlockSettings.copyOf(source).luminance(state -> state.getValue(LIT) ? 13 : 0));
}
@Override
public BlockEntity newBlockEntity(BlockGetter world) {
return new EFurnaceBlockEntity();
}
@Override
protected void openContainer(Level world, BlockPos pos, Player player) {
BlockEntity blockEntity = world.getBlockEntity(pos);
if (blockEntity instanceof EFurnaceBlockEntity) {
player.openMenu((MenuProvider) blockEntity);
player.awardStat(Stats.INTERACT_WITH_FURNACE);
}
}
@Override
public @Nullable BlockModel getBlockModel(ResourceLocation blockId, BlockState blockState) {
String blockName = blockId.getPath();
Map<String, String> textures = Maps.newHashMap();
textures.put("%top%", blockName + "_top");
textures.put("%side%", blockName + "_side");
Optional<String> pattern;
if (blockState.getValue(LIT)) {
textures.put("%front%", blockName + "_front_on");
textures.put("%glow%", blockName + "_glow");
pattern = Patterns.createJson(Patterns.BLOCK_FURNACE_LIT, textures);
} else {
textures.put("%front%", blockName + "_front");
pattern = Patterns.createJson(Patterns.BLOCK_FURNACE, textures);
}
return ModelsHelper.fromPattern(pattern);
}
@Override
public BlockModel getItemModel(ResourceLocation resourceLocation) {
return getBlockModel(resourceLocation, defaultBlockState());
}
@Override
public UnbakedModel getModelVariant(ResourceLocation stateId, BlockState blockState, Map<ResourceLocation, UnbakedModel> modelCache) {
String lit = blockState.getValue(LIT) ? "_lit" : "";
ResourceLocation modelId = new ResourceLocation(stateId.getNamespace(),
"block/" + stateId.getPath() + lit);
registerBlockModel(stateId, modelId, blockState, modelCache);
return ModelsHelper.createFacingModel(modelId, blockState.getValue(FACING), false, true);
}
@Override
public ERenderLayer getRenderLayer() {
return ERenderLayer.CUTOUT;
}
@Override
public List<ItemStack> getDrops(BlockState state, LootContext.Builder builder) {
List<ItemStack> drop = Lists.newArrayList(new ItemStack(this));
BlockEntity blockEntity = builder.getOptionalParameter(LootContextParams.BLOCK_ENTITY);
if (blockEntity instanceof EFurnaceBlockEntity) {
EFurnaceBlockEntity entity = (EFurnaceBlockEntity) blockEntity;
for (int i = 0; i < entity.getContainerSize(); i++) {
drop.add(entity.getItem(i));
}
}
return drop;
super(source);
}
}

View file

@ -1,82 +0,0 @@
package ru.betterend.blocks.basis;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import org.jetbrains.annotations.Nullable;
import com.google.common.collect.Maps;
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
import net.minecraft.client.renderer.block.model.BlockModel;
import net.minecraft.client.resources.model.UnbakedModel;
import net.minecraft.core.BlockPos;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.enchantment.EnchantmentHelper;
import net.minecraft.world.item.enchantment.Enchantments;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.storage.loot.LootContext;
import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.VoxelShape;
import ru.betterend.client.models.ModelsHelper;
import ru.betterend.client.models.Patterns;
public class EndPathBlock extends BlockBaseNotFull {
private static final VoxelShape SHAPE = Block.box(0, 0, 0, 16, 15, 16);
public EndPathBlock(Block source) {
super(FabricBlockSettings.copyOf(source).isValidSpawn((state, world, pos, type) -> { return false; }));
if (source instanceof EndTerrainBlock) {
EndTerrainBlock terrain = (EndTerrainBlock) source;
terrain.setPathBlock(this);
}
}
@Override
public List<ItemStack> getDrops(BlockState state, LootContext.Builder builder) {
ItemStack tool = builder.getParameter(LootContextParams.TOOL);
if (tool != null && EnchantmentHelper.getItemEnchantmentLevel(Enchantments.SILK_TOUCH, tool) > 0) {
return Collections.singletonList(new ItemStack(this));
}
return Collections.singletonList(new ItemStack(Blocks.END_STONE));
}
@Override
public VoxelShape getShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) {
return SHAPE;
}
@Override
public VoxelShape getCollisionShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) {
return SHAPE;
}
@Override
public BlockModel getItemModel(ResourceLocation blockId) {
return getBlockModel(blockId, defaultBlockState());
}
@Override
public @Nullable BlockModel getBlockModel(ResourceLocation resourceLocation, BlockState blockState) {
String name = resourceLocation.getPath();
Map<String, String> textures = Maps.newHashMap();
textures.put("%top%", name + "_top");
textures.put("%side%", name.replace("_path", "") + "_side");
Optional<String> pattern = Patterns.createJson(Patterns.BLOCK_PATH, textures);
return ModelsHelper.fromPattern(pattern);
}
@Override
public UnbakedModel getModelVariant(ResourceLocation stateId, BlockState blockState, Map<ResourceLocation, UnbakedModel> modelCache) {
ResourceLocation modelId = new ResourceLocation(stateId.getNamespace(), "block/" + stateId.getPath());
registerBlockModel(stateId, modelId, blockState, modelCache);
return ModelsHelper.createRandomTopModel(modelId);
}
}

View file

@ -1,197 +1,10 @@
package ru.betterend.blocks.basis;
import java.util.Collections;
import java.util.List;
import org.jetbrains.annotations.Nullable;
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
import net.minecraft.client.renderer.block.model.BlockModel;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.Registry;
import net.minecraft.network.protocol.game.ClientboundOpenSignEditorPacket;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.context.BlockPlaceContext;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.Mirror;
import net.minecraft.world.level.block.Rotation;
import net.minecraft.world.level.block.SignBlock;
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.IntegerProperty;
import net.minecraft.world.level.block.state.properties.WoodType;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.level.material.FluidState;
import net.minecraft.world.level.material.Fluids;
import net.minecraft.world.level.storage.loot.LootContext;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.VoxelShape;
import ru.betterend.blocks.entities.ESignBlockEntity;
import ru.betterend.client.models.BlockModelProvider;
import ru.betterend.client.models.ModelsHelper;
import ru.betterend.interfaces.ISpetialItem;
import ru.betterend.util.BlocksHelper;
import ru.bclib.blocks.BaseSignBlock;
public class EndSignBlock extends SignBlock implements BlockModelProvider, ISpetialItem {
public static final IntegerProperty ROTATION = BlockStateProperties.ROTATION_16;
public static final BooleanProperty FLOOR = BooleanProperty.create("floor");
private static final VoxelShape[] WALL_SHAPES = new VoxelShape[] {
Block.box(0.0D, 4.5D, 14.0D, 16.0D, 12.5D, 16.0D),
Block.box(0.0D, 4.5D, 0.0D, 2.0D, 12.5D, 16.0D),
Block.box(0.0D, 4.5D, 0.0D, 16.0D, 12.5D, 2.0D),
Block.box(14.0D, 4.5D, 0.0D, 16.0D, 12.5D, 16.0D)
};
private final Block parent;
public class EndSignBlock extends BaseSignBlock {
public EndSignBlock(Block source) {
super(FabricBlockSettings.copyOf(source).strength(1.0F, 1.0F).noCollission().noOcclusion(), WoodType.OAK);
this.registerDefaultState(this.stateDefinition.any().setValue(ROTATION, 0).setValue(FLOOR, false).setValue(WATERLOGGED, false));
this.parent = source;
}
@Override
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
builder.add(ROTATION, FLOOR, WATERLOGGED);
}
@Override
public VoxelShape getShape(BlockState state, BlockGetter view, BlockPos pos, CollisionContext ePos) {
return state.getValue(FLOOR) ? SHAPE : WALL_SHAPES[state.getValue(ROTATION) >> 2];
}
@Override
public BlockEntity newBlockEntity(BlockGetter world) {
return new ESignBlockEntity();
}
@Override
public void setPlacedBy(Level world, BlockPos pos, BlockState state, LivingEntity placer, ItemStack itemStack) {
if (placer instanceof Player) {
ESignBlockEntity sign = (ESignBlockEntity) world.getBlockEntity(pos);
if (sign != null) {
if (!world.isClientSide) {
sign.setAllowedPlayerEditor((Player) placer);
((ServerPlayer) placer).connection.send(new ClientboundOpenSignEditorPacket(pos));
} else {
sign.setEditable(true);
}
}
}
}
@Override
public BlockState updateShape(BlockState state, Direction facing, BlockState neighborState, LevelAccessor world, BlockPos pos, BlockPos neighborPos) {
if ((Boolean) state.getValue(WATERLOGGED)) {
world.getLiquidTicks().scheduleTick(pos, Fluids.WATER, Fluids.WATER.getTickDelay(world));
}
if (!canSurvive(state, world, pos)) {
return state.getValue(WATERLOGGED) ? state.getFluidState().createLegacyBlock() : Blocks.AIR.defaultBlockState();
}
return super.updateShape(state, facing, neighborState, world, pos, neighborPos);
}
@Override
public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) {
if (!state.getValue(FLOOR)) {
int index = (((state.getValue(ROTATION) >> 2) + 2)) & 3;
return world.getBlockState(pos.relative(BlocksHelper.HORIZONTAL[index])).getMaterial().isSolid();
}
else {
return world.getBlockState(pos.below()).getMaterial().isSolid();
}
}
@Override
public BlockState getStateForPlacement(BlockPlaceContext ctx) {
if (ctx.getClickedFace() == Direction.UP) {
FluidState fluidState = ctx.getLevel().getFluidState(ctx.getClickedPos());
return this.defaultBlockState().setValue(FLOOR, true)
.setValue(ROTATION, Mth.floor((180.0 + ctx.getRotation() * 16.0 / 360.0) + 0.5 - 12) & 15)
.setValue(WATERLOGGED, fluidState.getType() == Fluids.WATER);
}
else if (ctx.getClickedFace() != Direction.DOWN) {
BlockState blockState = this.defaultBlockState();
FluidState fluidState = ctx.getLevel().getFluidState(ctx.getClickedPos());
LevelReader worldView = ctx.getLevel();
BlockPos blockPos = ctx.getClickedPos();
Direction[] directions = ctx.getNearestLookingDirections();
for (Direction direction : directions) {
if (direction.getAxis().isHorizontal()) {
Direction dir = direction.getOpposite();
int rot = Mth.floor((180.0 + dir.toYRot() * 16.0 / 360.0) + 0.5 + 4) & 15;
blockState = blockState.setValue(ROTATION, rot);
if (blockState.canSurvive(worldView, blockPos)) {
return blockState.setValue(FLOOR, false).setValue(WATERLOGGED, fluidState.getType() == Fluids.WATER);
}
}
}
}
return null;
}
@Override
public @Nullable BlockModel getBlockModel(ResourceLocation resourceLocation, BlockState blockState) {
ResourceLocation parentId = Registry.BLOCK.getKey(parent);
return ModelsHelper.createBlockEmpty(parentId);
}
@Override
public BlockState rotate(BlockState state, Rotation rotation) {
return (BlockState) state.setValue(ROTATION, rotation.rotate((Integer) state.getValue(ROTATION), 16));
}
@Override
public BlockState mirror(BlockState state, Mirror mirror) {
return (BlockState) state.setValue(ROTATION, mirror.mirror((Integer) state.getValue(ROTATION), 16));
}
@Override
public List<ItemStack> getDrops(BlockState state, LootContext.Builder builder) {
return Collections.singletonList(new ItemStack(this));
}
@Override
public Fluid takeLiquid(LevelAccessor world, BlockPos pos, BlockState state) {
// TODO Auto-generated method stub
return null;
}
@Override
public boolean canPlaceLiquid(BlockGetter world, BlockPos pos, BlockState state, Fluid fluid) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean placeLiquid(LevelAccessor world, BlockPos pos, BlockState state, FluidState fluidState) {
// TODO Auto-generated method stub
return false;
}
@Override
public int getStackSize() {
return 16;
}
@Override
public boolean canPlaceOnWater() {
return false;
super(source);
}
}

View file

@ -38,87 +38,13 @@ import net.minecraft.world.level.material.MaterialColor;
import net.minecraft.world.level.storage.loot.LootContext;
import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
import net.minecraft.world.phys.BlockHitResult;
import ru.bclib.blocks.BaseTerrainBlock;
import ru.betterend.blocks.BlockSounds;
import ru.betterend.client.models.ModelsHelper;
import ru.betterend.client.models.Patterns;
public class EndTerrainBlock extends BlockBase {
private Block pathBlock;
public class EndTerrainBlock extends BaseTerrainBlock {
public EndTerrainBlock(MaterialColor color) {
super(FabricBlockSettings.copyOf(Blocks.END_STONE).materialColor(color).sound(BlockSounds.TERRAIN_SOUND).randomTicks());
}
public void setPathBlock(Block roadBlock) {
this.pathBlock = roadBlock;
}
@Override
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) {
if (pathBlock != null && player.getMainHandItem().getItem().is(FabricToolTags.SHOVELS)) {
world.playSound(player, pos, SoundEvents.SHOVEL_FLATTEN, SoundSource.BLOCKS, 1.0F, 1.0F);
if (!world.isClientSide) {
world.setBlockAndUpdate(pos, pathBlock.defaultBlockState());
if (!player.isCreative()) {
player.getMainHandItem().hurt(1, world.random, (ServerPlayer) player);
}
}
return InteractionResult.SUCCESS;
}
return InteractionResult.FAIL;
}
@Override
public List<ItemStack> getDrops(BlockState state, LootContext.Builder builder) {
ItemStack tool = builder.getParameter(LootContextParams.TOOL);
if (tool != null && EnchantmentHelper.getItemEnchantmentLevel(Enchantments.SILK_TOUCH, tool) > 0) {
return Collections.singletonList(new ItemStack(this));
}
return Collections.singletonList(new ItemStack(Blocks.END_STONE));
}
@Override
public void randomTick(BlockState state, ServerLevel world, BlockPos pos, Random random) {
if (random.nextInt(16) == 0 && !canStay(state, world, pos)) {
world.setBlockAndUpdate(pos, Blocks.END_STONE.defaultBlockState());
}
}
public boolean canStay(BlockState state, LevelReader worldView, BlockPos pos) {
BlockPos blockPos = pos.above();
BlockState blockState = worldView.getBlockState(blockPos);
if (blockState.is(Blocks.SNOW) && (Integer) blockState.getValue(SnowLayerBlock.LAYERS) == 1) {
return true;
}
else if (blockState.getFluidState().getAmount() == 8) {
return false;
}
else {
int i = LayerLightEngine.getLightBlockInto(worldView, state, pos, blockState, blockPos, Direction.UP, blockState.getLightBlock(worldView, blockPos));
return i < 5;
}
}
@Override
public BlockModel getItemModel(ResourceLocation blockId) {
return getBlockModel(blockId, defaultBlockState());
}
@Override
public @Nullable BlockModel getBlockModel(ResourceLocation resourceLocation, BlockState blockState) {
String name = resourceLocation.getPath();
Map<String, String> textures = Maps.newHashMap();
textures.put("%top%", "betterend:block/" + name + "_top");
textures.put("%side%", "betterend:block/" + name + "_side");
textures.put("%bottom%", "minecraft:block/end_stone");
Optional<String> pattern = Patterns.createJson(Patterns.BLOCK_TOP_SIDE_BOTTOM, textures);
return ModelsHelper.fromPattern(pattern);
}
@Override
public UnbakedModel getModelVariant(ResourceLocation stateId, BlockState blockState, Map<ResourceLocation, UnbakedModel> modelCache) {
ResourceLocation modelId = new ResourceLocation(stateId.getNamespace(), "block/" + stateId.getPath());
registerBlockModel(stateId, modelId, blockState, modelCache);
return ModelsHelper.createRandomTopModel(modelId);
super(Blocks.END_STONE, color);
}
}