minecraft-source/src/net/minecraft/world/level/block/BeehiveBlock.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;
}
}