// 
// Decompiled by Procyon v0.6.0
// 

package com.hypixel.hytale.server.core.entity.entities;

import com.hypixel.hytale.server.core.modules.physics.util.PhysicsMath;
import com.hypixel.hytale.component.Store;
import com.hypixel.hytale.server.core.entity.ExplosionConfig;
import com.hypixel.hytale.server.core.universe.world.World;
import com.hypixel.hytale.server.core.universe.world.storage.ChunkStore;
import com.hypixel.hytale.server.core.entity.ExplosionUtils;
import com.hypixel.hytale.component.CommandBuffer;
import com.hypixel.hytale.server.core.entity.Entity;
import com.hypixel.hytale.server.core.modules.entity.damage.DamageSystems;
import com.hypixel.hytale.server.core.modules.entity.damage.DamageCause;
import com.hypixel.hytale.server.core.modules.entity.damage.Damage;
import com.hypixel.hytale.server.core.entity.LivingEntity;
import com.hypixel.hytale.server.core.entity.EntityUtils;
import it.unimi.dsi.fastutil.objects.ObjectList;
import com.hypixel.hytale.server.core.asset.type.particle.config.WorldParticle;
import com.hypixel.hytale.server.core.universe.world.SoundUtil;
import com.hypixel.hytale.protocol.SoundCategory;
import com.hypixel.hytale.server.core.universe.world.ParticleUtil;
import java.util.List;
import com.hypixel.hytale.component.Ref;
import com.hypixel.hytale.component.spatial.SpatialResource;
import com.hypixel.hytale.component.ComponentAccessor;
import com.hypixel.hytale.server.core.modules.entity.component.BoundingBox;
import com.hypixel.hytale.server.core.entity.UUIDComponent;
import com.hypixel.hytale.server.core.modules.physics.component.Velocity;
import com.hypixel.hytale.server.core.modules.entity.component.TransformComponent;
import com.hypixel.hytale.server.core.modules.entity.DespawnComponent;
import com.hypixel.hytale.component.Holder;
import com.hypixel.hytale.math.vector.Vector3f;
import com.hypixel.hytale.server.core.modules.time.TimeResource;
import com.hypixel.hytale.server.core.modules.entity.EntityModule;
import com.hypixel.hytale.component.ComponentType;
import com.hypixel.hytale.math.vector.Vector3d;
import java.util.UUID;
import javax.annotation.Nullable;
import com.hypixel.hytale.server.core.asset.type.projectile.config.Projectile;
import com.hypixel.hytale.server.core.modules.physics.SimplePhysicsProvider;
import javax.annotation.Nonnull;
import com.hypixel.hytale.codec.builder.BuilderCodec;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import com.hypixel.hytale.component.Component;

public class ProjectileComponent implements Component<EntityStore>
{
    @Nonnull
    public static final BuilderCodec<ProjectileComponent> CODEC;
    private static final double DEFAULT_DESPAWN_SECONDS = 60.0;
    private transient SimplePhysicsProvider simplePhysicsProvider;
    private transient String appearance;
    @Nullable
    private transient Projectile projectile;
    private String projectileAssetName;
    private float brokenDamageModifier;
    private double deadTimer;
    private UUID creatorUuid;
    private boolean haveHit;
    private Vector3d lastBouncePosition;
    
    @Nonnull
    public static ComponentType<EntityStore, ProjectileComponent> getComponentType() {
        return EntityModule.get().getProjectileComponentType();
    }
    
    private ProjectileComponent() {
        this.simplePhysicsProvider = new SimplePhysicsProvider(this::bounceHandler, this::impactHandler);
        this.appearance = "Boy";
        this.brokenDamageModifier = 1.0f;
        this.deadTimer = -1.0;
    }
    
    public ProjectileComponent(@Nonnull final String projectileAssetName) {
        this.simplePhysicsProvider = new SimplePhysicsProvider(this::bounceHandler, this::impactHandler);
        this.appearance = "Boy";
        this.brokenDamageModifier = 1.0f;
        this.deadTimer = -1.0;
        this.projectileAssetName = projectileAssetName;
    }
    
