Newer
Older
void-pack-super-server / work / nms.old.1585251758016 / minecraft / server / TileEntityBeehive.java
package net.minecraft.server;

import com.google.common.collect.Lists;
import java.util.Iterator;
import java.util.List;
import javax.annotation.Nullable;

public class TileEntityBeehive extends TileEntity implements ITickable {

    private final List<TileEntityBeehive.HiveBee> bees = Lists.newArrayList();
    @Nullable
    public BlockPosition flowerPos = null;
    public int maxBees = 3; // CraftBukkit - allow setting max amount of bees a hive can hold

    public TileEntityBeehive() {
        super(TileEntityTypes.BEEHIVE);
    }

    @Override
    public void update() {
        if (this.d()) {
            this.a((EntityHuman) null, this.world.getType(this.getPosition()), TileEntityBeehive.ReleaseStatus.EMERGENCY);
        }

        super.update();
    }

    public boolean d() {
        if (this.world == null) {
            return false;
        } else {
            Iterator iterator = BlockPosition.a(this.position.b(-1, -1, -1), this.position.b(1, 1, 1)).iterator();

            BlockPosition blockposition;

            do {
                if (!iterator.hasNext()) {
                    return false;
                }

                blockposition = (BlockPosition) iterator.next();
            } while (!(this.world.getType(blockposition).getBlock() instanceof BlockFire));

            return true;
        }
    }

    public boolean isEmpty() {
        return this.bees.isEmpty();
    }

    public boolean isFull() {
        return this.bees.size() == this.maxBees; // CraftBukkit
    }

    public void a(@Nullable EntityHuman entityhuman, IBlockData iblockdata, TileEntityBeehive.ReleaseStatus tileentitybeehive_releasestatus) {
        List<Entity> list = this.a(iblockdata, tileentitybeehive_releasestatus);

        if (entityhuman != null) {
            Iterator iterator = list.iterator();

            while (iterator.hasNext()) {
                Entity entity = (Entity) iterator.next();

                if (entity instanceof EntityBee) {
                    EntityBee entitybee = (EntityBee) entity;

                    if (entityhuman.getPositionVector().distanceSquared(entity.getPositionVector()) <= 16.0D) {
                        if (!this.k()) {
                            entitybee.a((Entity) entityhuman);
                        } else {
                            entitybee.setCannotEnterHiveTicks(400);
                        }
                    }
                }
            }
        }

    }

    // CraftBukkit start - This allows us to bypass the night/rain/emergency check
    private List<Entity> a(IBlockData iblockdata, TileEntityBeehive.ReleaseStatus tileentitybeehive_releasestatus) { // PAIL rename releaseBees
        return releaseBees(iblockdata, tileentitybeehive_releasestatus, false);
    }

    public List<Entity> releaseBees(IBlockData iblockdata, TileEntityBeehive.ReleaseStatus tileentitybeehive_releasestatus, boolean force) {
        List<Entity> list = Lists.newArrayList();

        this.bees.removeIf((tileentitybeehive_hivebee) -> {
            return this.releaseBee(iblockdata, tileentitybeehive_hivebee.entityData, list, tileentitybeehive_releasestatus, force);
            // CraftBukkit end
        });
        return list;
    }

    public void a(Entity entity, boolean flag) {
        this.a(entity, flag, 0);
    }

    public int j() {
        return this.bees.size();
    }

    public static int a(IBlockData iblockdata) {
        return (Integer) iblockdata.get(BlockBeehive.c);
    }

    public boolean k() {
        return BlockCampfire.b(this.world, this.getPosition(), 5);
    }

    protected void l() {
        PacketDebug.a(this);
    }

    public void a(Entity entity, boolean flag, int i) {
        if (this.bees.size() < this.maxBees) { // CraftBukkit
            // CraftBukkit start
            if (this.world != null) {
                org.bukkit.event.entity.EntityEnterBlockEvent event = new org.bukkit.event.entity.EntityEnterBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, getPosition()));
                org.bukkit.Bukkit.getPluginManager().callEvent(event);
                if (event.isCancelled()) {
                    if (entity instanceof EntityBee) {
                        ((EntityBee) entity).setCannotEnterHiveTicks(400);
                    }
                    return;
                }
            }
            // CraftBukkit end
            entity.stopRiding();
            entity.ejectPassengers();
            NBTTagCompound nbttagcompound = new NBTTagCompound();

