package net.minecraft.world.entity.projectile;

import net.minecraft.network.protocol.game.ClientboundAddEntityPacket;
import net.minecraft.network.protocol.Packet;
import java.util.Iterator;
import java.util.List;
import java.util.UUID;
import net.minecraft.nbt.Tag;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.phys.EntityHitResult;
import net.minecraft.world.phys.HitResult;
import net.minecraft.world.phys.Vec3;
import net.minecraft.world.level.material.Material;
import net.minecraft.world.level.ClipContext;
import net.minecraft.core.particles.ParticleOptions;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.util.Mth;
import net.minecraft.world.level.Level;
import net.minecraft.world.entity.EntityType;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.entity.animal.horse.Llama;
import net.minecraft.world.entity.Entity;

public class LlamaSpit extends Entity implements Projectile {
    public Llama owner;
    private CompoundTag ownerTag;
    
    public LlamaSpit(final EntityType<? extends LlamaSpit> aku, final Level bjw) {
        super(aku, bjw);
    }
    
    public LlamaSpit(final Level bjw, final Llama auh) {
        this(EntityType.LLAMA_SPIT, bjw);
        this.owner = auh;
        this.setPos(auh.getX() - (auh.getBbWidth() + 1.0f) * 0.5 * Mth.sin(auh.yBodyRot * 0.017453292f), auh.getEyeY() - 0.10000000149011612, auh.getZ() + (auh.getBbWidth() + 1.0f) * 0.5 * Mth.cos(auh.yBodyRot * 0.017453292f));
    }
    
    public LlamaSpit(final Level bjw, final double double2, final double double3, final double double4, final double double5, final double double6, final double double7) {
        this(EntityType.LLAMA_SPIT, bjw);
        this.setPos(double2, double3, double4);
        for (int integer15 = 0; integer15 < 7; ++integer15) {
            final double double8 = 0.4 + 0.1 * integer15;
            bjw.addParticle(ParticleTypes.SPIT, double2, double3, double4, double5 * double8, double6, double7 * double8);
        }
        this.setDeltaMovement(double5, double6, double7);
    }
    
    @Override
    public void tick() {
        super.tick();
        if (this.ownerTag != null) {
            this.restoreOwnerFromSave();
        }
        final Vec3 cvl2 = this.getDeltaMovement();
        final HitResult cvi3 = ProjectileUtil.getHitResult(this, this.getBoundingBox().expandTowards(cvl2).inflate(1.0), akq -> !akq.isSpectator() && akq != this.owner, ClipContext.Block.OUTLINE, true);
        if (cvi3 != null) {
            this.onHit(cvi3);
        }
        final double double4 = this.getX() + cvl2.x;
        final double double5 = this.getY() + cvl2.y;
        final double double6 = this.getZ() + cvl2.z;
        final float float10 = Mth.sqrt(Entity.getHorizontalDistanceSqr(cvl2));
        this.yRot = (float)(Mth.atan2(cvl2.x, cvl2.z) * 57.2957763671875);
        this.xRot = (float)(Mth.atan2(cvl2.y, float10) * 57.2957763671875);
        while (this.xRot - this.xRotO < -180.0f) {
            this.xRotO -= 360.0f;
        }
        while (this.xRot - this.xRotO >= 180.0f) {
            this.xRotO += 360.0f;
        }
        while (this.yRot - this.yRotO < -180.0f) {
            this.yRotO -= 360.0f;
        }
        while (this.yRot - this.yRotO >= 180.0f) {
            this.yRotO += 360.0f;
        }
        this.xRot = Mth.lerp(0.2f, this.xRotO, this.xRot);
        this.yRot = Mth.lerp(0.2f, this.yRotO, this.yRot);
        final float float11 = 0.99f;
        final float float12 = 0.06f;
        if (!this.level.containsMaterial(this.getBoundingBox(), Material.AIR)) {
            this.remove();
            return;
        }
        if (this.isInWaterOrBubble()) {
            this.remove();
            return;
        }
        this.setDeltaMovement(cvl2.scale(0.9900000095367432));
        if (!this.isNoGravity()) {
            this.setDeltaMovement(this.getDeltaMovement().add(0.0, -0.05999999865889549, 0.0));
        }
        this.setPos(double4, double5, double6);
    }
    
    @Override
    public void lerpMotion(final double double1, final double double2, final double double3) {
        this.setDeltaMovement(double1, double2, double3);
        if (this.xRotO == 0.0f && this.yRotO == 0.0f) {
            final float float8 = Mth.sqrt(double1 * double1 + double3 * double3);
            this.xRot = (float)(Mth.atan2(double2, float8) * 57.2957763671875);
            this.yRot = (float)(Mth.atan2(double1, double3) * 57.2957763671875);
            this.xRotO = this.xRot;
            this.yRotO = this.yRot;
            this.moveTo(this.getX(), this.getY(), this.getZ(), this.yRot, this.xRot);
        }
    }
    
    @Override
    public void shoot(final double double1, final double double2, final double double3, final float float4, final float float5) {
        final Vec3 cvl10 = new Vec3(double1, double2, double3).normalize().add(this.random.nextGaussian() * 0.007499999832361937 * float5, this.random.nextGaussian() * 0.007499999832361937 * float5, this.random.nextGaussian() * 0.007499999832361937 * float5).scale(float4);
        this.setDeltaMovement(cvl10);
        final float float6 = Mth.sqrt(Entity.getHorizontalDistanceSqr(cvl10));
        this.yRot = (float)(Mth.atan2(cvl10.x, double3) * 57.2957763671875);
        this.xRot = (float)(Mth.atan2(cvl10.y, float6) * 57.2957763671875);
        this.yRotO = this.yRot;
        this.xRotO = this.xRot;
    }
    
    public void onHit(final HitResult cvi) {
        final HitResult.Type a3 = cvi.getType();
        if (a3 == HitResult.Type.ENTITY && this.owner != null) {
            ((EntityHitResult)cvi).getEntity().hurt(DamageSource.indirectMobAttack(this, this.owner).setProjectile(), 1.0f);
        }
        else if (a3 == HitResult.Type.BLOCK && !this.level.isClientSide) {
            this.remove();
        }
    }
    
    @Override
    protected void defineSynchedData() {
    }
    
    @Override
    protected void readAdditionalSaveData(final CompoundTag jt) {
        if (jt.contains("Owner", 10)) {
            this.ownerTag = jt.getCompound("Owner");
        }
    }
    
    @Override
    protected void addAdditionalSaveData(final CompoundTag jt) {
        if (this.owner != null) {
            final CompoundTag jt2 = new CompoundTag();
            final UUID uUID4 = this.owner.getUUID();
            jt2.putUUID("OwnerUUID", uUID4);
            jt.put("Owner", jt2);
        }
    }
    
    private void restoreOwnerFromSave() {
        if (this.ownerTag != null && this.ownerTag.hasUUID("OwnerUUID")) {
            final UUID uUID2 = this.ownerTag.getUUID("OwnerUUID");
            final List<Llama> list3 = this.level.<Llama>getEntitiesOfClass(Llama.class, this.getBoundingBox().inflate(15.0));
            for (final Llama auh5 : list3) {
                if (auh5.getUUID().equals(uUID2)) {
                    this.owner = auh5;
                    break;
                }
            }
        }
        this.ownerTag = null;
    }
    
    @Override
    public Packet<?> getAddEntityPacket() {
        return new ClientboundAddEntityPacket(this);
    }
}