    @Nonnull
    public static Holder<EntityStore> assembleDefaultProjectile(@Nonnull final TimeResource time, @Nonnull final String projectileAssetName, @Nonnull final Vector3d position, @Nonnull final Vector3f rotation) {
        if (projectileAssetName.isEmpty()) {
            throw new IllegalArgumentException("No projectile config typeName provided");
        }
        final Holder<EntityStore> holder = EntityStore.REGISTRY.newHolder();
        final ProjectileComponent projectileComponent = new ProjectileComponent(projectileAssetName);
        holder.putComponent(getComponentType(), projectileComponent);
        holder.putComponent(DespawnComponent.getComponentType(), DespawnComponent.despawnInMilliseconds(time, 60000L));
        holder.putComponent(TransformComponent.getComponentType(), new TransformComponent(position.clone(), rotation));
        holder.ensureComponent(Velocity.getComponentType());
        holder.ensureComponent(UUIDComponent.getComponentType());
        return holder;
    }
    
    public boolean initialize() {
        this.projectile = Projectile.getAssetMap().getAsset(this.projectileAssetName);
        if (this.projectile == null) {
            return false;
        }
        final String appearance = this.projectile.getAppearance();
        if (appearance != null && !appearance.isEmpty()) {
            this.appearance = appearance;
        }
        return true;
    }
    
    public void initializePhysics(@Nonnull final BoundingBox boundingBox) {
        this.simplePhysicsProvider.setProvideCharacterCollisions(true);
        this.simplePhysicsProvider.initialize(this.projectile, boundingBox);
    }
    
    public void onProjectileBounce(@Nonnull final Vector3d position, @Nonnull final ComponentAccessor<EntityStore> componentAccessor) {
        final WorldParticle bounceParticles = this.projectile.getBounceParticles();
        if (bounceParticles != null) {
            final SpatialResource<Ref<EntityStore>, EntityStore> playerSpatialResource = componentAccessor.getResource(EntityModule.get().getPlayerSpatialResourceType());
            final ObjectList<Ref<EntityStore>> results = SpatialResource.getThreadLocalReferenceList();
            playerSpatialResource.getSpatialStructure().collect(position, 75.0, results);
            ParticleUtil.spawnParticleEffect(bounceParticles, position, results, componentAccessor);
        }
        SoundUtil.playSoundEvent3d(this.projectile.getBounceSoundEventIndex(), SoundCategory.SFX, position, componentAccessor);
    }
    
    private void onProjectileHitEvent(@Nonnull final Ref<EntityStore> ref, @Nonnull final Vector3d position, @Nonnull final Ref<EntityStore> targetRef, @Nonnull final ComponentAccessor<EntityStore> componentAccessor) {
        final WorldParticle hitParticles = this.projectile.getHitParticles();
        if (hitParticles != null) {
            final SpatialResource<Ref<EntityStore>, EntityStore> playerSpatialResource = componentAccessor.getResource(EntityModule.get().getPlayerSpatialResourceType());
            final ObjectList<Ref<EntityStore>> results = SpatialResource.getThreadLocalReferenceList();
            playerSpatialResource.getSpatialStructure().collect(position, 75.0, results);
            ParticleUtil.spawnParticleEffect(hitParticles, position, results, componentAccessor);
        }
        SoundUtil.playSoundEvent3d(this.projectile.getHitSoundEventIndex(), SoundCategory.SFX, position, componentAccessor);
        final Entity targetEntity = EntityUtils.getEntity(targetRef, componentAccessor);
        if (targetEntity instanceof LivingEntity) {
            final Ref<EntityStore> shooterRef = componentAccessor.getExternalData().getRefFromUUID(this.creatorUuid);
            DamageSystems.executeDamage(targetRef, componentAccessor, new Damage(new Damage.ProjectileSource((shooterRef != null) ? shooterRef : ref, ref), DamageCause.PROJECTILE, this.projectile.getDamage() * this.brokenDamageModifier));
            this.haveHit = true;
        }
        this.deadTimer = this.projectile.getDeadTime();
    }
    
    public boolean consumeDeadTimer(final float dt) {
        if (this.deadTimer < 0.0) {
            return false;
        }
        this.deadTimer -= dt;
        return this.deadTimer <= 0.0;
    }
    
    protected void bounceHandler(@Nonnull final Vector3d position, @Nonnull final ComponentAccessor<EntityStore> componentAccessor) {
        if (this.lastBouncePosition == null) {
            this.lastBouncePosition = new Vector3d(position);
        }
        else {
            if (this.lastBouncePosition.distanceSquaredTo(position) < 0.5) {
                return;
            }
            this.lastBouncePosition.assign(position);
        }
        this.onProjectileBounce(position, componentAccessor);
    }
    
