package net.minecraft.world.entity.boss.enderdragon;

import net.minecraft.network.syncher.SynchedEntityData;
import net.minecraft.network.syncher.EntityDataSerializers;
import net.minecraft.network.protocol.game.ClientboundAddEntityPacket;
import net.minecraft.network.protocol.Packet;
import javax.annotation.Nullable;
import net.minecraft.world.level.dimension.end.EndDragonFight;
import net.minecraft.world.level.Explosion;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.nbt.Tag;
import net.minecraft.nbt.NbtUtils;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.block.BaseFireBlock;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.Level;
import net.minecraft.world.entity.EntityType;
import net.minecraft.core.BlockPos;
import java.util.Optional;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.world.entity.Entity;

public class EndCrystal extends Entity {
    private static final EntityDataAccessor<Optional<BlockPos>> DATA_BEAM_TARGET;
    private static final EntityDataAccessor<Boolean> DATA_SHOW_BOTTOM;
    public int time;
    
    public EndCrystal(final EntityType<? extends EndCrystal> aoq, final Level bqb) {
        super(aoq, bqb);
        this.blocksBuilding = true;
        this.time = this.random.nextInt(100000);
    }
    
    public EndCrystal(final Level bqb, final double double2, final double double3, final double double4) {
        this(EntityType.END_CRYSTAL, bqb);
        this.setPos(double2, double3, double4);
    }
    
    @Override
    protected boolean isMovementNoisy() {
        return false;
    }
    
    @Override
    protected void defineSynchedData() {
        this.getEntityData().<Optional<BlockPos>>define(EndCrystal.DATA_BEAM_TARGET, Optional.<BlockPos>empty());
        this.getEntityData().<Boolean>define(EndCrystal.DATA_SHOW_BOTTOM, true);
    }
    
    @Override
    public void tick() {
        ++this.time;
        if (this.level instanceof ServerLevel) {
            final BlockPos fu2 = this.blockPosition();
            if (((ServerLevel)this.level).dragonFight() != null && this.level.getBlockState(fu2).isAir()) {
                this.level.setBlockAndUpdate(fu2, BaseFireBlock.getState(this.level, fu2));
            }
        }
    }
    
    @Override
    protected void addAdditionalSaveData(final CompoundTag le) {
        if (this.getBeamTarget() != null) {
            le.put("BeamTarget", NbtUtils.writeBlockPos(this.getBeamTarget()));
        }
        le.putBoolean("ShowBottom", this.showsBottom());
    }
    
    @Override
    protected void readAdditionalSaveData(final CompoundTag le) {
        if (le.contains("BeamTarget", 10)) {
            this.setBeamTarget(NbtUtils.readBlockPos(le.getCompound("BeamTarget")));
        }
        if (le.contains("ShowBottom", 1)) {
            this.setShowBottom(le.getBoolean("ShowBottom"));
        }
    }
    
    @Override
    public boolean isPickable() {
        return true;
    }
    
    @Override
    public boolean hurt(final DamageSource anw, final float float2) {
        if (this.isInvulnerableTo(anw)) {
            return false;
        }
        if (anw.getEntity() instanceof EnderDragon) {
            return false;
        }
        if (!this.removed && !this.level.isClientSide) {
            this.remove();
            if (!anw.isExplosion()) {
                this.level.explode(null, this.getX(), this.getY(), this.getZ(), 6.0f, Explosion.BlockInteraction.DESTROY);
            }
            this.onDestroyedBy(anw);
        }
        return true;
    }
    
    @Override
    public void kill() {
        this.onDestroyedBy(DamageSource.GENERIC);
        super.kill();
    }
    
    private void onDestroyedBy(final DamageSource anw) {
        if (this.level instanceof ServerLevel) {
            final EndDragonFight cii3 = ((ServerLevel)this.level).dragonFight();
            if (cii3 != null) {
                cii3.onCrystalDestroyed(this, anw);
            }
        }
    }
    
    public void setBeamTarget(@Nullable final BlockPos fu) {
        this.getEntityData().<Optional<BlockPos>>set(EndCrystal.DATA_BEAM_TARGET, Optional.<BlockPos>ofNullable(fu));
    }
    
    @Nullable
    public BlockPos getBeamTarget() {
        return this.getEntityData().<Optional<BlockPos>>get(EndCrystal.DATA_BEAM_TARGET).orElse(null);
    }
    
    public void setShowBottom(final boolean boolean1) {
        this.getEntityData().<Boolean>set(EndCrystal.DATA_SHOW_BOTTOM, boolean1);
    }
    
    public boolean showsBottom() {
        return this.getEntityData().<Boolean>get(EndCrystal.DATA_SHOW_BOTTOM);
    }
    
    @Override
    public boolean shouldRenderAtSqrDistance(final double double1) {
        return super.shouldRenderAtSqrDistance(double1) || this.getBeamTarget() != null;
    }
    
    @Override
    public Packet<?> getAddEntityPacket() {
        return new ClientboundAddEntityPacket(this);
    }
    
    static {
        DATA_BEAM_TARGET = SynchedEntityData.<Optional<BlockPos>>defineId(EndCrystal.class, EntityDataSerializers.OPTIONAL_BLOCK_POS);
        DATA_SHOW_BOTTOM = SynchedEntityData.<Boolean>defineId(EndCrystal.class, EntityDataSerializers.BOOLEAN);
    }
}