            entity.d(nbttagcompound);
            this.bees.add(new TileEntityBeehive.HiveBee(nbttagcompound, i, flag ? 2400 : 600));
            if (this.world != null) {
                if (entity instanceof EntityBee) {
                    EntityBee entitybee = (EntityBee) entity;

                    if (entitybee.hasFlowerPos() && (!this.x() || this.world.random.nextBoolean())) {
                        this.flowerPos = entitybee.getFlowerPos();
                    }
                }

                BlockPosition blockposition = this.getPosition();

                this.world.playSound((EntityHuman) null, (double) blockposition.getX(), (double) blockposition.getY(), (double) blockposition.getZ(), SoundEffects.BLOCK_BEEHIVE_ENTER, SoundCategory.BLOCKS, 1.0F, 1.0F);
            }

            entity.die();
        }
    }

    // CraftBukkit start - This allows us to bypass the night/rain/emergency check
    private boolean a(IBlockData iblockdata, NBTTagCompound nbttagcompound, @Nullable List<Entity> list, TileEntityBeehive.ReleaseStatus tileentitybeehive_releasestatus) { // PAIL rename releaseBee
        return releaseBee(iblockdata, nbttagcompound, list, tileentitybeehive_releasestatus, false);
    }

    private boolean releaseBee(IBlockData iblockdata, NBTTagCompound nbttagcompound, @Nullable List<Entity> list, TileEntityBeehive.ReleaseStatus tileentitybeehive_releasestatus, boolean force) {
        BlockPosition blockposition = this.getPosition();

        if (!force && (this.world.isNight() || this.world.isRaining()) && tileentitybeehive_releasestatus != TileEntityBeehive.ReleaseStatus.EMERGENCY) {
            // CraftBukkit end
            return false;
        } else {
            nbttagcompound.remove("Passengers");
            nbttagcompound.remove("Leash");
            nbttagcompound.c("UUID");
            EnumDirection enumdirection = (EnumDirection) iblockdata.get(BlockBeehive.b);
            BlockPosition blockposition1 = blockposition.shift(enumdirection);
            boolean flag = !this.world.getType(blockposition1).getCollisionShape(this.world, blockposition1).isEmpty();

            if (flag && tileentitybeehive_releasestatus != TileEntityBeehive.ReleaseStatus.EMERGENCY) {
                return false;
            } else {
                Entity entity = EntityTypes.a(nbttagcompound, this.world, (entity1) -> {
                    return entity1;
                });

                if (entity != null) {
                    float f = entity.getWidth();
                    double d0 = flag ? 0.0D : 0.55D + (double) (f / 2.0F);
                    double d1 = (double) blockposition.getX() + 0.5D + d0 * (double) enumdirection.getAdjacentX();
                    double d2 = (double) blockposition.getY() + 0.5D - (double) (entity.getHeight() / 2.0F);
                    double d3 = (double) blockposition.getZ() + 0.5D + d0 * (double) enumdirection.getAdjacentZ();

                    entity.setPositionRotation(d1, d2, d3, entity.yaw, entity.pitch);
                    if (!entity.getEntityType().a(TagsEntity.BEEHIVE_INHABITORS)) {
                        return false;
                    } else {
                        if (!this.world.addEntity(entity, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.BEEHIVE)) return false; // CraftBukkit - SpawnReason, moved from below
                        if (entity instanceof EntityBee) {
                            EntityBee entitybee = (EntityBee) entity;

                            if (this.x() && !entitybee.hasFlowerPos() && this.world.random.nextFloat() < 0.9F) {
                                entitybee.setFlowerPos(this.flowerPos);
                            }

                            if (tileentitybeehive_releasestatus == TileEntityBeehive.ReleaseStatus.HONEY_DELIVERED) {
                                entitybee.eG();
                                if (iblockdata.getBlock().a(TagsBlock.BEEHIVES)) {
                                    int i = a(iblockdata);

                                    if (i < 5) {
                                        int j = this.world.random.nextInt(100) == 0 ? 2 : 1;

                                        if (i + j > 5) {
                                            --j;
                                        }

                                        this.world.setTypeUpdate(this.getPosition(), (IBlockData) iblockdata.set(BlockBeehive.c, i + j));
                                    }
                                }
                            }

                            entitybee.eu();
                            if (list != null) {
                                list.add(entitybee);
                            }
                        }

                        BlockPosition blockposition2 = this.getPosition();

                        this.world.playSound((EntityHuman) null, (double) blockposition2.getX(), (double) blockposition2.getY(), (double) blockposition2.getZ(), SoundEffects.BLOCK_BEEHIVE_EXIT, SoundCategory.BLOCKS, 1.0F, 1.0F);
                        return true; // return this.world.addEntity(entity); // CraftBukkit - moved up
                    }
                } else {
                    return false;
                }
            }
        }
    }

    private boolean x() {
        return this.flowerPos != null;
    }

    private void y() {
        Iterator<TileEntityBeehive.HiveBee> iterator = this.bees.iterator();
        IBlockData iblockdata = this.getBlock();

        while (iterator.hasNext()) {
            TileEntityBeehive.HiveBee tileentitybeehive_hivebee = (TileEntityBeehive.HiveBee) iterator.next();

            if (tileentitybeehive_hivebee.ticksInHive > tileentitybeehive_hivebee.minOccupationTicks) {
                NBTTagCompound nbttagcompound = tileentitybeehive_hivebee.entityData;
                TileEntityBeehive.ReleaseStatus tileentitybeehive_releasestatus = nbttagcompound.getBoolean("HasNectar") ? TileEntityBeehive.ReleaseStatus.HONEY_DELIVERED : TileEntityBeehive.ReleaseStatus.BEE_RELEASED;

                if (this.a(iblockdata, nbttagcompound, (List) null, tileentitybeehive_releasestatus)) {
                    iterator.remove();
                }
                // CraftBukkit start
                else {
                    tileentitybeehive_hivebee.ticksInHive = tileentitybeehive_hivebee.minOccupationTicks / 2; // Not strictly Vanilla behaviour in cases where bees cannot spawn but still reasonable
                }
                // CraftBukkit end
            } else {
                tileentitybeehive_hivebee.ticksInHive++;
            }
        }

    }

    @Override
    public void tick() {
        if (!this.world.isClientSide) {
            this.y();
            BlockPosition blockposition = this.getPosition();

            if (this.bees.size() > 0 && this.world.getRandom().nextDouble() < 0.005D) {
                double d0 = (double) blockposition.getX() + 0.5D;
                double d1 = (double) blockposition.getY();
                double d2 = (double) blockposition.getZ() + 0.5D;

                this.world.playSound((EntityHuman) null, d0, d1, d2, SoundEffects.BLOCK_BEEHIVE_WORK, SoundCategory.BLOCKS, 1.0F, 1.0F);
            }

            this.l();
        }
    }

    @Override
    public void load(NBTTagCompound nbttagcompound) {
        super.load(nbttagcompound);
        this.bees.clear();
        NBTTagList nbttaglist = nbttagcompound.getList("Bees", 10);

        for (int i = 0; i < nbttaglist.size(); ++i) {
            NBTTagCompound nbttagcompound1 = nbttaglist.getCompound(i);
            TileEntityBeehive.HiveBee tileentitybeehive_hivebee = new TileEntityBeehive.HiveBee(nbttagcompound1.getCompound("EntityData"), nbttagcompound1.getInt("TicksInHive"), nbttagcompound1.getInt("MinOccupationTicks"));

            this.bees.add(tileentitybeehive_hivebee);
        }

        this.flowerPos = null;
        if (nbttagcompound.hasKey("FlowerPos")) {
            this.flowerPos = GameProfileSerializer.c(nbttagcompound.getCompound("FlowerPos"));
        }

        // CraftBukkit start
        if (nbttagcompound.hasKey("Bukkit.MaxEntities")) {
            this.maxBees = nbttagcompound.getInt("Bukkit.MaxEntities");
        }
        // CraftBukkit end
    }

    @Override
    public NBTTagCompound save(NBTTagCompound nbttagcompound) {
        super.save(nbttagcompound);
        nbttagcompound.set("Bees", this.m());
        if (this.x()) {
            nbttagcompound.set("FlowerPos", GameProfileSerializer.a(this.flowerPos));
        }
        nbttagcompound.setInt("Bukkit.MaxEntities", this.maxBees); // CraftBukkit

        return nbttagcompound;
    }

    public NBTTagList m() {
        NBTTagList nbttaglist = new NBTTagList();
        Iterator iterator = this.bees.iterator();

        while (iterator.hasNext()) {
            TileEntityBeehive.HiveBee tileentitybeehive_hivebee = (TileEntityBeehive.HiveBee) iterator.next();

            tileentitybeehive_hivebee.entityData.c("UUID");
            NBTTagCompound nbttagcompound = new NBTTagCompound();

            nbttagcompound.set("EntityData", tileentitybeehive_hivebee.entityData);
            nbttagcompound.setInt("TicksInHive", tileentitybeehive_hivebee.ticksInHive);
            nbttagcompound.setInt("MinOccupationTicks", tileentitybeehive_hivebee.minOccupationTicks);
            nbttaglist.add(nbttagcompound);
        }

        return nbttaglist;
    }

    static class HiveBee {

        private final NBTTagCompound entityData;
        private int ticksInHive;
        private final int minOccupationTicks;

        private HiveBee(NBTTagCompound nbttagcompound, int i, int j) {
            nbttagcompound.c("UUID");
            this.entityData = nbttagcompound;
            this.ticksInHive = i;
            this.minOccupationTicks = j;
        }
    }

    public static enum ReleaseStatus {

        HONEY_DELIVERED, BEE_RELEASED, EMERGENCY;

        private ReleaseStatus() {}
    }
}