    protected void impactHandler(@Nonnull final Ref<EntityStore> ref, @Nonnull final Vector3d position, @Nullable final Ref<EntityStore> targetRef, @Nonnull final ComponentAccessor<EntityStore> componentAccessor) {
        if (targetRef != null) {
            this.onProjectileHitEvent(ref, position, targetRef, componentAccessor);
        }
        else {
            this.onProjectileMissEvent(position, componentAccessor);
        }
    }
    
    private void onProjectileMissEvent(@Nonnull final Vector3d position, @Nonnull final ComponentAccessor<EntityStore> componentAccessor) {
        final WorldParticle missParticles = this.projectile.getMissParticles();
        if (missParticles != null) {
            final SpatialResource<Ref<EntityStore>, EntityStore> playerSpatialResource = componentAccessor.getResource(EntityModule.get().getPlayerSpatialResourceType());
            final ObjectList<Ref<EntityStore>> results = SpatialResource.getThreadLocalReferenceList();
            playerSpatialResource.getSpatialStructure().collect(position, 75.0, results);
            ParticleUtil.spawnParticleEffect(missParticles, position, results, componentAccessor);
        }
        SoundUtil.playSoundEvent3d(this.projectile.getMissSoundEventIndex(), SoundCategory.SFX, position, componentAccessor);
        this.deadTimer = this.projectile.getDeadTimeMiss();
    }
    
    public void onProjectileDeath(@Nonnull final Ref<EntityStore> ref, @Nonnull final Vector3d position, @Nonnull final CommandBuffer<EntityStore> commandBuffer) {
        final EntityStore entityStore = commandBuffer.getExternalData();
        final World world = entityStore.getWorld();
        final ExplosionConfig explosionConfig = this.projectile.getExplosionConfig();
        if (explosionConfig != null) {
            final Store<ChunkStore> chunkStore = world.getChunkStore().getStore();
            final Ref<EntityStore> creatorRef = entityStore.getRefFromUUID(this.creatorUuid);
            final Damage.ProjectileSource damageSource = new Damage.ProjectileSource((creatorRef != null) ? creatorRef : ref, ref);
            ExplosionUtils.performExplosion(damageSource, position, explosionConfig, ref, commandBuffer, chunkStore);
        }
        if (this.haveHit && !this.projectile.isDeathEffectsOnHit()) {
            return;
        }
        final WorldParticle deathParticles = this.projectile.getDeathParticles();
        if (deathParticles != null) {
            final SpatialResource<Ref<EntityStore>, EntityStore> playerSpatialResource = commandBuffer.getResource(EntityModule.get().getPlayerSpatialResourceType());
            final ObjectList<Ref<EntityStore>> results = SpatialResource.getThreadLocalReferenceList();
            playerSpatialResource.getSpatialStructure().collect(position, 75.0, results);
            ParticleUtil.spawnParticleEffect(deathParticles, position, results, commandBuffer);
        }
        SoundUtil.playSoundEvent3d(this.projectile.getDeathSoundEventIndex(), SoundCategory.SFX, position, commandBuffer);
    }
    
    public void shoot(@Nonnull final Holder<EntityStore> holder, @Nonnull final UUID creatorUuid, double x, double y, double z, final float yaw, final float pitch) {
        this.creatorUuid = creatorUuid;
        this.simplePhysicsProvider.setCreatorId(creatorUuid);
        final Vector3d direction = new Vector3d();
        computeStartOffset(this.projectile.isPitchAdjustShot(), this.projectile.getVerticalCenterShot(), this.projectile.getHorizontalCenterShot(), this.projectile.getDepthShot(), yaw, pitch, direction);
        x += direction.x;
        y += direction.y;
        z += direction.z;
        holder.ensureAndGetComponent(TransformComponent.getComponentType()).setPosition(new Vector3d(x, y, z));
        PhysicsMath.vectorFromAngles(yaw, pitch, direction);
        direction.setLength(this.projectile.getMuzzleVelocity());
        this.simplePhysicsProvider.setVelocity(direction);
    }
    
