Registries, Base blocks with entities
This commit is contained in:
parent
5aeee09cfc
commit
8ab247f861
45 changed files with 1684 additions and 40 deletions
143
src/main/java/ru/bclib/blockentities/BaseBarrelBlockEntity.java
Normal file
143
src/main/java/ru/bclib/blockentities/BaseBarrelBlockEntity.java
Normal file
|
@ -0,0 +1,143 @@
|
||||||
|
package ru.bclib.blockentities;
|
||||||
|
|
||||||
|
import net.minecraft.core.NonNullList;
|
||||||
|
import net.minecraft.core.Vec3i;
|
||||||
|
import net.minecraft.nbt.CompoundTag;
|
||||||
|
import net.minecraft.network.chat.Component;
|
||||||
|
import net.minecraft.network.chat.TranslatableComponent;
|
||||||
|
import net.minecraft.sounds.SoundEvent;
|
||||||
|
import net.minecraft.sounds.SoundEvents;
|
||||||
|
import net.minecraft.sounds.SoundSource;
|
||||||
|
import net.minecraft.world.ContainerHelper;
|
||||||
|
import net.minecraft.world.entity.player.Inventory;
|
||||||
|
import net.minecraft.world.entity.player.Player;
|
||||||
|
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||||
|
import net.minecraft.world.inventory.ChestMenu;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.level.block.BarrelBlock;
|
||||||
|
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||||
|
import net.minecraft.world.level.block.entity.ChestBlockEntity;
|
||||||
|
import net.minecraft.world.level.block.entity.RandomizableContainerBlockEntity;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
import ru.bclib.blocks.BaseBarrelBlock;
|
||||||
|
import ru.bclib.registry.BaseBlockEntities;
|
||||||
|
|
||||||
|
public class BaseBarrelBlockEntity extends RandomizableContainerBlockEntity {
|
||||||
|
private NonNullList<ItemStack> inventory;
|
||||||
|
private int viewerCount;
|
||||||
|
|
||||||
|
private BaseBarrelBlockEntity(BlockEntityType<?> type) {
|
||||||
|
super(type);
|
||||||
|
this.inventory = NonNullList.withSize(27, ItemStack.EMPTY);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BaseBarrelBlockEntity() {
|
||||||
|
this(BaseBlockEntities.BARREL);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CompoundTag save(CompoundTag tag) {
|
||||||
|
super.save(tag);
|
||||||
|
if (!this.trySaveLootTable(tag)) {
|
||||||
|
ContainerHelper.saveAllItems(tag, this.inventory);
|
||||||
|
}
|
||||||
|
|
||||||
|
return tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void load(BlockState state, CompoundTag tag) {
|
||||||
|
super.load(state, tag);
|
||||||
|
this.inventory = NonNullList.withSize(this.getContainerSize(), ItemStack.EMPTY);
|
||||||
|
if (!this.tryLoadLootTable(tag)) {
|
||||||
|
ContainerHelper.loadAllItems(tag, this.inventory);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getContainerSize() {
|
||||||
|
return 27;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected NonNullList<ItemStack> getItems() {
|
||||||
|
return this.inventory;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setItems(NonNullList<ItemStack> list) {
|
||||||
|
this.inventory = list;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Component getDefaultName() {
|
||||||
|
return new TranslatableComponent("container.barrel");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected AbstractContainerMenu createMenu(int syncId, Inventory playerInventory) {
|
||||||
|
return ChestMenu.threeRows(syncId, playerInventory, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void startOpen(Player player) {
|
||||||
|
if (!player.isSpectator()) {
|
||||||
|
if (viewerCount < 0) {
|
||||||
|
viewerCount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
++viewerCount;
|
||||||
|
BlockState blockState = this.getBlockState();
|
||||||
|
if (!blockState.getValue(BarrelBlock.OPEN)) {
|
||||||
|
playSound(blockState, SoundEvents.BARREL_OPEN);
|
||||||
|
setOpen(blockState, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (level != null) {
|
||||||
|
scheduleUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("ConstantConditions")
|
||||||
|
private void scheduleUpdate() {
|
||||||
|
level.getBlockTicks().scheduleTick(getBlockPos(), getBlockState().getBlock(), 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void tick() {
|
||||||
|
if (level != null) {
|
||||||
|
int x = worldPosition.getX();
|
||||||
|
int y = worldPosition.getY();
|
||||||
|
int z = worldPosition.getZ();
|
||||||
|
viewerCount = ChestBlockEntity.getOpenCount(level, this, x, y, z);
|
||||||
|
if (viewerCount > 0) {
|
||||||
|
scheduleUpdate();
|
||||||
|
} else {
|
||||||
|
BlockState blockState = getBlockState();
|
||||||
|
if (!(blockState.getBlock() instanceof BaseBarrelBlock)) {
|
||||||
|
setRemoved();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (blockState.getValue(BarrelBlock.OPEN)) {
|
||||||
|
playSound(blockState, SoundEvents.BARREL_CLOSE);
|
||||||
|
setOpen(blockState, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stopOpen(Player player) {
|
||||||
|
if (!player.isSpectator()) {
|
||||||
|
--this.viewerCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setOpen(BlockState state, boolean open) {
|
||||||
|
if (level != null) {
|
||||||
|
level.setBlock(this.getBlockPos(), state.setValue(BarrelBlock.OPEN, open), 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void playSound(BlockState blockState, SoundEvent soundEvent) {
|
||||||
|
if (level != null) {
|
||||||
|
Vec3i vec3i = blockState.getValue(BarrelBlock.FACING).getNormal();
|
||||||
|
double d = (double) this.worldPosition.getX() + 0.5D + (double) vec3i.getX() / 2.0D;
|
||||||
|
double e = (double) this.worldPosition.getY() + 0.5D + (double) vec3i.getY() / 2.0D;
|
||||||
|
double f = (double) this.worldPosition.getZ() + 0.5D + (double) vec3i.getZ() / 2.0D;
|
||||||
|
level.playSound(null, d, e, f, soundEvent, SoundSource.BLOCKS, 0.5F,
|
||||||
|
this.level.random.nextFloat() * 0.1F + 0.9F);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
package ru.bclib.blockentities;
|
||||||
|
|
||||||
|
import net.minecraft.world.level.block.entity.ChestBlockEntity;
|
||||||
|
import ru.bclib.registry.BaseBlockEntities;
|
||||||
|
|
||||||
|
public class BaseChestBlockEntity extends ChestBlockEntity {
|
||||||
|
public BaseChestBlockEntity() {
|
||||||
|
super(BaseBlockEntities.CHEST);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
package ru.bclib.blockentities;
|
||||||
|
|
||||||
|
import net.minecraft.network.chat.Component;
|
||||||
|
import net.minecraft.network.chat.TranslatableComponent;
|
||||||
|
import net.minecraft.world.entity.player.Inventory;
|
||||||
|
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||||
|
import net.minecraft.world.inventory.FurnaceMenu;
|
||||||
|
import net.minecraft.world.item.crafting.RecipeType;
|
||||||
|
import net.minecraft.world.level.block.entity.AbstractFurnaceBlockEntity;
|
||||||
|
import ru.bclib.registry.BaseBlockEntities;
|
||||||
|
|
||||||
|
public class BaseFurnaceBlockEntity extends AbstractFurnaceBlockEntity {
|
||||||
|
public BaseFurnaceBlockEntity() {
|
||||||
|
super(BaseBlockEntities.FURNACE, RecipeType.SMELTING);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Component getDefaultName() {
|
||||||
|
return new TranslatableComponent("container.furnace");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected AbstractContainerMenu createMenu(int syncId, Inventory playerInventory) {
|
||||||
|
return new FurnaceMenu(syncId, playerInventory, this, this.dataAccess);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
package ru.bclib.blockentities;
|
||||||
|
|
||||||
|
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||||
|
import net.minecraft.world.level.block.entity.SignBlockEntity;
|
||||||
|
import ru.bclib.registry.BaseBlockEntities;
|
||||||
|
|
||||||
|
public class BaseSignBlockEntity extends SignBlockEntity {
|
||||||
|
public BaseSignBlockEntity() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockEntityType<?> getType() {
|
||||||
|
return BaseBlockEntities.SIGN;
|
||||||
|
}
|
||||||
|
}
|
|
@ -29,11 +29,9 @@ import ru.bclib.client.models.PatternsHelper;
|
||||||
|
|
||||||
public class BaseAnvilBlock extends AnvilBlock implements BlockModelProvider {
|
public class BaseAnvilBlock extends AnvilBlock implements BlockModelProvider {
|
||||||
private static final IntegerProperty DESTRUCTION = BlockProperties.DESTRUCTION;
|
private static final IntegerProperty DESTRUCTION = BlockProperties.DESTRUCTION;
|
||||||
protected final int level;
|
|
||||||
|
|
||||||
public BaseAnvilBlock(MaterialColor color, int level) {
|
public BaseAnvilBlock(MaterialColor color) {
|
||||||
super(FabricBlockSettings.copyOf(Blocks.ANVIL).materialColor(color));
|
super(FabricBlockSettings.copyOf(Blocks.ANVIL).materialColor(color));
|
||||||
this.level = level;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -46,10 +44,6 @@ public class BaseAnvilBlock extends AnvilBlock implements BlockModelProvider {
|
||||||
return DESTRUCTION;
|
return DESTRUCTION;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getCraftingLevel() {
|
|
||||||
return level;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<ItemStack> getDrops(BlockState state, LootContext.Builder builder) {
|
public List<ItemStack> getDrops(BlockState state, LootContext.Builder builder) {
|
||||||
ItemStack stack = new ItemStack(this);
|
ItemStack stack = new ItemStack(this);
|
||||||
|
|
133
src/main/java/ru/bclib/blocks/BaseBarrelBlock.java
Normal file
133
src/main/java/ru/bclib/blocks/BaseBarrelBlock.java
Normal file
|
@ -0,0 +1,133 @@
|
||||||
|
package ru.bclib.blocks;
|
||||||
|
|
||||||
|
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.bclib.blockentities.BaseBarrelBlockEntity;
|
||||||
|
import ru.bclib.client.models.BasePatterns;
|
||||||
|
import ru.bclib.client.models.BlockModelProvider;
|
||||||
|
import ru.bclib.client.models.ModelsHelper;
|
||||||
|
import ru.bclib.client.models.PatternsHelper;
|
||||||
|
import ru.bclib.registry.BaseBlockEntities;
|
||||||
|
|
||||||
|
public class BaseBarrelBlock extends BarrelBlock implements BlockModelProvider {
|
||||||
|
public BaseBarrelBlock(Block source) {
|
||||||
|
super(FabricBlockSettings.copyOf(source).noOcclusion());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockEntity newBlockEntity(BlockGetter world) {
|
||||||
|
return BaseBlockEntities.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 BaseBarrelBlockEntity) {
|
||||||
|
player.openMenu((BaseBarrelBlockEntity) 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 BaseBarrelBlockEntity) {
|
||||||
|
((BaseBarrelBlockEntity) 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 BaseBarrelBlockEntity) {
|
||||||
|
((BaseBarrelBlockEntity) blockEntity).setCustomName(itemStack.getHoverName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockModel getItemModel(ResourceLocation blockId) {
|
||||||
|
return getBlockModel(blockId, defaultBlockState());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable BlockModel getBlockModel(ResourceLocation blockId, BlockState blockState) {
|
||||||
|
Optional<String> pattern;
|
||||||
|
if (blockState.getValue(OPEN)) {
|
||||||
|
pattern = PatternsHelper.createJson(BasePatterns.BLOCK_BARREL_OPEN, blockId);
|
||||||
|
} else {
|
||||||
|
pattern = PatternsHelper.createJson(BasePatterns.BLOCK_BOTTOM_TOP, blockId);
|
||||||
|
}
|
||||||
|
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:
|
||||||
|
default: rotation = BlockModelRotation.X180_Y0; break;
|
||||||
|
}
|
||||||
|
return ModelsHelper.createMultiVariant(modelId, rotation.getRotation(), false);
|
||||||
|
}
|
||||||
|
}
|
|
@ -23,9 +23,9 @@ import ru.bclib.client.models.BlockModelProvider;
|
||||||
import ru.bclib.client.models.ModelsHelper;
|
import ru.bclib.client.models.ModelsHelper;
|
||||||
import ru.bclib.client.models.PatternsHelper;
|
import ru.bclib.client.models.PatternsHelper;
|
||||||
import ru.bclib.client.render.ERenderLayer;
|
import ru.bclib.client.render.ERenderLayer;
|
||||||
import ru.bclib.interfaces.IRenderTypeable;
|
import ru.bclib.interfaces.IRenderTyped;
|
||||||
|
|
||||||
public class BaseChainBlock extends ChainBlock implements BlockModelProvider, IRenderTypeable {
|
public class BaseChainBlock extends ChainBlock implements BlockModelProvider, IRenderTyped {
|
||||||
public BaseChainBlock(MaterialColor color) {
|
public BaseChainBlock(MaterialColor color) {
|
||||||
super(FabricBlockSettings.copyOf(Blocks.CHAIN).materialColor(color));
|
super(FabricBlockSettings.copyOf(Blocks.CHAIN).materialColor(color));
|
||||||
}
|
}
|
||||||
|
|
58
src/main/java/ru/bclib/blocks/BaseChestBlock.java
Normal file
58
src/main/java/ru/bclib/blocks/BaseChestBlock.java
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
package ru.bclib.blocks;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
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.Registry;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.level.BlockGetter;
|
||||||
|
import net.minecraft.world.level.block.Block;
|
||||||
|
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.client.models.BasePatterns;
|
||||||
|
import ru.bclib.client.models.BlockModelProvider;
|
||||||
|
import ru.bclib.client.models.ModelsHelper;
|
||||||
|
import ru.bclib.client.models.PatternsHelper;
|
||||||
|
import ru.bclib.registry.BaseBlockEntities;
|
||||||
|
|
||||||
|
public class BaseChestBlock extends ChestBlock implements BlockModelProvider {
|
||||||
|
private final Block parent;
|
||||||
|
|
||||||
|
public BaseChestBlock(Block source) {
|
||||||
|
super(FabricBlockSettings.copyOf(source).noOcclusion(), () -> BaseBlockEntities.CHEST);
|
||||||
|
this.parent = source;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockEntity newBlockEntity(BlockGetter world)
|
||||||
|
{
|
||||||
|
return BaseBlockEntities.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 = PatternsHelper.createJson(BasePatterns.ITEM_CHEST, blockId);
|
||||||
|
return ModelsHelper.fromPattern(pattern);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable BlockModel getBlockModel(ResourceLocation resourceLocation, BlockState blockState) {
|
||||||
|
ResourceLocation parentId = Registry.BLOCK.getKey(parent);
|
||||||
|
return ModelsHelper.createBlockEmpty(parentId);
|
||||||
|
}
|
||||||
|
}
|
|
@ -26,9 +26,9 @@ import ru.bclib.client.models.BlockModelProvider;
|
||||||
import ru.bclib.client.models.ModelsHelper;
|
import ru.bclib.client.models.ModelsHelper;
|
||||||
import ru.bclib.client.models.PatternsHelper;
|
import ru.bclib.client.models.PatternsHelper;
|
||||||
import ru.bclib.client.render.ERenderLayer;
|
import ru.bclib.client.render.ERenderLayer;
|
||||||
import ru.bclib.interfaces.IRenderTypeable;
|
import ru.bclib.interfaces.IRenderTyped;
|
||||||
|
|
||||||
public class BaseDoorBlock extends DoorBlock implements IRenderTypeable, BlockModelProvider {
|
public class BaseDoorBlock extends DoorBlock implements IRenderTyped, BlockModelProvider {
|
||||||
public BaseDoorBlock(Block source) {
|
public BaseDoorBlock(Block source) {
|
||||||
super(FabricBlockSettings.copyOf(source).strength(3F, 3F).noOcclusion());
|
super(FabricBlockSettings.copyOf(source).strength(3F, 3F).noOcclusion());
|
||||||
}
|
}
|
||||||
|
|
105
src/main/java/ru/bclib/blocks/BaseFurnaceBlock.java
Normal file
105
src/main/java/ru/bclib/blocks/BaseFurnaceBlock.java
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
package ru.bclib.blocks;
|
||||||
|
|
||||||
|
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.bclib.blockentities.BaseFurnaceBlockEntity;
|
||||||
|
import ru.bclib.client.models.BasePatterns;
|
||||||
|
import ru.bclib.client.models.BlockModelProvider;
|
||||||
|
import ru.bclib.client.models.ModelsHelper;
|
||||||
|
import ru.bclib.client.models.PatternsHelper;
|
||||||
|
import ru.bclib.client.render.ERenderLayer;
|
||||||
|
import ru.bclib.interfaces.IRenderTyped;
|
||||||
|
|
||||||
|
public class BaseFurnaceBlock extends FurnaceBlock implements BlockModelProvider, IRenderTyped {
|
||||||
|
public BaseFurnaceBlock(Block source) {
|
||||||
|
super(FabricBlockSettings.copyOf(source).luminance(state -> state.getValue(LIT) ? 13 : 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockEntity newBlockEntity(BlockGetter world) {
|
||||||
|
return new BaseFurnaceBlockEntity();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void openContainer(Level world, BlockPos pos, Player player) {
|
||||||
|
BlockEntity blockEntity = world.getBlockEntity(pos);
|
||||||
|
if (blockEntity instanceof BaseFurnaceBlockEntity) {
|
||||||
|
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 = PatternsHelper.createJson(BasePatterns.BLOCK_FURNACE_LIT, textures);
|
||||||
|
} else {
|
||||||
|
textures.put("%front%", blockName + "_front");
|
||||||
|
pattern = PatternsHelper.createJson(BasePatterns.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 BaseFurnaceBlockEntity) {
|
||||||
|
BaseFurnaceBlockEntity entity = (BaseFurnaceBlockEntity) blockEntity;
|
||||||
|
for (int i = 0; i < entity.getContainerSize(); i++) {
|
||||||
|
drop.add(entity.getItem(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return drop;
|
||||||
|
}
|
||||||
|
}
|
|
@ -34,10 +34,10 @@ import ru.bclib.client.models.BasePatterns;
|
||||||
import ru.bclib.client.models.BlockModelProvider;
|
import ru.bclib.client.models.BlockModelProvider;
|
||||||
import ru.bclib.client.models.ModelsHelper;
|
import ru.bclib.client.models.ModelsHelper;
|
||||||
import ru.bclib.client.models.PatternsHelper;
|
import ru.bclib.client.models.PatternsHelper;
|
||||||
import ru.bclib.interfaces.IRenderTypeable;
|
import ru.bclib.interfaces.IRenderTyped;
|
||||||
import ru.bclib.util.BlocksHelper;
|
import ru.bclib.util.BlocksHelper;
|
||||||
|
|
||||||
public class BaseLadderBlock extends BaseBlockNotFull implements IRenderTypeable, BlockModelProvider {
|
public class BaseLadderBlock extends BaseBlockNotFull implements IRenderTyped, BlockModelProvider {
|
||||||
public static final DirectionProperty FACING = HorizontalDirectionalBlock.FACING;
|
public static final DirectionProperty FACING = HorizontalDirectionalBlock.FACING;
|
||||||
public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED;
|
public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED;
|
||||||
protected static final VoxelShape EAST_SHAPE = Block.box(0.0D, 0.0D, 0.0D, 3.0D, 16.0D, 16.0D);
|
protected static final VoxelShape EAST_SHAPE = Block.box(0.0D, 0.0D, 0.0D, 3.0D, 16.0D, 16.0D);
|
||||||
|
|
|
@ -21,10 +21,10 @@ import net.minecraft.world.level.storage.loot.LootContext;
|
||||||
import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
|
import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
|
||||||
import ru.bclib.client.models.BlockModelProvider;
|
import ru.bclib.client.models.BlockModelProvider;
|
||||||
import ru.bclib.client.render.ERenderLayer;
|
import ru.bclib.client.render.ERenderLayer;
|
||||||
import ru.bclib.interfaces.IRenderTypeable;
|
import ru.bclib.interfaces.IRenderTyped;
|
||||||
import ru.bclib.util.MHelper;
|
import ru.bclib.util.MHelper;
|
||||||
|
|
||||||
public class BaseLeavesBlock extends LeavesBlock implements BlockModelProvider, IRenderTypeable {
|
public class BaseLeavesBlock extends LeavesBlock implements BlockModelProvider, IRenderTyped {
|
||||||
private final Block sapling;
|
private final Block sapling;
|
||||||
|
|
||||||
public BaseLeavesBlock(Block sapling, MaterialColor color) {
|
public BaseLeavesBlock(Block sapling, MaterialColor color) {
|
||||||
|
|
|
@ -26,9 +26,9 @@ import ru.bclib.client.models.BlockModelProvider;
|
||||||
import ru.bclib.client.models.ModelsHelper;
|
import ru.bclib.client.models.ModelsHelper;
|
||||||
import ru.bclib.client.models.PatternsHelper;
|
import ru.bclib.client.models.PatternsHelper;
|
||||||
import ru.bclib.client.render.ERenderLayer;
|
import ru.bclib.client.render.ERenderLayer;
|
||||||
import ru.bclib.interfaces.IRenderTypeable;
|
import ru.bclib.interfaces.IRenderTyped;
|
||||||
|
|
||||||
public class BaseMetalBarsBlock extends IronBarsBlock implements BlockModelProvider, IRenderTypeable {
|
public class BaseMetalBarsBlock extends IronBarsBlock implements BlockModelProvider, IRenderTyped {
|
||||||
public BaseMetalBarsBlock(Block source) {
|
public BaseMetalBarsBlock(Block source) {
|
||||||
super(FabricBlockSettings.copyOf(source).strength(5.0F, 6.0F).noOcclusion());
|
super(FabricBlockSettings.copyOf(source).strength(5.0F, 6.0F).noOcclusion());
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,11 +30,10 @@ import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
|
||||||
import net.minecraft.world.phys.Vec3;
|
import net.minecraft.world.phys.Vec3;
|
||||||
import net.minecraft.world.phys.shapes.CollisionContext;
|
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||||
import ru.bclib.api.TagAPI;
|
|
||||||
import ru.bclib.client.render.ERenderLayer;
|
import ru.bclib.client.render.ERenderLayer;
|
||||||
import ru.bclib.interfaces.IRenderTypeable;
|
import ru.bclib.interfaces.IRenderTyped;
|
||||||
|
|
||||||
public abstract class BasePlantBlock extends BaseBlockNotFull implements IRenderTypeable, BonemealableBlock {
|
public abstract class BasePlantBlock extends BaseBlockNotFull implements IRenderTyped, BonemealableBlock {
|
||||||
private static final VoxelShape SHAPE = Block.box(4, 0, 4, 12, 14, 12);
|
private static final VoxelShape SHAPE = Block.box(4, 0, 4, 12, 14, 12);
|
||||||
|
|
||||||
public BasePlantBlock() {
|
public BasePlantBlock() {
|
||||||
|
|
196
src/main/java/ru/bclib/blocks/BaseSignBlock.java
Normal file
196
src/main/java/ru/bclib/blocks/BaseSignBlock.java
Normal file
|
@ -0,0 +1,196 @@
|
||||||
|
package ru.bclib.blocks;
|
||||||
|
|
||||||
|
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.bclib.blockentities.BaseSignBlockEntity;
|
||||||
|
import ru.bclib.client.models.BlockModelProvider;
|
||||||
|
import ru.bclib.client.models.ModelsHelper;
|
||||||
|
import ru.bclib.interfaces.ISpetialItem;
|
||||||
|
import ru.bclib.util.BlocksHelper;
|
||||||
|
|
||||||
|
public class BaseSignBlock 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 BaseSignBlock(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 BaseSignBlockEntity();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setPlacedBy(Level world, BlockPos pos, BlockState state, LivingEntity placer, ItemStack itemStack) {
|
||||||
|
if (placer instanceof Player) {
|
||||||
|
BaseSignBlockEntity sign = (BaseSignBlockEntity) 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 (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 state.setValue(ROTATION, rotation.rotate((Integer) state.getValue(ROTATION), 16));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockState mirror(BlockState state, Mirror mirror) {
|
||||||
|
return 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 super.takeLiquid(world, pos, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canPlaceLiquid(BlockGetter world, BlockPos pos, BlockState state, Fluid fluid) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return super.canPlaceLiquid(world, pos, state, fluid);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean placeLiquid(LevelAccessor world, BlockPos pos, BlockState state, FluidState fluidState) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return super.placeLiquid(world, pos, state, fluidState);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getStackSize() {
|
||||||
|
return 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canPlaceOnWater() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -24,9 +24,9 @@ import ru.bclib.client.models.BlockModelProvider;
|
||||||
import ru.bclib.client.models.ModelsHelper;
|
import ru.bclib.client.models.ModelsHelper;
|
||||||
import ru.bclib.client.models.PatternsHelper;
|
import ru.bclib.client.models.PatternsHelper;
|
||||||
import ru.bclib.client.render.ERenderLayer;
|
import ru.bclib.client.render.ERenderLayer;
|
||||||
import ru.bclib.interfaces.IRenderTypeable;
|
import ru.bclib.interfaces.IRenderTyped;
|
||||||
|
|
||||||
public class BaseTrapdoorBlock extends TrapDoorBlock implements IRenderTypeable, BlockModelProvider {
|
public class BaseTrapdoorBlock extends TrapDoorBlock implements IRenderTyped, BlockModelProvider {
|
||||||
public BaseTrapdoorBlock(Block source) {
|
public BaseTrapdoorBlock(Block source) {
|
||||||
super(FabricBlockSettings.copyOf(source).strength(3.0F, 3.0F).noOcclusion());
|
super(FabricBlockSettings.copyOf(source).strength(3.0F, 3.0F).noOcclusion());
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,10 +35,10 @@ import net.minecraft.world.phys.Vec3;
|
||||||
import net.minecraft.world.phys.shapes.CollisionContext;
|
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||||
import ru.bclib.client.render.ERenderLayer;
|
import ru.bclib.client.render.ERenderLayer;
|
||||||
import ru.bclib.interfaces.IRenderTypeable;
|
import ru.bclib.interfaces.IRenderTyped;
|
||||||
import ru.bclib.util.BlocksHelper;
|
import ru.bclib.util.BlocksHelper;
|
||||||
|
|
||||||
public abstract class DoublePlantBlock extends BaseBlockNotFull implements IRenderTypeable, BonemealableBlock {
|
public abstract class DoublePlantBlock extends BaseBlockNotFull implements IRenderTyped, BonemealableBlock {
|
||||||
private static final VoxelShape SHAPE = Block.box(4, 2, 4, 12, 16, 12);
|
private static final VoxelShape SHAPE = Block.box(4, 2, 4, 12, 16, 12);
|
||||||
public static final IntegerProperty ROTATION = BlockProperties.ROTATION;
|
public static final IntegerProperty ROTATION = BlockProperties.ROTATION;
|
||||||
public static final BooleanProperty TOP = BooleanProperty.create("top");
|
public static final BooleanProperty TOP = BooleanProperty.create("top");
|
||||||
|
|
|
@ -17,7 +17,6 @@ import net.minecraft.world.item.ItemStack;
|
||||||
import net.minecraft.world.level.BlockGetter;
|
import net.minecraft.world.level.BlockGetter;
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
import net.minecraft.world.level.LevelAccessor;
|
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.Block;
|
||||||
import net.minecraft.world.level.block.Blocks;
|
import net.minecraft.world.level.block.Blocks;
|
||||||
import net.minecraft.world.level.block.SaplingBlock;
|
import net.minecraft.world.level.block.SaplingBlock;
|
||||||
|
@ -33,9 +32,9 @@ import ru.bclib.client.models.BlockModelProvider;
|
||||||
import ru.bclib.client.models.ModelsHelper;
|
import ru.bclib.client.models.ModelsHelper;
|
||||||
import ru.bclib.client.models.PatternsHelper;
|
import ru.bclib.client.models.PatternsHelper;
|
||||||
import ru.bclib.client.render.ERenderLayer;
|
import ru.bclib.client.render.ERenderLayer;
|
||||||
import ru.bclib.interfaces.IRenderTypeable;
|
import ru.bclib.interfaces.IRenderTyped;
|
||||||
|
|
||||||
public abstract class FeatureSaplingBlock extends SaplingBlock implements IRenderTypeable, BlockModelProvider {
|
public abstract class FeatureSaplingBlock extends SaplingBlock implements IRenderTyped, BlockModelProvider {
|
||||||
private static final VoxelShape SHAPE = Block.box(4, 0, 4, 12, 14, 12);
|
private static final VoxelShape SHAPE = Block.box(4, 0, 4, 12, 14, 12);
|
||||||
|
|
||||||
public FeatureSaplingBlock() {
|
public FeatureSaplingBlock() {
|
||||||
|
|
|
@ -5,9 +5,9 @@ import net.minecraft.world.level.block.SoundType;
|
||||||
import net.minecraft.world.level.material.Material;
|
import net.minecraft.world.level.material.Material;
|
||||||
import net.minecraft.world.level.material.MaterialColor;
|
import net.minecraft.world.level.material.MaterialColor;
|
||||||
import ru.bclib.client.render.ERenderLayer;
|
import ru.bclib.client.render.ERenderLayer;
|
||||||
import ru.bclib.interfaces.IRenderTypeable;
|
import ru.bclib.interfaces.IRenderTyped;
|
||||||
|
|
||||||
public class SimpleLeavesBlock extends BaseBlockNotFull implements IRenderTypeable {
|
public class SimpleLeavesBlock extends BaseBlockNotFull implements IRenderTyped {
|
||||||
public SimpleLeavesBlock(MaterialColor color) {
|
public SimpleLeavesBlock(MaterialColor color) {
|
||||||
super(FabricBlockSettings.of(Material.LEAVES)
|
super(FabricBlockSettings.of(Material.LEAVES)
|
||||||
.strength(0.2F)
|
.strength(0.2F)
|
||||||
|
|
|
@ -39,9 +39,9 @@ import ru.bclib.client.models.BasePatterns;
|
||||||
import ru.bclib.client.models.ModelsHelper;
|
import ru.bclib.client.models.ModelsHelper;
|
||||||
import ru.bclib.client.models.PatternsHelper;
|
import ru.bclib.client.models.PatternsHelper;
|
||||||
import ru.bclib.client.render.ERenderLayer;
|
import ru.bclib.client.render.ERenderLayer;
|
||||||
import ru.bclib.interfaces.IRenderTypeable;
|
import ru.bclib.interfaces.IRenderTyped;
|
||||||
|
|
||||||
public class StalactiteBlock extends BaseBlockNotFull implements SimpleWaterloggedBlock, LiquidBlockContainer, IRenderTypeable {
|
public class StalactiteBlock extends BaseBlockNotFull implements SimpleWaterloggedBlock, LiquidBlockContainer, IRenderTyped {
|
||||||
public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED;
|
public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED;
|
||||||
public static final BooleanProperty IS_FLOOR = BlockProperties.IS_FLOOR;
|
public static final BooleanProperty IS_FLOOR = BlockProperties.IS_FLOOR;
|
||||||
public static final IntegerProperty SIZE = BlockProperties.SIZE;
|
public static final IntegerProperty SIZE = BlockProperties.SIZE;
|
||||||
|
|
|
@ -35,9 +35,9 @@ import net.minecraft.world.phys.Vec3;
|
||||||
import net.minecraft.world.phys.shapes.CollisionContext;
|
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||||
import ru.bclib.client.render.ERenderLayer;
|
import ru.bclib.client.render.ERenderLayer;
|
||||||
import ru.bclib.interfaces.IRenderTypeable;
|
import ru.bclib.interfaces.IRenderTyped;
|
||||||
|
|
||||||
public abstract class UnderwaterPlantBlock extends BaseBlockNotFull implements IRenderTypeable, BonemealableBlock, LiquidBlockContainer {
|
public abstract class UnderwaterPlantBlock extends BaseBlockNotFull implements IRenderTyped, BonemealableBlock, LiquidBlockContainer {
|
||||||
private static final VoxelShape SHAPE = Block.box(4, 0, 4, 12, 14, 12);
|
private static final VoxelShape SHAPE = Block.box(4, 0, 4, 12, 14, 12);
|
||||||
|
|
||||||
public UnderwaterPlantBlock() {
|
public UnderwaterPlantBlock() {
|
||||||
|
|
|
@ -27,9 +27,9 @@ import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
|
||||||
import net.minecraft.world.phys.shapes.CollisionContext;
|
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||||
import ru.bclib.client.render.ERenderLayer;
|
import ru.bclib.client.render.ERenderLayer;
|
||||||
import ru.bclib.interfaces.IRenderTypeable;
|
import ru.bclib.interfaces.IRenderTyped;
|
||||||
|
|
||||||
public abstract class UpDownPlantBlock extends BaseBlockNotFull implements IRenderTypeable {
|
public abstract class UpDownPlantBlock extends BaseBlockNotFull implements IRenderTyped {
|
||||||
private static final VoxelShape SHAPE = Block.box(4, 0, 4, 12, 16, 12);
|
private static final VoxelShape SHAPE = Block.box(4, 0, 4, 12, 16, 12);
|
||||||
|
|
||||||
public UpDownPlantBlock() {
|
public UpDownPlantBlock() {
|
||||||
|
|
|
@ -34,10 +34,10 @@ import net.minecraft.world.phys.shapes.CollisionContext;
|
||||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||||
import ru.bclib.blocks.BlockProperties.TripleShape;
|
import ru.bclib.blocks.BlockProperties.TripleShape;
|
||||||
import ru.bclib.client.render.ERenderLayer;
|
import ru.bclib.client.render.ERenderLayer;
|
||||||
import ru.bclib.interfaces.IRenderTypeable;
|
import ru.bclib.interfaces.IRenderTyped;
|
||||||
import ru.bclib.util.BlocksHelper;
|
import ru.bclib.util.BlocksHelper;
|
||||||
|
|
||||||
public class VineBlock extends BaseBlockNotFull implements IRenderTypeable, BonemealableBlock {
|
public class VineBlock extends BaseBlockNotFull implements IRenderTyped, BonemealableBlock {
|
||||||
public static final EnumProperty<TripleShape> SHAPE = BlockProperties.TRIPLE_SHAPE;
|
public static final EnumProperty<TripleShape> SHAPE = BlockProperties.TRIPLE_SHAPE;
|
||||||
private static final VoxelShape VOXEL_SHAPE = Block.box(2, 0, 2, 14, 16, 14);
|
private static final VoxelShape VOXEL_SHAPE = Block.box(2, 0, 2, 14, 16, 14);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,180 @@
|
||||||
|
package ru.bclib.client.render;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
|
import com.mojang.blaze3d.vertex.VertexConsumer;
|
||||||
|
import com.mojang.math.Vector3f;
|
||||||
|
|
||||||
|
import it.unimi.dsi.fastutil.floats.Float2FloatFunction;
|
||||||
|
import it.unimi.dsi.fastutil.ints.Int2IntFunction;
|
||||||
|
import net.minecraft.client.model.geom.ModelPart;
|
||||||
|
import net.minecraft.client.renderer.MultiBufferSource;
|
||||||
|
import net.minecraft.client.renderer.RenderType;
|
||||||
|
import net.minecraft.client.renderer.blockentity.BlockEntityRenderDispatcher;
|
||||||
|
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer;
|
||||||
|
import net.minecraft.client.renderer.blockentity.BrightnessCombiner;
|
||||||
|
import net.minecraft.core.Direction;
|
||||||
|
import net.minecraft.core.Registry;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.world.item.BlockItem;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
|
import net.minecraft.world.level.block.AbstractChestBlock;
|
||||||
|
import net.minecraft.world.level.block.Block;
|
||||||
|
import net.minecraft.world.level.block.Blocks;
|
||||||
|
import net.minecraft.world.level.block.ChestBlock;
|
||||||
|
import net.minecraft.world.level.block.DoubleBlockCombiner;
|
||||||
|
import net.minecraft.world.level.block.DoubleBlockCombiner.NeighborCombineResult;
|
||||||
|
import net.minecraft.world.level.block.entity.ChestBlockEntity;
|
||||||
|
import net.minecraft.world.level.block.entity.LidBlockEntity;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
import net.minecraft.world.level.block.state.properties.ChestType;
|
||||||
|
import ru.bclib.blockentities.BaseChestBlockEntity;
|
||||||
|
import ru.bclib.blocks.BaseChestBlock;
|
||||||
|
import ru.bclib.registry.BaseRegistry;
|
||||||
|
|
||||||
|
public class BaseChestBlockEntityRenderer extends BlockEntityRenderer<BaseChestBlockEntity> {
|
||||||
|
private static final HashMap<Block, RenderType[]> LAYERS = Maps.newHashMap();
|
||||||
|
private static final RenderType[] defaultLayer;
|
||||||
|
|
||||||
|
private static final int ID_NORMAL = 0;
|
||||||
|
private static final int ID_LEFT = 1;
|
||||||
|
private static final int ID_RIGHT = 2;
|
||||||
|
|
||||||
|
private final ModelPart partA;
|
||||||
|
private final ModelPart partC;
|
||||||
|
private final ModelPart partB;
|
||||||
|
private final ModelPart partRightA;
|
||||||
|
private final ModelPart partRightC;
|
||||||
|
private final ModelPart partRightB;
|
||||||
|
private final ModelPart partLeftA;
|
||||||
|
private final ModelPart partLeftC;
|
||||||
|
private final ModelPart partLeftB;
|
||||||
|
|
||||||
|
public BaseChestBlockEntityRenderer(BlockEntityRenderDispatcher blockEntityRenderDispatcher) {
|
||||||
|
super(blockEntityRenderDispatcher);
|
||||||
|
|
||||||
|
this.partC = new ModelPart(64, 64, 0, 19);
|
||||||
|
this.partC.addBox(1.0F, 0.0F, 1.0F, 14.0F, 9.0F, 14.0F, 0.0F);
|
||||||
|
this.partA = new ModelPart(64, 64, 0, 0);
|
||||||
|
this.partA.addBox(1.0F, 0.0F, 0.0F, 14.0F, 5.0F, 14.0F, 0.0F);
|
||||||
|
this.partA.y = 9.0F;
|
||||||
|
this.partA.z = 1.0F;
|
||||||
|
this.partB = new ModelPart(64, 64, 0, 0);
|
||||||
|
this.partB.addBox(7.0F, -1.0F, 15.0F, 2.0F, 4.0F, 1.0F, 0.0F);
|
||||||
|
this.partB.y = 8.0F;
|
||||||
|
this.partRightC = new ModelPart(64, 64, 0, 19);
|
||||||
|
this.partRightC.addBox(1.0F, 0.0F, 1.0F, 15.0F, 9.0F, 14.0F, 0.0F);
|
||||||
|
this.partRightA = new ModelPart(64, 64, 0, 0);
|
||||||
|
this.partRightA.addBox(1.0F, 0.0F, 0.0F, 15.0F, 5.0F, 14.0F, 0.0F);
|
||||||
|
this.partRightA.y = 9.0F;
|
||||||
|
this.partRightA.z = 1.0F;
|
||||||
|
this.partRightB = new ModelPart(64, 64, 0, 0);
|
||||||
|
this.partRightB.addBox(15.0F, -1.0F, 15.0F, 1.0F, 4.0F, 1.0F, 0.0F);
|
||||||
|
this.partRightB.y = 8.0F;
|
||||||
|
this.partLeftC = new ModelPart(64, 64, 0, 19);
|
||||||
|
this.partLeftC.addBox(0.0F, 0.0F, 1.0F, 15.0F, 9.0F, 14.0F, 0.0F);
|
||||||
|
this.partLeftA = new ModelPart(64, 64, 0, 0);
|
||||||
|
this.partLeftA.addBox(0.0F, 0.0F, 0.0F, 15.0F, 5.0F, 14.0F, 0.0F);
|
||||||
|
this.partLeftA.y = 9.0F;
|
||||||
|
this.partLeftA.z = 1.0F;
|
||||||
|
this.partLeftB = new ModelPart(64, 64, 0, 0);
|
||||||
|
this.partLeftB.addBox(0.0F, -1.0F, 15.0F, 1.0F, 4.0F, 1.0F, 0.0F);
|
||||||
|
this.partLeftB.y = 8.0F;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void render(BaseChestBlockEntity entity, float tickDelta, PoseStack matrices, MultiBufferSource vertexConsumers, int light, int overlay) {
|
||||||
|
Level world = entity.getLevel();
|
||||||
|
boolean worldExists = world != null;
|
||||||
|
BlockState blockState = worldExists ? entity.getBlockState() : (BlockState) Blocks.CHEST.defaultBlockState().setValue(ChestBlock.FACING, Direction.SOUTH);
|
||||||
|
ChestType chestType = blockState.hasProperty(ChestBlock.TYPE) ? (ChestType) blockState.getValue(ChestBlock.TYPE) : ChestType.SINGLE;
|
||||||
|
Block block = blockState.getBlock();
|
||||||
|
if (block instanceof AbstractChestBlock) {
|
||||||
|
AbstractChestBlock<?> abstractChestBlock = (AbstractChestBlock<?>) block;
|
||||||
|
boolean isDouble = chestType != ChestType.SINGLE;
|
||||||
|
float f = ((Direction) blockState.getValue(ChestBlock.FACING)).toYRot();
|
||||||
|
NeighborCombineResult<? extends ChestBlockEntity> propertySource;
|
||||||
|
|
||||||
|
matrices.pushPose();
|
||||||
|
matrices.translate(0.5D, 0.5D, 0.5D);
|
||||||
|
matrices.mulPose(Vector3f.YP.rotationDegrees(-f));
|
||||||
|
matrices.translate(-0.5D, -0.5D, -0.5D);
|
||||||
|
|
||||||
|
if (worldExists) {
|
||||||
|
propertySource = abstractChestBlock.combine(blockState, world, entity.getBlockPos(), true);
|
||||||
|
} else {
|
||||||
|
propertySource = DoubleBlockCombiner.Combiner::acceptNone;
|
||||||
|
}
|
||||||
|
|
||||||
|
float pitch = ((Float2FloatFunction) propertySource.apply(ChestBlock.opennessCombiner((LidBlockEntity) entity))).get(tickDelta);
|
||||||
|
pitch = 1.0F - pitch;
|
||||||
|
pitch = 1.0F - pitch * pitch * pitch;
|
||||||
|
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||||
|
int blockLight = ((Int2IntFunction) propertySource.apply(new BrightnessCombiner())).applyAsInt(light);
|
||||||
|
|
||||||
|
VertexConsumer vertexConsumer = getConsumer(vertexConsumers, block, chestType);
|
||||||
|
|
||||||
|
if (isDouble) {
|
||||||
|
if (chestType == ChestType.LEFT) {
|
||||||
|
renderParts(matrices, vertexConsumer, this.partLeftA, this.partLeftB, this.partLeftC, pitch, blockLight, overlay);
|
||||||
|
} else {
|
||||||
|
renderParts(matrices, vertexConsumer, this.partRightA, this.partRightB, this.partRightC, pitch, blockLight, overlay);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
renderParts(matrices, vertexConsumer, this.partA, this.partB, this.partC, pitch, blockLight, overlay);
|
||||||
|
}
|
||||||
|
|
||||||
|
matrices.popPose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void renderParts(PoseStack matrices, VertexConsumer vertices, ModelPart modelPart, ModelPart modelPart2, ModelPart modelPart3, float pitch, int light, int overlay) {
|
||||||
|
modelPart.xRot = -(pitch * 1.5707964F);
|
||||||
|
modelPart2.xRot = modelPart.xRot;
|
||||||
|
modelPart.render(matrices, vertices, light, overlay);
|
||||||
|
modelPart2.render(matrices, vertices, light, overlay);
|
||||||
|
modelPart3.render(matrices, vertices, light, overlay);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static RenderType getChestTexture(ChestType type, RenderType[] layers) {
|
||||||
|
switch (type) {
|
||||||
|
case LEFT:
|
||||||
|
return layers[ID_LEFT];
|
||||||
|
case RIGHT:
|
||||||
|
return layers[ID_RIGHT];
|
||||||
|
case SINGLE:
|
||||||
|
default:
|
||||||
|
return layers[ID_NORMAL];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static VertexConsumer getConsumer(MultiBufferSource provider, Block block, ChestType chestType) {
|
||||||
|
RenderType[] layers = LAYERS.getOrDefault(block, defaultLayer);
|
||||||
|
return provider.getBuffer(getChestTexture(chestType, layers));
|
||||||
|
}
|
||||||
|
|
||||||
|
static {
|
||||||
|
defaultLayer = new RenderType[] {
|
||||||
|
RenderType.entityCutout(new ResourceLocation("textures/entity/chest/normal.png")),
|
||||||
|
RenderType.entityCutout(new ResourceLocation("textures/entity/chest/normal_left.png")),
|
||||||
|
RenderType.entityCutout(new ResourceLocation("textures/entity/chest/normal_right.png"))
|
||||||
|
};
|
||||||
|
|
||||||
|
BaseRegistry.getModBlocks().forEach((item) -> {
|
||||||
|
if (item instanceof BlockItem) {
|
||||||
|
Block block = ((BlockItem) item).getBlock();
|
||||||
|
if (block instanceof BaseChestBlock) {
|
||||||
|
ResourceLocation blockId = Registry.BLOCK.getKey(block);
|
||||||
|
String modId = blockId.getNamespace();
|
||||||
|
String path = blockId.getPath();
|
||||||
|
LAYERS.put(block, new RenderType[] {
|
||||||
|
RenderType.entityCutout(new ResourceLocation(modId, "textures/entity/chest/" + path + ".png")),
|
||||||
|
RenderType.entityCutout(new ResourceLocation(modId, "textures/entity/chest/" + path + "_left.png")),
|
||||||
|
RenderType.entityCutout(new ResourceLocation(modId, "textures/entity/chest/" + path + "_right.png"))
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,122 @@
|
||||||
|
package ru.bclib.client.render;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
import com.mojang.blaze3d.platform.NativeImage;
|
||||||
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
|
import com.mojang.blaze3d.vertex.VertexConsumer;
|
||||||
|
import com.mojang.math.Vector3f;
|
||||||
|
|
||||||
|
import net.minecraft.client.gui.Font;
|
||||||
|
import net.minecraft.client.renderer.MultiBufferSource;
|
||||||
|
import net.minecraft.client.renderer.RenderType;
|
||||||
|
import net.minecraft.client.renderer.Sheets;
|
||||||
|
import net.minecraft.client.renderer.blockentity.BlockEntityRenderDispatcher;
|
||||||
|
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer;
|
||||||
|
import net.minecraft.client.renderer.blockentity.SignRenderer;
|
||||||
|
import net.minecraft.client.renderer.blockentity.SignRenderer.SignModel;
|
||||||
|
import net.minecraft.client.resources.model.Material;
|
||||||
|
import net.minecraft.core.Registry;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.util.FormattedCharSequence;
|
||||||
|
import net.minecraft.world.item.BlockItem;
|
||||||
|
import net.minecraft.world.level.block.Block;
|
||||||
|
import net.minecraft.world.level.block.SignBlock;
|
||||||
|
import net.minecraft.world.level.block.StandingSignBlock;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
import net.minecraft.world.level.block.state.properties.WoodType;
|
||||||
|
import ru.bclib.blockentities.BaseSignBlockEntity;
|
||||||
|
import ru.bclib.blocks.BaseSignBlock;
|
||||||
|
import ru.bclib.registry.BaseRegistry;
|
||||||
|
|
||||||
|
public class BaseSignBlockEntityRenderer extends BlockEntityRenderer<BaseSignBlockEntity> {
|
||||||
|
private static final HashMap<Block, RenderType> LAYERS = Maps.newHashMap();
|
||||||
|
private static final RenderType defaultLayer;
|
||||||
|
private final SignModel model = new SignRenderer.SignModel();
|
||||||
|
|
||||||
|
public BaseSignBlockEntityRenderer(BlockEntityRenderDispatcher dispatcher) {
|
||||||
|
super(dispatcher);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void render(BaseSignBlockEntity signBlockEntity, float tickDelta, PoseStack matrixStack,
|
||||||
|
MultiBufferSource provider, int light, int overlay) {
|
||||||
|
BlockState state = signBlockEntity.getBlockState();
|
||||||
|
matrixStack.pushPose();
|
||||||
|
|
||||||
|
matrixStack.translate(0.5D, 0.5D, 0.5D);
|
||||||
|
float angle = -((float) ((Integer) state.getValue(StandingSignBlock.ROTATION) * 360) / 16.0F);
|
||||||
|
|
||||||
|
BlockState blockState = signBlockEntity.getBlockState();
|
||||||
|
if (blockState.getValue(BaseSignBlock.FLOOR)) {
|
||||||
|
matrixStack.mulPose(Vector3f.YP.rotationDegrees(angle));
|
||||||
|
this.model.stick.visible = true;
|
||||||
|
} else {
|
||||||
|
matrixStack.mulPose(Vector3f.YP.rotationDegrees(angle + 180));
|
||||||
|
matrixStack.translate(0.0D, -0.3125D, -0.4375D);
|
||||||
|
this.model.stick.visible = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
matrixStack.pushPose();
|
||||||
|
matrixStack.scale(0.6666667F, -0.6666667F, -0.6666667F);
|
||||||
|
VertexConsumer vertexConsumer = getConsumer(provider, state.getBlock());
|
||||||
|
model.sign.render(matrixStack, vertexConsumer, light, overlay);
|
||||||
|
model.stick.render(matrixStack, vertexConsumer, light, overlay);
|
||||||
|
matrixStack.popPose();
|
||||||
|
Font textRenderer = renderer.getFont();
|
||||||
|
matrixStack.translate(0.0D, 0.3333333432674408D, 0.046666666865348816D);
|
||||||
|
matrixStack.scale(0.010416667F, -0.010416667F, 0.010416667F);
|
||||||
|
int m = signBlockEntity.getColor().getTextColor();
|
||||||
|
int n = (int) (NativeImage.getR(m) * 0.4D);
|
||||||
|
int o = (int) (NativeImage.getG(m) * 0.4D);
|
||||||
|
int p = (int) (NativeImage.getB(m) * 0.4D);
|
||||||
|
int q = NativeImage.combine(0, p, o, n);
|
||||||
|
|
||||||
|
for (int s = 0; s < 4; ++s) {
|
||||||
|
FormattedCharSequence orderedText = signBlockEntity.getRenderMessage(s, (text) -> {
|
||||||
|
List<FormattedCharSequence> list = textRenderer.split(text, 90);
|
||||||
|
return list.isEmpty() ? FormattedCharSequence.EMPTY : (FormattedCharSequence) list.get(0);
|
||||||
|
});
|
||||||
|
if (orderedText != null) {
|
||||||
|
float t = (float) (-textRenderer.width(orderedText) / 2);
|
||||||
|
textRenderer.drawInBatch((FormattedCharSequence) orderedText, t, (float) (s * 10 - 20), q, false, matrixStack.last().pose(), provider, false, 0, light);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
matrixStack.popPose();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Material getModelTexture(Block block) {
|
||||||
|
WoodType signType2;
|
||||||
|
if (block instanceof SignBlock) {
|
||||||
|
signType2 = ((SignBlock) block).type();
|
||||||
|
} else {
|
||||||
|
signType2 = WoodType.OAK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Sheets.signTexture(signType2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static VertexConsumer getConsumer(MultiBufferSource provider, Block block) {
|
||||||
|
return provider.getBuffer(LAYERS.getOrDefault(block, defaultLayer));
|
||||||
|
}
|
||||||
|
|
||||||
|
static {
|
||||||
|
defaultLayer = RenderType.entitySolid(new ResourceLocation("textures/entity/sign/oak.png"));
|
||||||
|
|
||||||
|
BaseRegistry.getModBlocks().forEach((item) -> {
|
||||||
|
if (item instanceof BlockItem) {
|
||||||
|
Block block = ((BlockItem) item).getBlock();
|
||||||
|
if (block instanceof BaseSignBlock) {
|
||||||
|
ResourceLocation blockId = Registry.BLOCK.getKey(block);
|
||||||
|
RenderType layer = RenderType.entitySolid(new ResourceLocation(blockId.getNamespace(),
|
||||||
|
"textures/entity/sign/" + blockId.getPath() + ".png"));
|
||||||
|
LAYERS.put(block, layer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
10
src/main/java/ru/bclib/interfaces/IColorProvider.java
Normal file
10
src/main/java/ru/bclib/interfaces/IColorProvider.java
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
package ru.bclib.interfaces;
|
||||||
|
|
||||||
|
import net.minecraft.client.color.block.BlockColor;
|
||||||
|
import net.minecraft.client.color.item.ItemColor;
|
||||||
|
|
||||||
|
public interface IColorProvider {
|
||||||
|
BlockColor getProvider();
|
||||||
|
|
||||||
|
ItemColor getItemProvider();
|
||||||
|
}
|
|
@ -2,7 +2,6 @@ package ru.bclib.interfaces;
|
||||||
|
|
||||||
import ru.bclib.client.render.ERenderLayer;
|
import ru.bclib.client.render.ERenderLayer;
|
||||||
|
|
||||||
public interface IRenderTypeable
|
public interface IRenderTyped {
|
||||||
{
|
ERenderLayer getRenderLayer();
|
||||||
public ERenderLayer getRenderLayer();
|
|
||||||
}
|
}
|
6
src/main/java/ru/bclib/interfaces/ISpetialItem.java
Normal file
6
src/main/java/ru/bclib/interfaces/ISpetialItem.java
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
package ru.bclib.interfaces;
|
||||||
|
|
||||||
|
public interface ISpetialItem {
|
||||||
|
boolean canPlaceOnWater();
|
||||||
|
int getStackSize();
|
||||||
|
}
|
49
src/main/java/ru/bclib/items/BaseArmorItem.java
Normal file
49
src/main/java/ru/bclib/items/BaseArmorItem.java
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
package ru.bclib.items;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import com.google.common.collect.HashMultimap;
|
||||||
|
import com.google.common.collect.Multimap;
|
||||||
|
|
||||||
|
import net.minecraft.world.entity.EquipmentSlot;
|
||||||
|
import net.minecraft.world.entity.ai.attributes.Attribute;
|
||||||
|
import net.minecraft.world.entity.ai.attributes.AttributeModifier;
|
||||||
|
import net.minecraft.world.entity.ai.attributes.Attributes;
|
||||||
|
import net.minecraft.world.item.ArmorItem;
|
||||||
|
import net.minecraft.world.item.ArmorMaterial;
|
||||||
|
import ru.bclib.client.models.ItemModelProvider;
|
||||||
|
|
||||||
|
public class BaseArmorItem extends ArmorItem implements ItemModelProvider {
|
||||||
|
|
||||||
|
protected static final UUID[] ARMOR_MODIFIER_UUID_PER_SLOT = new UUID[] {
|
||||||
|
UUID.fromString("845DB27C-C624-495F-8C9F-6020A9A58B6B"),
|
||||||
|
UUID.fromString("D8499B04-0E66-4726-AB29-64469D734E0D"),
|
||||||
|
UUID.fromString("9F3D476D-C118-4544-8365-64846904B48E"),
|
||||||
|
UUID.fromString("2AD3F246-FEE1-4E67-B886-69FD380BB150")
|
||||||
|
};
|
||||||
|
|
||||||
|
protected final Multimap<Attribute, AttributeModifier> defaultModifiers;
|
||||||
|
|
||||||
|
public BaseArmorItem(ArmorMaterial material, EquipmentSlot equipmentSlot, Properties settings) {
|
||||||
|
super(material, equipmentSlot, settings);
|
||||||
|
this.defaultModifiers = HashMultimap.create();
|
||||||
|
UUID uuid = ARMOR_MODIFIER_UUID_PER_SLOT[equipmentSlot.getIndex()];
|
||||||
|
addAttributeModifier(Attributes.ARMOR, new AttributeModifier(uuid, "Armor modifier", getDefense(), AttributeModifier.Operation.ADDITION));
|
||||||
|
addAttributeModifier(Attributes.ARMOR_TOUGHNESS, new AttributeModifier(uuid, "Armor toughness", getToughness(), AttributeModifier.Operation.ADDITION));
|
||||||
|
if (knockbackResistance > 0.0F) {
|
||||||
|
addAttributeModifier(Attributes.KNOCKBACK_RESISTANCE, new AttributeModifier(uuid, "Armor knockback resistance", knockbackResistance, AttributeModifier.Operation.ADDITION));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Multimap<Attribute, AttributeModifier> getDefaultAttributeModifiers(EquipmentSlot equipmentSlot) {
|
||||||
|
return equipmentSlot == slot ? defaultModifiers : super.getDefaultAttributeModifiers(equipmentSlot);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void addAttributeModifier(Attribute attribute, AttributeModifier modifier) {
|
||||||
|
if (defaultModifiers.containsKey(attribute)) {
|
||||||
|
defaultModifiers.removeAll(attribute);
|
||||||
|
}
|
||||||
|
defaultModifiers.put(attribute, modifier);
|
||||||
|
}
|
||||||
|
}
|
9
src/main/java/ru/bclib/items/BaseAttribute.java
Normal file
9
src/main/java/ru/bclib/items/BaseAttribute.java
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
package ru.bclib.items;
|
||||||
|
|
||||||
|
import net.minecraft.world.entity.ai.attributes.Attribute;
|
||||||
|
|
||||||
|
public class BaseAttribute extends Attribute {
|
||||||
|
public BaseAttribute(String description, double value) {
|
||||||
|
super(description, value);
|
||||||
|
}
|
||||||
|
}
|
13
src/main/java/ru/bclib/items/BaseBucketItem.java
Normal file
13
src/main/java/ru/bclib/items/BaseBucketItem.java
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
package ru.bclib.items;
|
||||||
|
|
||||||
|
import net.fabricmc.fabric.api.item.v1.FabricItemSettings;
|
||||||
|
import net.minecraft.world.entity.EntityType;
|
||||||
|
import net.minecraft.world.item.FishBucketItem;
|
||||||
|
import net.minecraft.world.level.material.Fluids;
|
||||||
|
import ru.bclib.client.models.ItemModelProvider;
|
||||||
|
|
||||||
|
public class BaseBucketItem extends FishBucketItem implements ItemModelProvider {
|
||||||
|
public BaseBucketItem(EntityType<?> type, FabricItemSettings settings) {
|
||||||
|
super(type, Fluids.WATER, settings.stacksTo(1));
|
||||||
|
}
|
||||||
|
}
|
54
src/main/java/ru/bclib/items/BaseDrinkItem.java
Normal file
54
src/main/java/ru/bclib/items/BaseDrinkItem.java
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
package ru.bclib.items;
|
||||||
|
|
||||||
|
import net.minecraft.advancements.CriteriaTriggers;
|
||||||
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
|
import net.minecraft.stats.Stats;
|
||||||
|
import net.minecraft.world.InteractionHand;
|
||||||
|
import net.minecraft.world.InteractionResultHolder;
|
||||||
|
import net.minecraft.world.entity.LivingEntity;
|
||||||
|
import net.minecraft.world.entity.player.Player;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.item.ItemUtils;
|
||||||
|
import net.minecraft.world.item.Items;
|
||||||
|
import net.minecraft.world.item.UseAnim;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
|
|
||||||
|
public class BaseDrinkItem extends ModelProviderItem {
|
||||||
|
public BaseDrinkItem(Properties settings) {
|
||||||
|
super(settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getUseDuration(ItemStack stack) {
|
||||||
|
return 32;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UseAnim getUseAnimation(ItemStack stack) {
|
||||||
|
return UseAnim.DRINK;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InteractionResultHolder<ItemStack> use(Level world, Player user, InteractionHand hand) {
|
||||||
|
return ItemUtils.useDrink(world, user, hand);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack finishUsingItem(ItemStack stack, Level world, LivingEntity user) {
|
||||||
|
if (user instanceof ServerPlayer) {
|
||||||
|
ServerPlayer serverPlayerEntity = (ServerPlayer) user;
|
||||||
|
CriteriaTriggers.CONSUME_ITEM.trigger(serverPlayerEntity, stack);
|
||||||
|
serverPlayerEntity.awardStat(Stats.ITEM_USED.get(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (user instanceof Player && !((Player) user).abilities.instabuild) {
|
||||||
|
stack.shrink(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!world.isClientSide) {
|
||||||
|
user.removeAllEffects();
|
||||||
|
}
|
||||||
|
|
||||||
|
return stack.isEmpty() ? new ItemStack(Items.GLASS_BOTTLE) : stack;
|
||||||
|
}
|
||||||
|
}
|
24
src/main/java/ru/bclib/items/BaseSpawnEggItem.java
Normal file
24
src/main/java/ru/bclib/items/BaseSpawnEggItem.java
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
package ru.bclib.items;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import net.minecraft.client.renderer.block.model.BlockModel;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.world.entity.EntityType;
|
||||||
|
import net.minecraft.world.item.SpawnEggItem;
|
||||||
|
import ru.bclib.client.models.BasePatterns;
|
||||||
|
import ru.bclib.client.models.ItemModelProvider;
|
||||||
|
import ru.bclib.client.models.ModelsHelper;
|
||||||
|
import ru.bclib.client.models.PatternsHelper;
|
||||||
|
|
||||||
|
public class BaseSpawnEggItem extends SpawnEggItem implements ItemModelProvider {
|
||||||
|
public BaseSpawnEggItem(EntityType<?> type, int primaryColor, int secondaryColor, Properties settings) {
|
||||||
|
super(type, primaryColor, secondaryColor, settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockModel getItemModel(ResourceLocation resourceLocation) {
|
||||||
|
Optional<String> pattern = PatternsHelper.createJson(BasePatterns.ITEM_SPAWN_EGG, resourceLocation);
|
||||||
|
return ModelsHelper.fromPattern(pattern);
|
||||||
|
}
|
||||||
|
}
|
11
src/main/java/ru/bclib/items/EndDiscItem.java
Normal file
11
src/main/java/ru/bclib/items/EndDiscItem.java
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
package ru.bclib.items;
|
||||||
|
|
||||||
|
import net.minecraft.sounds.SoundEvent;
|
||||||
|
import net.minecraft.world.item.RecordItem;
|
||||||
|
import ru.bclib.client.models.ItemModelProvider;
|
||||||
|
|
||||||
|
public class EndDiscItem extends RecordItem implements ItemModelProvider {
|
||||||
|
public EndDiscItem(int comparatorOutput, SoundEvent sound, Properties settings) {
|
||||||
|
super(comparatorOutput, sound, settings);
|
||||||
|
}
|
||||||
|
}
|
18
src/main/java/ru/bclib/items/ModelProviderItem.java
Normal file
18
src/main/java/ru/bclib/items/ModelProviderItem.java
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
package ru.bclib.items;
|
||||||
|
|
||||||
|
import net.minecraft.client.renderer.block.model.BlockModel;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.world.item.Item;
|
||||||
|
import ru.bclib.client.models.ItemModelProvider;
|
||||||
|
import ru.bclib.client.models.ModelsHelper;
|
||||||
|
|
||||||
|
public class ModelProviderItem extends Item implements ItemModelProvider {
|
||||||
|
public ModelProviderItem(Properties settings) {
|
||||||
|
super(settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockModel getItemModel(ResourceLocation resourceLocation) {
|
||||||
|
return ModelsHelper.createItemModel(resourceLocation);
|
||||||
|
}
|
||||||
|
}
|
34
src/main/java/ru/bclib/items/tool/BaseAxeItem.java
Normal file
34
src/main/java/ru/bclib/items/tool/BaseAxeItem.java
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
package ru.bclib.items.tool;
|
||||||
|
|
||||||
|
import net.fabricmc.fabric.api.tool.attribute.v1.DynamicAttributeTool;
|
||||||
|
import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags;
|
||||||
|
import net.minecraft.client.renderer.block.model.BlockModel;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.tags.Tag;
|
||||||
|
import net.minecraft.world.entity.LivingEntity;
|
||||||
|
import net.minecraft.world.item.AxeItem;
|
||||||
|
import net.minecraft.world.item.Item;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.item.Tier;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
import ru.bclib.client.models.ItemModelProvider;
|
||||||
|
import ru.bclib.client.models.ModelsHelper;
|
||||||
|
|
||||||
|
public class BaseAxeItem extends AxeItem implements DynamicAttributeTool, ItemModelProvider {
|
||||||
|
public BaseAxeItem(Tier material, float attackDamage, float attackSpeed, Properties settings) {
|
||||||
|
super(material, attackDamage, attackSpeed, settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMiningLevel(Tag<Item> tag, BlockState state, ItemStack stack, LivingEntity user) {
|
||||||
|
if (tag.equals(FabricToolTags.AXES)) {
|
||||||
|
return this.getTier().getLevel();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockModel getItemModel(ResourceLocation resourceLocation) {
|
||||||
|
return ModelsHelper.createHandheldItem(resourceLocation);
|
||||||
|
}
|
||||||
|
}
|
19
src/main/java/ru/bclib/items/tool/BaseHoeItem.java
Normal file
19
src/main/java/ru/bclib/items/tool/BaseHoeItem.java
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
package ru.bclib.items.tool;
|
||||||
|
|
||||||
|
import net.minecraft.client.renderer.block.model.BlockModel;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.world.item.HoeItem;
|
||||||
|
import net.minecraft.world.item.Tier;
|
||||||
|
import ru.bclib.client.models.ItemModelProvider;
|
||||||
|
import ru.bclib.client.models.ModelsHelper;
|
||||||
|
|
||||||
|
public class BaseHoeItem extends HoeItem implements ItemModelProvider {
|
||||||
|
public BaseHoeItem(Tier material, int attackDamage, float attackSpeed, Properties settings) {
|
||||||
|
super(material, attackDamage, attackSpeed, settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockModel getItemModel(ResourceLocation resourceLocation) {
|
||||||
|
return ModelsHelper.createHandheldItem(resourceLocation);
|
||||||
|
}
|
||||||
|
}
|
42
src/main/java/ru/bclib/items/tool/BasePickaxeItem.java
Normal file
42
src/main/java/ru/bclib/items/tool/BasePickaxeItem.java
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
package ru.bclib.items.tool;
|
||||||
|
|
||||||
|
import net.fabricmc.fabric.api.tool.attribute.v1.DynamicAttributeTool;
|
||||||
|
import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags;
|
||||||
|
import net.fabricmc.fabric.impl.tool.attribute.ToolManagerImpl;
|
||||||
|
import net.fabricmc.fabric.impl.tool.attribute.ToolManagerImpl.Entry;
|
||||||
|
import net.minecraft.client.renderer.block.model.BlockModel;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.tags.Tag;
|
||||||
|
import net.minecraft.world.entity.LivingEntity;
|
||||||
|
import net.minecraft.world.item.Item;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.item.PickaxeItem;
|
||||||
|
import net.minecraft.world.item.Tier;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
import ru.bclib.client.models.ItemModelProvider;
|
||||||
|
import ru.bclib.client.models.ModelsHelper;
|
||||||
|
|
||||||
|
public class BasePickaxeItem extends PickaxeItem implements DynamicAttributeTool, ItemModelProvider {
|
||||||
|
public BasePickaxeItem(Tier material, int attackDamage, float attackSpeed, Properties settings) {
|
||||||
|
super(material, attackDamage, attackSpeed, settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMiningLevel(Tag<Item> tag, BlockState state, ItemStack stack, LivingEntity user) {
|
||||||
|
if (tag.equals(FabricToolTags.PICKAXES)) {
|
||||||
|
return getTier().getLevel();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getDestroySpeed(ItemStack stack, BlockState state) {
|
||||||
|
Entry entry = ToolManagerImpl.entryNullable(state.getBlock());
|
||||||
|
return (entry != null && entry.getMiningLevel(FabricToolTags.PICKAXES) >= 0) ? speed : super.getDestroySpeed(stack, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockModel getItemModel(ResourceLocation resourceLocation) {
|
||||||
|
return ModelsHelper.createHandheldItem(resourceLocation);
|
||||||
|
}
|
||||||
|
}
|
42
src/main/java/ru/bclib/items/tool/BaseShovelItem.java
Normal file
42
src/main/java/ru/bclib/items/tool/BaseShovelItem.java
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
package ru.bclib.items.tool;
|
||||||
|
|
||||||
|
import net.fabricmc.fabric.api.tool.attribute.v1.DynamicAttributeTool;
|
||||||
|
import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags;
|
||||||
|
import net.fabricmc.fabric.impl.tool.attribute.ToolManagerImpl;
|
||||||
|
import net.fabricmc.fabric.impl.tool.attribute.ToolManagerImpl.Entry;
|
||||||
|
import net.minecraft.client.renderer.block.model.BlockModel;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.tags.Tag;
|
||||||
|
import net.minecraft.world.entity.LivingEntity;
|
||||||
|
import net.minecraft.world.item.Item;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.item.ShovelItem;
|
||||||
|
import net.minecraft.world.item.Tier;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
import ru.bclib.client.models.ItemModelProvider;
|
||||||
|
import ru.bclib.client.models.ModelsHelper;
|
||||||
|
|
||||||
|
public class BaseShovelItem extends ShovelItem implements DynamicAttributeTool, ItemModelProvider {
|
||||||
|
public BaseShovelItem(Tier material, float attackDamage, float attackSpeed, Properties settings) {
|
||||||
|
super(material, attackDamage, attackSpeed, settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMiningLevel(Tag<Item> tag, BlockState state, ItemStack stack, LivingEntity user) {
|
||||||
|
if (tag.equals(FabricToolTags.SHOVELS)) {
|
||||||
|
return this.getTier().getLevel();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getDestroySpeed(ItemStack stack, BlockState state) {
|
||||||
|
Entry entry = ToolManagerImpl.entryNullable(state.getBlock());
|
||||||
|
return (entry != null && entry.getMiningLevel(FabricToolTags.SHOVELS) >= 0) ? speed : super.getDestroySpeed(stack, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockModel getItemModel(ResourceLocation resourceLocation) {
|
||||||
|
return ModelsHelper.createHandheldItem(resourceLocation);
|
||||||
|
}
|
||||||
|
}
|
20
src/main/java/ru/bclib/items/tool/BaseSwordItem.java
Normal file
20
src/main/java/ru/bclib/items/tool/BaseSwordItem.java
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
package ru.bclib.items.tool;
|
||||||
|
|
||||||
|
import net.fabricmc.fabric.api.tool.attribute.v1.DynamicAttributeTool;
|
||||||
|
import net.minecraft.client.renderer.block.model.BlockModel;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.world.item.SwordItem;
|
||||||
|
import net.minecraft.world.item.Tier;
|
||||||
|
import ru.bclib.client.models.ItemModelProvider;
|
||||||
|
import ru.bclib.client.models.ModelsHelper;
|
||||||
|
|
||||||
|
public class BaseSwordItem extends SwordItem implements DynamicAttributeTool, ItemModelProvider {
|
||||||
|
public BaseSwordItem(Tier material, int attackDamage, float attackSpeed, Properties settings) {
|
||||||
|
super(material, attackDamage, attackSpeed, settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockModel getItemModel(ResourceLocation resourceLocation) {
|
||||||
|
return ModelsHelper.createHandheldItem(resourceLocation);
|
||||||
|
}
|
||||||
|
}
|
90
src/main/java/ru/bclib/registry/BaseBlockEntities.java
Normal file
90
src/main/java/ru/bclib/registry/BaseBlockEntities.java
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
package ru.bclib.registry;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
|
import net.minecraft.core.Registry;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.world.item.BlockItem;
|
||||||
|
import net.minecraft.world.level.block.Block;
|
||||||
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
|
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||||
|
import ru.bclib.BCLib;
|
||||||
|
import ru.bclib.blockentities.BaseBarrelBlockEntity;
|
||||||
|
import ru.bclib.blockentities.BaseChestBlockEntity;
|
||||||
|
import ru.bclib.blockentities.BaseFurnaceBlockEntity;
|
||||||
|
import ru.bclib.blockentities.BaseSignBlockEntity;
|
||||||
|
import ru.bclib.blocks.BaseBarrelBlock;
|
||||||
|
import ru.bclib.blocks.BaseChestBlock;
|
||||||
|
import ru.bclib.blocks.BaseFurnaceBlock;
|
||||||
|
import ru.bclib.blocks.BaseSignBlock;
|
||||||
|
|
||||||
|
public class BaseBlockEntities {
|
||||||
|
public static final BlockEntityType<BaseChestBlockEntity> CHEST = registerBlockEntity(BCLib.makeID("chest"),
|
||||||
|
BlockEntityType.Builder.of(BaseChestBlockEntity::new, getChests()));
|
||||||
|
public static final BlockEntityType<BaseBarrelBlockEntity> BARREL = registerBlockEntity(BCLib.makeID("barrel"),
|
||||||
|
BlockEntityType.Builder.of(BaseBarrelBlockEntity::new, getBarrels()));
|
||||||
|
public static final BlockEntityType<BaseSignBlockEntity> SIGN = registerBlockEntity(BCLib.makeID("sign"),
|
||||||
|
BlockEntityType.Builder.of(BaseSignBlockEntity::new, getSigns()));
|
||||||
|
public static final BlockEntityType<BaseFurnaceBlockEntity> FURNACE = registerBlockEntity(BCLib.makeID("furnace"),
|
||||||
|
BlockEntityType.Builder.of(BaseFurnaceBlockEntity::new, getFurnaces()));
|
||||||
|
|
||||||
|
public static <T extends BlockEntity> BlockEntityType<T> registerBlockEntity(ResourceLocation blockId, BlockEntityType.Builder<T> builder) {
|
||||||
|
return Registry.register(Registry.BLOCK_ENTITY_TYPE, blockId, builder.build(null));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void register() {}
|
||||||
|
|
||||||
|
static Block[] getChests() {
|
||||||
|
List<Block> result = Lists.newArrayList();
|
||||||
|
BaseRegistry.getModBlocks().forEach((item) -> {
|
||||||
|
if (item instanceof BlockItem) {
|
||||||
|
Block block = ((BlockItem) item).getBlock();
|
||||||
|
if (block instanceof BaseChestBlock) {
|
||||||
|
result.add(block);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return result.toArray(new Block[] {});
|
||||||
|
}
|
||||||
|
|
||||||
|
static Block[] getBarrels() {
|
||||||
|
List<Block> result = Lists.newArrayList();
|
||||||
|
BaseRegistry.getModBlocks().forEach((item) -> {
|
||||||
|
if (item instanceof BlockItem) {
|
||||||
|
Block block = ((BlockItem) item).getBlock();
|
||||||
|
if (block instanceof BaseBarrelBlock) {
|
||||||
|
result.add(block);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return result.toArray(new Block[] {});
|
||||||
|
}
|
||||||
|
|
||||||
|
static Block[] getSigns() {
|
||||||
|
List<Block> result = Lists.newArrayList();
|
||||||
|
BaseRegistry.getModBlocks().forEach((item) -> {
|
||||||
|
if (item instanceof BlockItem) {
|
||||||
|
Block block = ((BlockItem) item).getBlock();
|
||||||
|
if (block instanceof BaseSignBlock) {
|
||||||
|
result.add(block);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return result.toArray(new Block[] {});
|
||||||
|
}
|
||||||
|
|
||||||
|
static Block[] getFurnaces() {
|
||||||
|
List<Block> result = Lists.newArrayList();
|
||||||
|
BaseRegistry.getModBlocks().forEach((item) -> {
|
||||||
|
if (item instanceof BlockItem) {
|
||||||
|
Block block = ((BlockItem) item).getBlock();
|
||||||
|
if (block instanceof BaseFurnaceBlock) {
|
||||||
|
result.add(block);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return result.toArray(new Block[] {});
|
||||||
|
}
|
||||||
|
}
|
15
src/main/java/ru/bclib/registry/BaseBlockEntityRenders.java
Normal file
15
src/main/java/ru/bclib/registry/BaseBlockEntityRenders.java
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
package ru.bclib.registry;
|
||||||
|
|
||||||
|
import net.fabricmc.api.EnvType;
|
||||||
|
import net.fabricmc.api.Environment;
|
||||||
|
import net.fabricmc.fabric.api.client.rendereregistry.v1.BlockEntityRendererRegistry;
|
||||||
|
import ru.bclib.client.render.BaseChestBlockEntityRenderer;
|
||||||
|
import ru.bclib.client.render.BaseSignBlockEntityRenderer;
|
||||||
|
|
||||||
|
@Environment(EnvType.CLIENT)
|
||||||
|
public class BaseBlockEntityRenders {
|
||||||
|
public static void register() {
|
||||||
|
BlockEntityRendererRegistry.INSTANCE.register(BaseBlockEntities.CHEST, BaseChestBlockEntityRenderer::new);
|
||||||
|
BlockEntityRendererRegistry.INSTANCE.register(BaseBlockEntities.SIGN, BaseSignBlockEntityRenderer::new);
|
||||||
|
}
|
||||||
|
}
|
50
src/main/java/ru/bclib/registry/BaseRegistry.java
Normal file
50
src/main/java/ru/bclib/registry/BaseRegistry.java
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
package ru.bclib.registry;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import net.fabricmc.fabric.api.item.v1.FabricItemSettings;
|
||||||
|
import net.minecraft.core.Registry;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.world.item.*;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public abstract class BaseRegistry<T> {
|
||||||
|
protected static final List<Item> MOD_BLOCKS = Lists.newArrayList();
|
||||||
|
protected static final List<Item> MOD_ITEMS = Lists.newArrayList();
|
||||||
|
|
||||||
|
public static void register() {}
|
||||||
|
|
||||||
|
public static List<Item> getModBlocks() {
|
||||||
|
return MOD_BLOCKS;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<Item> getModItems() {
|
||||||
|
return MOD_ITEMS;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected final CreativeModeTab creativeTab;
|
||||||
|
|
||||||
|
protected BaseRegistry(CreativeModeTab creativeTab) {
|
||||||
|
this.creativeTab = creativeTab;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected T register(String name, T obj) {
|
||||||
|
return register(createModId(name), obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract T register(ResourceLocation objId, T obj);
|
||||||
|
|
||||||
|
protected abstract ResourceLocation createModId(String name);
|
||||||
|
|
||||||
|
protected void registerItem(ResourceLocation id, Item item, List<Item> registry) {
|
||||||
|
if (item != Items.AIR) {
|
||||||
|
Registry.register(Registry.ITEM, id, item);
|
||||||
|
registry.add(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public FabricItemSettings makeItemSettings() {
|
||||||
|
FabricItemSettings properties = new FabricItemSettings();
|
||||||
|
return (FabricItemSettings) properties.tab(creativeTab);
|
||||||
|
}
|
||||||
|
}
|
49
src/main/java/ru/bclib/registry/BlocksRegistry.java
Normal file
49
src/main/java/ru/bclib/registry/BlocksRegistry.java
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
package ru.bclib.registry;
|
||||||
|
|
||||||
|
import net.fabricmc.fabric.api.registry.FlammableBlockRegistry;
|
||||||
|
import net.minecraft.core.Registry;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.world.item.BlockItem;
|
||||||
|
import net.minecraft.world.item.CreativeModeTab;
|
||||||
|
import net.minecraft.world.item.Item;
|
||||||
|
import net.minecraft.world.item.Item.Properties;
|
||||||
|
import net.minecraft.world.item.WaterLilyBlockItem;
|
||||||
|
import net.minecraft.world.level.block.Block;
|
||||||
|
import ru.bclib.interfaces.ISpetialItem;
|
||||||
|
|
||||||
|
public abstract class BlocksRegistry extends BaseRegistry<Block> {
|
||||||
|
|
||||||
|
protected BlocksRegistry(CreativeModeTab creativeTab) {
|
||||||
|
super(creativeTab);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Block register(ResourceLocation id, Block block) {
|
||||||
|
int maxCount = 64;
|
||||||
|
boolean placeOnWater = false;
|
||||||
|
if (block instanceof ISpetialItem) {
|
||||||
|
ISpetialItem item = (ISpetialItem) block;
|
||||||
|
maxCount = item.getStackSize();
|
||||||
|
placeOnWater = item.canPlaceOnWater();
|
||||||
|
}
|
||||||
|
Properties item = makeItemSettings().stacksTo(maxCount);
|
||||||
|
if (placeOnWater) {
|
||||||
|
registerBlockItem(id, new WaterLilyBlockItem(block, item));
|
||||||
|
} else {
|
||||||
|
registerBlockItem(id, new BlockItem(block, item));
|
||||||
|
}
|
||||||
|
if (block.defaultBlockState().getMaterial().isFlammable() && FlammableBlockRegistry.getDefaultInstance().get(block).getBurnChance() == 0) {
|
||||||
|
FlammableBlockRegistry.getDefaultInstance().add(block, 5, 5);
|
||||||
|
}
|
||||||
|
return Registry.register(Registry.BLOCK, id, block);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Block registerBlockOnly(String name, Block block) {
|
||||||
|
return Registry.register(Registry.BLOCK, createModId(name), block);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Item registerBlockItem(ResourceLocation id, Item item) {
|
||||||
|
registerItem(id, item, BaseRegistry.MOD_BLOCKS);
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
}
|
111
src/main/java/ru/bclib/registry/ItemsRegistry.java
Normal file
111
src/main/java/ru/bclib/registry/ItemsRegistry.java
Normal file
|
@ -0,0 +1,111 @@
|
||||||
|
package ru.bclib.registry;
|
||||||
|
|
||||||
|
import net.fabricmc.fabric.api.tool.attribute.v1.FabricToolTags;
|
||||||
|
import net.minecraft.core.BlockSource;
|
||||||
|
import net.minecraft.core.Direction;
|
||||||
|
import net.minecraft.core.dispenser.DefaultDispenseItemBehavior;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.sounds.SoundEvent;
|
||||||
|
import net.minecraft.tags.Tag;
|
||||||
|
import net.minecraft.world.effect.MobEffectInstance;
|
||||||
|
import net.minecraft.world.entity.EntityType;
|
||||||
|
import net.minecraft.world.entity.MobSpawnType;
|
||||||
|
import net.minecraft.world.food.FoodProperties;
|
||||||
|
import net.minecraft.world.item.*;
|
||||||
|
import net.minecraft.world.level.block.DispenserBlock;
|
||||||
|
import ru.bclib.items.BaseDrinkItem;
|
||||||
|
import ru.bclib.items.BaseSpawnEggItem;
|
||||||
|
import ru.bclib.items.EndDiscItem;
|
||||||
|
import ru.bclib.items.ModelProviderItem;
|
||||||
|
import ru.bclib.items.tool.BaseAxeItem;
|
||||||
|
import ru.bclib.items.tool.BaseHoeItem;
|
||||||
|
import ru.bclib.items.tool.BasePickaxeItem;
|
||||||
|
import ru.bclib.util.TagHelper;
|
||||||
|
|
||||||
|
public abstract class ItemsRegistry extends BaseRegistry<Item> {
|
||||||
|
|
||||||
|
protected ItemsRegistry(CreativeModeTab creativeTab) {
|
||||||
|
super(creativeTab);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Item registerDisc(String name, int power, SoundEvent sound) {
|
||||||
|
return register(name, new EndDiscItem(power, sound, makeItemSettings()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Item registerItem(String name) {
|
||||||
|
return register(name, new ModelProviderItem(makeItemSettings()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Item register(ResourceLocation itemId, Item item) {
|
||||||
|
if (item instanceof ArmorItem) {
|
||||||
|
return registerArmor(itemId, item);
|
||||||
|
}
|
||||||
|
registerItem(itemId, item, BaseRegistry.MOD_ITEMS);
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Item registerArmor(ResourceLocation id, Item item) {
|
||||||
|
registerItem(id, item, BaseRegistry.MOD_ITEMS);
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TieredItem registerTool(String name, TieredItem item) {
|
||||||
|
ResourceLocation id = createModId(name);
|
||||||
|
registerItem(id, item, BaseRegistry.MOD_ITEMS);
|
||||||
|
|
||||||
|
if (item instanceof ShovelItem) {
|
||||||
|
TagHelper.addTag((Tag.Named<Item>) FabricToolTags.SHOVELS, item);
|
||||||
|
} else if (item instanceof SwordItem) {
|
||||||
|
TagHelper.addTag((Tag.Named<Item>) FabricToolTags.SWORDS, item);
|
||||||
|
} else if (item instanceof BasePickaxeItem) {
|
||||||
|
TagHelper.addTag((Tag.Named<Item>) FabricToolTags.PICKAXES, item);
|
||||||
|
} else if (item instanceof BaseAxeItem) {
|
||||||
|
TagHelper.addTag((Tag.Named<Item>) FabricToolTags.AXES, item);
|
||||||
|
} else if (item instanceof BaseHoeItem) {
|
||||||
|
TagHelper.addTag((Tag.Named<Item>) FabricToolTags.HOES, item);
|
||||||
|
}
|
||||||
|
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Item registerEgg(String name, EntityType<?> type, int background, int dots) {
|
||||||
|
SpawnEggItem item = new BaseSpawnEggItem(type, background, dots, makeItemSettings());
|
||||||
|
DefaultDispenseItemBehavior behavior = new DefaultDispenseItemBehavior() {
|
||||||
|
public ItemStack execute(BlockSource pointer, ItemStack stack) {
|
||||||
|
Direction direction = pointer.getBlockState().getValue(DispenserBlock.FACING);
|
||||||
|
EntityType<?> entityType = ((SpawnEggItem) stack.getItem()).getType(stack.getTag());
|
||||||
|
entityType.spawn(pointer.getLevel(), stack, null, pointer.getPos().relative(direction), MobSpawnType.DISPENSER, direction != Direction.UP, false);
|
||||||
|
stack.shrink(1);
|
||||||
|
return stack;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
DispenserBlock.registerBehavior(item, behavior);
|
||||||
|
return register(name, item);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Item registerFood(String name, int hunger, float saturation, MobEffectInstance... effects) {
|
||||||
|
FoodProperties.Builder builder = new FoodProperties.Builder().nutrition(hunger).saturationMod(saturation);
|
||||||
|
for (MobEffectInstance effect: effects) {
|
||||||
|
builder.effect(effect, 1F);
|
||||||
|
}
|
||||||
|
return registerFood(name, builder.build());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Item registerFood(String name, FoodProperties foodComponent) {
|
||||||
|
return register(name, new ModelProviderItem(makeItemSettings().food(foodComponent)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Item registerDrink(String name) {
|
||||||
|
return register(name, new BaseDrinkItem(makeItemSettings().stacksTo(1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Item registerDrink(String name, FoodProperties foodComponent) {
|
||||||
|
return register(name, new BaseDrinkItem(makeItemSettings().stacksTo(1).food(foodComponent)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Item registerDrink(String name, int hunger, float saturation) {
|
||||||
|
FoodProperties.Builder builder = new FoodProperties.Builder().nutrition(hunger).saturationMod(saturation);
|
||||||
|
return registerDrink(name, builder.build());
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue