package net.minecraft.world.entity.projectile;

import net.minecraft.network.syncher.SynchedEntityData;
import net.minecraft.network.syncher.EntityDataSerializers;
import net.minecraft.nbt.Tag;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.entity.player.Player;
import net.minecraft.core.BlockPos;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.core.Vec3i;
import net.minecraft.world.entity.LightningBolt;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.damagesource.DamageSource;
import javax.annotation.Nullable;
import net.minecraft.world.phys.EntityHitResult;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.Entity;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.world.phys.Vec3;
import net.minecraft.world.item.enchantment.EnchantmentHelper;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.level.ItemLike;
import net.minecraft.world.item.Items;
import net.minecraft.world.level.Level;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.item.ItemStack;
import net.minecraft.network.syncher.EntityDataAccessor;

public class ThrownTrident extends AbstractArrow {
    private static final EntityDataAccessor<Byte> ID_LOYALTY;
    private static final EntityDataAccessor<Boolean> ID_FOIL;
    private ItemStack tridentItem;
    private boolean dealtDamage;
    public int clientSideReturnTridentTickCount;
    
    public ThrownTrident(final EntityType<? extends ThrownTrident> aoq, final Level bqb) {
        super(aoq, bqb);
        this.tridentItem = new ItemStack(Items.TRIDENT);
    }
    
    public ThrownTrident(final Level bqb, final LivingEntity aoy, final ItemStack bki) {
        super(EntityType.TRIDENT, aoy, bqb);
        this.tridentItem = new ItemStack(Items.TRIDENT);
        this.tridentItem = bki.copy();
        this.entityData.<Byte>set(ThrownTrident.ID_LOYALTY, (byte)EnchantmentHelper.getLoyalty(bki));
        this.entityData.<Boolean>set(ThrownTrident.ID_FOIL, bki.hasFoil());
    }
    
    public ThrownTrident(final Level bqb, final double double2, final double double3, final double double4) {
        super(EntityType.TRIDENT, double2, double3, double4, bqb);
        this.tridentItem = new ItemStack(Items.TRIDENT);
    }
    
    @Override
    protected void defineSynchedData() {
        super.defineSynchedData();
        this.entityData.<Byte>define(ThrownTrident.ID_LOYALTY, (Byte)0);
        this.entityData.<Boolean>define(ThrownTrident.ID_FOIL, false);
    }
    
    @Override
    public void tick() {
        if (this.inGroundTime > 4) {
            this.dealtDamage = true;
        }
        final Entity aom2 = this.getOwner();
        if ((this.dealtDamage || this.isNoPhysics()) && aom2 != null) {
            final int integer3 = this.entityData.<Byte>get(ThrownTrident.ID_LOYALTY);
            if (integer3 > 0 && !this.isAcceptibleReturnOwner()) {
                if (!this.level.isClientSide && this.pickup == Pickup.ALLOWED) {
                    this.spawnAtLocation(this.getPickupItem(), 0.1f);
                }
                this.remove();
            }
            else if (integer3 > 0) {
                this.setNoPhysics(true);
                final Vec3 dem4 = new Vec3(aom2.getX() - this.getX(), aom2.getEyeY() - this.getY(), aom2.getZ() - this.getZ());
                this.setPosRaw(this.getX(), this.getY() + dem4.y * 0.015 * integer3, this.getZ());
                if (this.level.isClientSide) {
                    this.yOld = this.getY();
                }
                final double double5 = 0.05 * integer3;
                this.setDeltaMovement(this.getDeltaMovement().scale(0.95).add(dem4.normalize().scale(double5)));
                if (this.clientSideReturnTridentTickCount == 0) {
                    this.playSound(SoundEvents.TRIDENT_RETURN, 10.0f, 1.0f);
                }
                ++this.clientSideReturnTridentTickCount;
            }
        }
        super.tick();
    }
    
    private boolean isAcceptibleReturnOwner() {
        final Entity aom2 = this.getOwner();
        return aom2 != null && aom2.isAlive() && (!(aom2 instanceof ServerPlayer) || !aom2.isSpectator());
    }
    
    @Override
    protected ItemStack getPickupItem() {
        return this.tridentItem.copy();
    }
    
    public boolean isFoil() {
        return this.entityData.<Boolean>get(ThrownTrident.ID_FOIL);
    }
    
    @Nullable
    @Override
    protected EntityHitResult findHitEntity(final Vec3 dem1, final Vec3 dem2) {
        if (this.dealtDamage) {
            return null;
        }
        return super.findHitEntity(dem1, dem2);
    }
    
    @Override
    protected void onHitEntity(final EntityHitResult dei) {
        final Entity aom3 = dei.getEntity();
        float float4 = 8.0f;
        if (aom3 instanceof LivingEntity) {
            final LivingEntity aoy5 = (LivingEntity)aom3;
            float4 += EnchantmentHelper.getDamageBonus(this.tridentItem, aoy5.getMobType());
        }
        final Entity aom4 = this.getOwner();
        final DamageSource anw6 = DamageSource.trident(this, (aom4 == null) ? this : aom4);
        this.dealtDamage = true;
        SoundEvent ack7 = SoundEvents.TRIDENT_HIT;
        if (aom3.hurt(anw6, float4)) {
            if (aom3.getType() == EntityType.ENDERMAN) {
                return;
            }
            if (aom3 instanceof LivingEntity) {
                final LivingEntity aoy6 = (LivingEntity)aom3;
                if (aom4 instanceof LivingEntity) {
                    EnchantmentHelper.doPostHurtEffects(aoy6, aom4);
                    EnchantmentHelper.doPostDamageEffects((LivingEntity)aom4, aoy6);
                }
                this.doPostHurtEffects(aoy6);
            }
        }
        this.setDeltaMovement(this.getDeltaMovement().multiply(-0.01, -0.1, -0.01));
        float float5 = 1.0f;
        if (this.level instanceof ServerLevel && this.level.isThundering() && EnchantmentHelper.hasChanneling(this.tridentItem)) {
            final BlockPos fu9 = aom3.blockPosition();
            if (this.level.canSeeSky(fu9)) {
                final LightningBolt aox10 = EntityType.LIGHTNING_BOLT.create(this.level);
                aox10.moveTo(Vec3.atBottomCenterOf(fu9));
                aox10.setCause((aom4 instanceof ServerPlayer) ? ((ServerPlayer)aom4) : null);
                this.level.addFreshEntity(aox10);
                ack7 = SoundEvents.TRIDENT_THUNDER;
                float5 = 5.0f;
            }
        }
        this.playSound(ack7, float5, 1.0f);
    }
    
    @Override
    protected SoundEvent getDefaultHitGroundSoundEvent() {
        return SoundEvents.TRIDENT_HIT_GROUND;
    }
    
    @Override
    public void playerTouch(final Player bec) {
        final Entity aom3 = this.getOwner();
        if (aom3 != null && aom3.getUUID() != bec.getUUID()) {
            return;
        }
        super.playerTouch(bec);
    }
    
    @Override
    public void readAdditionalSaveData(final CompoundTag le) {
        super.readAdditionalSaveData(le);
        if (le.contains("Trident", 10)) {
            this.tridentItem = ItemStack.of(le.getCompound("Trident"));
        }
        this.dealtDamage = le.getBoolean("DealtDamage");
        this.entityData.<Byte>set(ThrownTrident.ID_LOYALTY, (byte)EnchantmentHelper.getLoyalty(this.tridentItem));
    }
    
    @Override
    public void addAdditionalSaveData(final CompoundTag le) {
        super.addAdditionalSaveData(le);
        le.put("Trident", this.tridentItem.save(new CompoundTag()));
        le.putBoolean("DealtDamage", this.dealtDamage);
    }
    
    public void tickDespawn() {
        final int integer2 = this.entityData.<Byte>get(ThrownTrident.ID_LOYALTY);
        if (this.pickup != Pickup.ALLOWED || integer2 <= 0) {
            super.tickDespawn();
        }
    }
    
    @Override
    protected float getWaterInertia() {
        return 0.99f;
    }
    
    @Override
    public boolean shouldRender(final double double1, final double double2, final double double3) {
        return true;
    }
    
    static {
        ID_LOYALTY = SynchedEntityData.<Byte>defineId(ThrownTrident.class, EntityDataSerializers.BYTE);
        ID_FOIL = SynchedEntityData.<Boolean>defineId(ThrownTrident.class, EntityDataSerializers.BOOLEAN);
    }
}