    public static void computeStartOffset(final boolean pitchAdjust, final double verticalCenterShot, final double horizontalCenterShot, final double depthShot, final float yaw, final float pitch, @Nonnull final Vector3d offset) {
        offset.assign(0.0, 0.0, 0.0);
        if (depthShot != 0.0) {
            PhysicsMath.vectorFromAngles(yaw, pitchAdjust ? pitch : 0.0f, offset);
            offset.setLength(depthShot);
        }
        else {
            offset.assign(0.0, 0.0, 0.0);
        }
        offset.add(horizontalCenterShot * -PhysicsMath.headingZ(yaw), -verticalCenterShot, horizontalCenterShot * PhysicsMath.headingX(yaw));
    }
    
    public boolean isOnGround() {
        return this.simplePhysicsProvider.isOnGround();
    }
    
    @Nullable
    public Projectile getProjectile() {
        return this.projectile;
    }
    
    public String getAppearance() {
        return this.appearance;
    }
    
    public String getProjectileAssetName() {
        return this.projectileAssetName;
    }
    
    public SimplePhysicsProvider getSimplePhysicsProvider() {
        return this.simplePhysicsProvider;
    }
    
    public void applyBrokenPenalty(final float penalty) {
        this.brokenDamageModifier = 1.0f - penalty;
    }
    
    public ProjectileComponent(@Nonnull final ProjectileComponent other) {
        this.simplePhysicsProvider = new SimplePhysicsProvider(this::bounceHandler, this::impactHandler);
        this.appearance = "Boy";
        this.brokenDamageModifier = 1.0f;
        this.deadTimer = -1.0;
        this.simplePhysicsProvider = other.simplePhysicsProvider;
        this.projectileAssetName = other.projectileAssetName;
        this.projectile = other.projectile;
        this.appearance = other.appearance;
        this.deadTimer = other.deadTimer;
        this.creatorUuid = other.creatorUuid;
        this.haveHit = other.haveHit;
        this.brokenDamageModifier = other.brokenDamageModifier;
        this.lastBouncePosition = other.lastBouncePosition;
    }
    
    @Nonnull
    @Override
    public Component<EntityStore> clone() {
        return new ProjectileComponent(this);
    }
    
