293 lines
14 KiB
Java
293 lines
14 KiB
Java
package net.minecraft.world.level.block;
|
|
|
|
import net.minecraft.world.level.block.state.AbstractStateHolder;
|
|
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
|
|
import net.minecraft.world.level.LevelAccessor;
|
|
import net.minecraft.world.entity.vehicle.MinecartTNT;
|
|
import net.minecraft.world.entity.boss.wither.WitherBoss;
|
|
import net.minecraft.world.entity.projectile.WitherSkull;
|
|
import net.minecraft.world.entity.monster.Creeper;
|
|
import net.minecraft.world.entity.item.PrimedTnt;
|
|
import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
|
|
import net.minecraft.world.level.storage.loot.LootContext;
|
|
import net.minecraft.world.entity.item.ItemEntity;
|
|
import net.minecraft.nbt.Tag;
|
|
import net.minecraft.nbt.CompoundTag;
|
|
import net.minecraft.world.level.GameRules;
|
|
import net.minecraft.world.level.block.state.StateDefinition;
|
|
import net.minecraft.world.item.BlockPlaceContext;
|
|
import net.minecraft.core.particles.ParticleOptions;
|
|
import net.minecraft.util.Mth;
|
|
import net.minecraft.core.particles.ParticleTypes;
|
|
import net.minecraft.world.phys.shapes.VoxelShape;
|
|
import net.minecraft.tags.BlockTags;
|
|
import net.minecraft.world.level.BlockGetter;
|
|
import java.util.Random;
|
|
import net.minecraft.sounds.SoundSource;
|
|
import net.minecraft.sounds.SoundEvents;
|
|
import net.minecraft.world.InteractionResult;
|
|
import net.minecraft.world.phys.BlockHitResult;
|
|
import net.minecraft.world.InteractionHand;
|
|
import net.minecraft.world.level.ItemLike;
|
|
import net.minecraft.world.item.Items;
|
|
import java.util.Iterator;
|
|
import java.util.List;
|
|
import net.minecraft.world.entity.Entity;
|
|
import net.minecraft.world.phys.AABB;
|
|
import net.minecraft.world.entity.animal.Bee;
|
|
import net.minecraft.server.level.ServerPlayer;
|
|
import net.minecraft.advancements.CriteriaTriggers;
|
|
import net.minecraft.world.item.enchantment.EnchantmentHelper;
|
|
import net.minecraft.world.item.enchantment.Enchantments;
|
|
import net.minecraft.world.level.block.entity.BeehiveBlockEntity;
|
|
import net.minecraft.world.item.ItemStack;
|
|
import javax.annotation.Nullable;
|
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
|
import net.minecraft.world.entity.player.Player;
|
|
import net.minecraft.core.BlockPos;
|
|
import net.minecraft.world.level.Level;
|
|
import net.minecraft.world.level.block.state.properties.Property;
|
|
import net.minecraft.world.level.block.state.BlockState;
|
|
import net.minecraft.world.level.block.state.properties.IntegerProperty;
|
|
import net.minecraft.world.level.block.state.properties.DirectionProperty;
|
|
import net.minecraft.core.Direction;
|
|
|
|
public class BeehiveBlock extends BaseEntityBlock {
|
|
public static final Direction[] SPAWN_DIRECTIONS;
|
|
public static final DirectionProperty FACING;
|
|
public static final IntegerProperty HONEY_LEVEL;
|
|
|
|
public BeehiveBlock(final Properties c) {
|
|
super(c);
|
|
this.registerDefaultState((((AbstractStateHolder<O, BlockState>)this.stateDefinition.any()).setValue((Property<Comparable>)BeehiveBlock.HONEY_LEVEL, 0)).<Comparable, Direction>setValue((Property<Comparable>)BeehiveBlock.FACING, Direction.NORTH));
|
|
}
|
|
|
|
@Override
|
|
public boolean hasAnalogOutputSignal(final BlockState byg) {
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public int getAnalogOutputSignal(final BlockState byg, final Level bjt, final BlockPos fk) {
|
|
return byg.<Integer>getValue((Property<Integer>)BeehiveBlock.HONEY_LEVEL);
|
|
}
|
|
|
|
@Override
|
|
public void playerDestroy(final Level bjt, final Player ayg, final BlockPos fk, final BlockState byg, @Nullable final BlockEntity bwi, final ItemStack bek) {
|
|
super.playerDestroy(bjt, ayg, fk, byg, bwi, bek);
|
|
if (!bjt.isClientSide && bwi instanceof BeehiveBlockEntity) {
|
|
final BeehiveBlockEntity bwf8 = (BeehiveBlockEntity)bwi;
|
|
if (EnchantmentHelper.getItemEnchantmentLevel(Enchantments.SILK_TOUCH, bek) == 0) {
|
|
bwf8.emptyAllLivingFromHive(ayg, byg, BeehiveBlockEntity.BeeReleaseStatus.EMERGENCY);
|
|
bjt.updateNeighbourForOutputSignal(fk, this);
|
|
}
|
|
this.angerNearbyBees(bjt, fk);
|
|
CriteriaTriggers.BEE_NEST_DESTROYED.trigger((ServerPlayer)ayg, byg.getBlock(), bek, bwf8.getOccupantCount());
|
|
}
|
|
}
|
|
|
|
private void angerNearbyBees(final Level bjt, final BlockPos fk) {
|
|
final List<Bee> list4 = bjt.<Bee>getEntitiesOfClass(Bee.class, new AABB(fk).inflate(8.0, 6.0, 8.0));
|
|
if (!list4.isEmpty()) {
|
|
final List<Player> list5 = bjt.<Player>getEntitiesOfClass(Player.class, new AABB(fk).inflate(8.0, 6.0, 8.0));
|
|
final int integer6 = list5.size();
|
|
for (final Bee ata8 : list4) {
|
|
if (ata8.getTarget() == null) {
|
|
ata8.makeAngry(list5.get(bjt.random.nextInt(integer6)));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public static void dropHoneycomb(final Level bjt, final BlockPos fk) {
|
|
for (int integer3 = 0; integer3 < 3; ++integer3) {
|
|
Block.popResource(bjt, fk, new ItemStack(Items.HONEYCOMB, 1));
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public InteractionResult use(final BlockState byg, final Level bjt, final BlockPos fk, final Player ayg, final InteractionHand ajh, final BlockHitResult cvd) {
|
|
final ItemStack bek8 = ayg.getItemInHand(ajh);
|
|
final ItemStack bek9 = bek8.copy();
|
|
final int integer10 = byg.<Integer>getValue((Property<Integer>)BeehiveBlock.HONEY_LEVEL);
|
|
boolean boolean11 = false;
|
|
if (integer10 >= 5) {
|
|
if (bek8.getItem() == Items.SHEARS) {
|
|
bjt.playSound(ayg, ayg.getX(), ayg.getY(), ayg.getZ(), SoundEvents.BEEHIVE_SHEAR, SoundSource.NEUTRAL, 1.0f, 1.0f);
|
|
dropHoneycomb(bjt, fk);
|
|
bek8.<Player>hurtAndBreak(1, ayg, ayg -> ayg.broadcastBreakEvent(ajh));
|
|
boolean11 = true;
|
|
}
|
|
else if (bek8.getItem() == Items.GLASS_BOTTLE) {
|
|
bek8.shrink(1);
|
|
bjt.playSound(ayg, ayg.getX(), ayg.getY(), ayg.getZ(), SoundEvents.BOTTLE_FILL, SoundSource.NEUTRAL, 1.0f, 1.0f);
|
|
if (bek8.isEmpty()) {
|
|
ayg.setItemInHand(ajh, new ItemStack(Items.HONEY_BOTTLE));
|
|
}
|
|
else if (!ayg.inventory.add(new ItemStack(Items.HONEY_BOTTLE))) {
|
|
ayg.drop(new ItemStack(Items.HONEY_BOTTLE), false);
|
|
}
|
|
boolean11 = true;
|
|
}
|
|
}
|
|
if (boolean11) {
|
|
if (!CampfireBlock.isSmokeyPos(bjt, fk, 5)) {
|
|
if (this.hiveContainsBees(bjt, fk)) {
|
|
this.angerNearbyBees(bjt, fk);
|
|
}
|
|
this.releaseBeesAndResetHoneyLevel(bjt, byg, fk, ayg, BeehiveBlockEntity.BeeReleaseStatus.EMERGENCY);
|
|
}
|
|
else {
|
|
this.resetHoneyLevel(bjt, byg, fk);
|
|
if (ayg instanceof ServerPlayer) {
|
|
CriteriaTriggers.SAFELY_HARVEST_HONEY.trigger((ServerPlayer)ayg, fk, bek9);
|
|
}
|
|
}
|
|
return InteractionResult.SUCCESS;
|
|
}
|
|
return super.use(byg, bjt, fk, ayg, ajh, cvd);
|
|
}
|
|
|
|
private boolean hiveContainsBees(final Level bjt, final BlockPos fk) {
|
|
final BlockEntity bwi4 = bjt.getBlockEntity(fk);
|
|
if (bwi4 instanceof BeehiveBlockEntity) {
|
|
final BeehiveBlockEntity bwf5 = (BeehiveBlockEntity)bwi4;
|
|
return !bwf5.isEmpty();
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public void releaseBeesAndResetHoneyLevel(final Level bjt, final BlockState byg, final BlockPos fk, @Nullable final Player ayg, final BeehiveBlockEntity.BeeReleaseStatus b) {
|
|
this.resetHoneyLevel(bjt, byg, fk);
|
|
final BlockEntity bwi7 = bjt.getBlockEntity(fk);
|
|
if (bwi7 instanceof BeehiveBlockEntity) {
|
|
final BeehiveBlockEntity bwf8 = (BeehiveBlockEntity)bwi7;
|
|
bwf8.emptyAllLivingFromHive(ayg, byg, b);
|
|
}
|
|
}
|
|
|
|
public void resetHoneyLevel(final Level bjt, final BlockState byg, final BlockPos fk) {
|
|
bjt.setBlock(fk, ((AbstractStateHolder<O, BlockState>)byg).<Comparable, Integer>setValue((Property<Comparable>)BeehiveBlock.HONEY_LEVEL, 0), 3);
|
|
}
|
|
|
|
@Override
|
|
public void animateTick(final BlockState byg, final Level bjt, final BlockPos fk, final Random random) {
|
|
if (byg.<Integer>getValue((Property<Integer>)BeehiveBlock.HONEY_LEVEL) >= 5) {
|
|
for (int integer6 = 0; integer6 < random.nextInt(1) + 1; ++integer6) {
|
|
this.trySpawnDripParticles(bjt, fk, byg);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void trySpawnDripParticles(final Level bjt, final BlockPos fk, final BlockState byg) {
|
|
if (!byg.getFluidState().isEmpty() || bjt.random.nextFloat() < 0.3f) {
|
|
return;
|
|
}
|
|
final VoxelShape cwc5 = byg.getCollisionShape(bjt, fk);
|
|
final double double6 = cwc5.max(Direction.Axis.Y);
|
|
if (double6 >= 1.0 && !byg.is(BlockTags.IMPERMEABLE)) {
|
|
final double double7 = cwc5.min(Direction.Axis.Y);
|
|
if (double7 > 0.0) {
|
|
this.spawnParticle(bjt, fk, cwc5, fk.getY() + double7 - 0.05);
|
|
}
|
|
else {
|
|
final BlockPos fk2 = fk.below();
|
|
final BlockState byg2 = bjt.getBlockState(fk2);
|
|
final VoxelShape cwc6 = byg2.getCollisionShape(bjt, fk2);
|
|
final double double8 = cwc6.max(Direction.Axis.Y);
|
|
if ((double8 < 1.0 || !byg2.isCollisionShapeFullBlock(bjt, fk2)) && byg2.getFluidState().isEmpty()) {
|
|
this.spawnParticle(bjt, fk, cwc5, fk.getY() - 0.05);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void spawnParticle(final Level bjt, final BlockPos fk, final VoxelShape cwc, final double double4) {
|
|
this.spawnFluidParticle(bjt, fk.getX() + cwc.min(Direction.Axis.X), fk.getX() + cwc.max(Direction.Axis.X), fk.getZ() + cwc.min(Direction.Axis.Z), fk.getZ() + cwc.max(Direction.Axis.Z), double4);
|
|
}
|
|
|
|
private void spawnFluidParticle(final Level bjt, final double double2, final double double3, final double double4, final double double5, final double double6) {
|
|
bjt.addParticle(ParticleTypes.DRIPPING_HONEY, Mth.lerp(bjt.random.nextDouble(), double2, double3), double6, Mth.lerp(bjt.random.nextDouble(), double4, double5), 0.0, 0.0, 0.0);
|
|
}
|
|
|
|
@Override
|
|
public BlockState getStateForPlacement(final BlockPlaceContext bcn) {
|
|
return ((AbstractStateHolder<O, BlockState>)this.defaultBlockState()).<Comparable, Direction>setValue((Property<Comparable>)BeehiveBlock.FACING, bcn.getHorizontalDirection().getOpposite());
|
|
}
|
|
|
|
@Override
|
|
protected void createBlockStateDefinition(final StateDefinition.Builder<Block, BlockState> a) {
|
|
a.add(BeehiveBlock.HONEY_LEVEL, BeehiveBlock.FACING);
|
|
}
|
|
|
|
@Override
|
|
public RenderShape getRenderShape(final BlockState byg) {
|
|
return RenderShape.MODEL;
|
|
}
|
|
|
|
@Nullable
|
|
@Override
|
|
public BlockEntity newBlockEntity(final BlockGetter bjd) {
|
|
return new BeehiveBlockEntity();
|
|
}
|
|
|
|
@Override
|
|
public void playerWillDestroy(final Level bjt, final BlockPos fk, final BlockState byg, final Player ayg) {
|
|
if (!bjt.isClientSide && ayg.isCreative() && bjt.getGameRules().getBoolean(GameRules.RULE_DOBLOCKDROPS)) {
|
|
final BlockEntity bwi6 = bjt.getBlockEntity(fk);
|
|
if (bwi6 instanceof BeehiveBlockEntity) {
|
|
final BeehiveBlockEntity bwf7 = (BeehiveBlockEntity)bwi6;
|
|
final ItemStack bek8 = new ItemStack(this);
|
|
final int integer9 = byg.<Integer>getValue((Property<Integer>)BeehiveBlock.HONEY_LEVEL);
|
|
final boolean boolean10 = !bwf7.isEmpty();
|
|
if (!boolean10 && integer9 == 0) {
|
|
return;
|
|
}
|
|
if (boolean10) {
|
|
final CompoundTag jt11 = new CompoundTag();
|
|
jt11.put("Bees", bwf7.writeBees());
|
|
bek8.addTagElement("BlockEntityTag", jt11);
|
|
}
|
|
final CompoundTag jt11 = new CompoundTag();
|
|
jt11.putInt("honey_level", integer9);
|
|
bek8.addTagElement("BlockStateTag", jt11);
|
|
final ItemEntity avy12 = new ItemEntity(bjt, fk.getX(), fk.getY(), fk.getZ(), bek8);
|
|
avy12.setDefaultPickUpDelay();
|
|
bjt.addFreshEntity(avy12);
|
|
}
|
|
}
|
|
super.playerWillDestroy(bjt, fk, byg, ayg);
|
|
}
|
|
|
|
@Override
|
|
public List<ItemStack> getDrops(final BlockState byg, final LootContext.Builder a) {
|
|
final Entity akn4 = a.<Entity>getOptionalParameter(LootContextParams.THIS_ENTITY);
|
|
if (akn4 instanceof PrimedTnt || akn4 instanceof Creeper || akn4 instanceof WitherSkull || akn4 instanceof WitherBoss || akn4 instanceof MinecartTNT) {
|
|
final BlockEntity bwi5 = a.<BlockEntity>getOptionalParameter(LootContextParams.BLOCK_ENTITY);
|
|
if (bwi5 instanceof BeehiveBlockEntity) {
|
|
final BeehiveBlockEntity bwf6 = (BeehiveBlockEntity)bwi5;
|
|
bwf6.emptyAllLivingFromHive(null, byg, BeehiveBlockEntity.BeeReleaseStatus.EMERGENCY);
|
|
}
|
|
}
|
|
return super.getDrops(byg, a);
|
|
}
|
|
|
|
@Override
|
|
public BlockState updateShape(final BlockState byg1, final Direction fp, final BlockState byg3, final LevelAccessor bju, final BlockPos fk5, final BlockPos fk6) {
|
|
if (bju.getBlockState(fk6).getBlock() instanceof FireBlock) {
|
|
final BlockEntity bwi8 = bju.getBlockEntity(fk5);
|
|
if (bwi8 instanceof BeehiveBlockEntity) {
|
|
final BeehiveBlockEntity bwf9 = (BeehiveBlockEntity)bwi8;
|
|
bwf9.emptyAllLivingFromHive(null, byg1, BeehiveBlockEntity.BeeReleaseStatus.EMERGENCY);
|
|
}
|
|
}
|
|
return super.updateShape(byg1, fp, byg3, bju, fk5, fk6);
|
|
}
|
|
|
|
static {
|
|
SPAWN_DIRECTIONS = new Direction[] { Direction.WEST, Direction.EAST, Direction.SOUTH };
|
|
FACING = HorizontalDirectionalBlock.FACING;
|
|
HONEY_LEVEL = BlockStateProperties.LEVEL_HONEY;
|
|
}
|
|
}
|