    static {
        // 
        // This method could not be decompiled.
        // 
        // Original Bytecode:
        // 
        //     2: invokedynamic   BootstrapMethod #2, get:()Ljava/util/function/Supplier;
        //     7: invokestatic    com/hypixel/hytale/codec/builder/BuilderCodec.builder:(Ljava/lang/Class;Ljava/util/function/Supplier;)Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //    10: new             Lcom/hypixel/hytale/codec/KeyedCodec;
        //    13: dup            
        //    14: ldc_w           "ProjectileType"
        //    17: getstatic       com/hypixel/hytale/codec/Codec.STRING:Lcom/hypixel/hytale/codec/codecs/simple/StringCodec;
        //    20: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
        //    23: invokedynamic   BootstrapMethod #3, accept:()Ljava/util/function/BiConsumer;
        //    28: invokedynamic   BootstrapMethod #4, apply:()Ljava/util/function/Function;
        //    33: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.append:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
        //    36: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.add:()Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
        //    39: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //    42: new             Lcom/hypixel/hytale/codec/KeyedCodec;
        //    45: dup            
        //    46: ldc_w           "BrokenDamageModifier"
        //    49: getstatic       com/hypixel/hytale/codec/Codec.FLOAT:Lcom/hypixel/hytale/codec/codecs/simple/FloatCodec;
        //    52: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
        //    55: invokedynamic   BootstrapMethod #5, accept:()Ljava/util/function/BiConsumer;
        //    60: invokedynamic   BootstrapMethod #6, apply:()Ljava/util/function/Function;
        //    65: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.append:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
        //    68: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.add:()Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
        //    71: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //    74: new             Lcom/hypixel/hytale/codec/KeyedCodec;
        //    77: dup            
        //    78: ldc_w           "DeadTimer"
        //    81: getstatic       com/hypixel/hytale/codec/Codec.DOUBLE:Lcom/hypixel/hytale/codec/codecs/simple/DoubleCodec;
        //    84: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
        //    87: invokedynamic   BootstrapMethod #7, accept:()Ljava/util/function/BiConsumer;
        //    92: invokedynamic   BootstrapMethod #8, apply:()Ljava/util/function/Function;
        //    97: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.append:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
        //   100: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.add:()Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
        //   103: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //   106: new             Lcom/hypixel/hytale/codec/KeyedCodec;
        //   109: dup            
        //   110: ldc_w           "CreatorUUID"
        //   113: getstatic       com/hypixel/hytale/codec/Codec.UUID_STRING:Lcom/hypixel/hytale/codec/function/FunctionCodec;
        //   116: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
        //   119: invokedynamic   BootstrapMethod #9, accept:()Ljava/util/function/BiConsumer;
        //   124: invokedynamic   BootstrapMethod #10, apply:()Ljava/util/function/Function;
        //   129: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.append:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
        //   132: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.add:()Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
        //   135: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //   138: new             Lcom/hypixel/hytale/codec/KeyedCodec;
        //   141: dup            
        //   142: ldc_w           "HaveHit"
        //   145: getstatic       com/hypixel/hytale/codec/Codec.BOOLEAN:Lcom/hypixel/hytale/codec/codecs/simple/BooleanCodec;
        //   148: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
        //   151: invokedynamic   BootstrapMethod #11, accept:()Ljava/util/function/BiConsumer;
        //   156: invokedynamic   BootstrapMethod #12, apply:()Ljava/util/function/Function;
        //   161: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.append:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
        //   164: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.add:()Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
        //   167: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //   170: new             Lcom/hypixel/hytale/codec/KeyedCodec;
        //   173: dup            
        //   174: ldc_w           "LastBouncePosition"
        //   177: getstatic       com/hypixel/hytale/math/vector/Vector3d.CODEC:Lcom/hypixel/hytale/codec/builder/BuilderCodec;
        //   180: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
        //   183: invokedynamic   BootstrapMethod #13, accept:()Ljava/util/function/BiConsumer;
        //   188: invokedynamic   BootstrapMethod #14, apply:()Ljava/util/function/Function;
        //   193: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.append:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
        //   196: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.add:()Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
        //   199: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //   202: new             Lcom/hypixel/hytale/codec/KeyedCodec;
        //   205: dup            
        //   206: ldc_w           "SppImpacted"
        //   209: getstatic       com/hypixel/hytale/codec/Codec.BOOLEAN:Lcom/hypixel/hytale/codec/codecs/simple/BooleanCodec;
        //   212: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
        //   215: invokedynamic   BootstrapMethod #15, accept:()Ljava/util/function/BiConsumer;
        //   220: invokedynamic   BootstrapMethod #16, apply:()Ljava/util/function/Function;
        //   225: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.append:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
        //   228: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.add:()Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
        //   231: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //   234: new             Lcom/hypixel/hytale/codec/KeyedCodec;
        //   237: dup            
        //   238: ldc_w           "SppResting"
        //   241: getstatic       com/hypixel/hytale/codec/Codec.BOOLEAN:Lcom/hypixel/hytale/codec/codecs/simple/BooleanCodec;
        //   244: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
        //   247: invokedynamic   BootstrapMethod #17, accept:()Ljava/util/function/BiConsumer;
        //   252: invokedynamic   BootstrapMethod #18, apply:()Ljava/util/function/Function;
        //   257: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.append:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
        //   260: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.add:()Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
        //   263: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //   266: new             Lcom/hypixel/hytale/codec/KeyedCodec;
        //   269: dup            
        //   270: ldc_w           "SppVelocity"
        //   273: getstatic       com/hypixel/hytale/math/vector/Vector3d.CODEC:Lcom/hypixel/hytale/codec/builder/BuilderCodec;
        //   276: invokespecial   com/hypixel/hytale/codec/KeyedCodec.<init>:(Ljava/lang/String;Lcom/hypixel/hytale/codec/Codec;)V
        //   279: invokedynamic   BootstrapMethod #19, accept:()Ljava/util/function/BiConsumer;
        //   284: invokedynamic   BootstrapMethod #20, apply:()Ljava/util/function/Function;
        //   289: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.append:(Lcom/hypixel/hytale/codec/KeyedCodec;Ljava/util/function/BiConsumer;Ljava/util/function/Function;)Lcom/hypixel/hytale/codec/builder/BuilderField$FieldBuilder;
        //   292: invokevirtual   com/hypixel/hytale/codec/builder/BuilderField$FieldBuilder.add:()Lcom/hypixel/hytale/codec/builder/BuilderCodec$BuilderBase;
        //   295: checkcast       Lcom/hypixel/hytale/codec/builder/BuilderCodec$Builder;
        //   298: invokevirtual   com/hypixel/hytale/codec/builder/BuilderCodec$Builder.build:()Lcom/hypixel/hytale/codec/builder/BuilderCodec;
        //   301: putstatic       com/hypixel/hytale/server/core/entity/entities/ProjectileComponent.CODEC:Lcom/hypixel/hytale/codec/builder/BuilderCodec;
        //   304: return         
        // 
        // The error that occurred was:
        // 
        // java.lang.UnsupportedOperationException: The requested operation is not supported.
        //     at com.strobel.util.ContractUtils.unsupported(ContractUtils.java:27)
        //     at com.strobel.assembler.metadata.TypeReference.getRawType(TypeReference.java:284)
        //     at com.strobel.assembler.metadata.TypeReference.getRawType(TypeReference.java:279)
        //     at com.strobel.assembler.metadata.TypeReference.makeGenericType(TypeReference.java:154)
        //     at com.strobel.assembler.metadata.TypeSubstitutionVisitor.visitClassType(TypeSubstitutionVisitor.java:267)
        //     at com.strobel.assembler.metadata.TypeSubstitutionVisitor.visitClassType(TypeSubstitutionVisitor.java:25)
        //     at com.strobel.assembler.metadata.TypeDefinition.accept(TypeDefinition.java:189)
        //     at com.strobel.assembler.metadata.TypeSubstitutionVisitor.visit(TypeSubstitutionVisitor.java:40)
        //     at com.strobel.assembler.metadata.TypeSubstitutionVisitor.visitMethod(TypeSubstitutionVisitor.java:324)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2586)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:790)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2689)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1510)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:790)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2689)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:790)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2689)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1510)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:790)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2689)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:790)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2689)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1510)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:790)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2689)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:790)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2689)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1510)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:790)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2689)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:790)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2689)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1510)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:790)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2689)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2483)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1510)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2483)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2483)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1510)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2483)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2483)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1510)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferCall(TypeAnalysis.java:2483)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1040)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:782)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:778)
        //     at com.strobel.decompiler.ast.TypeAnalysis.doInferTypeForExpression(TypeAnalysis.java:1083)
        //     at com.strobel.decompiler.ast.TypeAnalysis.inferTypeForExpression(TypeAnalysis.java:815)
        //     at com.strobel.decompiler.ast.TypeAnalysis.runInference(TypeAnalysis.java:684)
        //     at com.strobel.decompiler.ast.TypeAnalysis.runInference(TypeAnalysis.java:667)
        //     at com.strobel.decompiler.ast.TypeAnalysis.runInference(TypeAnalysis.java:373)
        //     at com.strobel.decompiler.ast.TypeAnalysis.run(TypeAnalysis.java:95)
        //     at com.strobel.decompiler.ast.AstOptimizer.optimize(AstOptimizer.java:344)
        //     at com.strobel.decompiler.ast.AstOptimizer.optimize(AstOptimizer.java:42)
        //     at com.strobel.decompiler.languages.java.ast.AstMethodBodyBuilder.createMethodBody(AstMethodBodyBuilder.java:206)
        //     at com.strobel.decompiler.languages.java.ast.AstMethodBodyBuilder.createMethodBody(AstMethodBodyBuilder.java:93)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createMethodBody(AstBuilder.java:868)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createMethod(AstBuilder.java:761)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.addTypeMembers(AstBuilder.java:638)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createTypeCore(AstBuilder.java:605)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createTypeNoCache(AstBuilder.java:195)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.createType(AstBuilder.java:162)
        //     at com.strobel.decompiler.languages.java.ast.AstBuilder.addType(AstBuilder.java:137)
        //     at com.strobel.decompiler.languages.java.JavaLanguage.buildAst(JavaLanguage.java:71)
        //     at com.strobel.decompiler.languages.java.JavaLanguage.decompileType(JavaLanguage.java:59)
        //     at com.strobel.decompiler.DecompilerDriver.decompileType(DecompilerDriver.java:333)
        //     at com.strobel.decompiler.DecompilerDriver.decompileJar(DecompilerDriver.java:254)
        //     at com.strobel.decompiler.DecompilerDriver.main(DecompilerDriver.java:129)
        // 
        throw new IllegalStateException("An error occurred while decompiling this method.");
    }
}
