package me.km.entities; import java.util.List; import me.km.KajetansMod; import me.km.snuviscript.ScriptEvents; import me.km.utils.ReflectionUtils; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.IProjectile; import net.minecraft.entity.item.EntityItem; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.util.DamageSource; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; public class EntityItemProjectile extends EntityItem implements IProjectile { private final EntityLivingBase thrower; private boolean noHit; private final float damage; public EntityItemProjectile(EntityLivingBase thrower, ItemStack stack, float damage) { super(thrower.world, thrower.posX, thrower.posY + thrower.getEyeHeight() - 0.1d, thrower.posZ, stack); this.thrower = thrower; this.noHit = true; super.setInfinitePickupDelay(); this.damage = damage; } public EntityItemProjectile(EntityLivingBase thrower, ItemStack stack) { this(thrower, stack, -1); } public EntityLivingBase getItemThrower() { return thrower; } public void setHeadingFromThrower(Entity entityThrower, float rotationPitchIn, float rotationYawIn, float pitchOffset, float velocity, float inaccuracy) { float f = -MathHelper.sin(rotationYawIn * 0.017453292F) * MathHelper.cos(rotationPitchIn * 0.017453292F); float f1 = -MathHelper.sin((rotationPitchIn + pitchOffset) * 0.017453292F); float f2 = MathHelper.cos(rotationYawIn * 0.017453292F) * MathHelper.cos(rotationPitchIn * 0.017453292F); this.setThrowableHeading(f, f1, f2, velocity, inaccuracy); this.motionX += entityThrower.motionX; this.motionZ += entityThrower.motionZ; if (!entityThrower.onGround) { this.motionY += entityThrower.motionY; } } @Override public void setThrowableHeading(double x, double y, double z, float velocity, float inaccuracy) { float f = MathHelper.sqrt(x * x + y * y + z * z); x = x / (double)f; y = y / (double)f; z = z / (double)f; x = x + this.rand.nextGaussian() * 0.0075d * (double)inaccuracy; y = y + this.rand.nextGaussian() * 0.0075d * (double)inaccuracy; z = z + this.rand.nextGaussian() * 0.0075d * (double)inaccuracy; x = x * (double)velocity; y = y * (double)velocity; z = z * (double)velocity; this.motionX = x; this.motionY = y; this.motionZ = z; float f1 = MathHelper.sqrt(x * x + z * z); this.rotationYaw = (float)(MathHelper.atan2(x, z) * (180D / Math.PI)); this.rotationPitch = (float)(MathHelper.atan2(y, (double)f1) * (180D / Math.PI)); this.prevRotationYaw = this.rotationYaw; this.prevRotationPitch = this.rotationPitch; } @Override public void onUpdate() { super.onUpdate(); if(noHit) { if(this.onGround) { noHit = false; this.setDefaultPickupDelay(); return; } float fw = this.width / 2; float fh = this.height / 2; List list = this.world.getEntitiesWithinAABBExcludingEntity(this, new AxisAlignedBB(prevPosX, prevPosY, prevPosZ, posX, posY, posZ).expand(fw, fh, fw)); if(list.isEmpty()) { return; } double oldX = this.prevPosX; double oldY = this.prevPosY; double oldZ = this.prevPosZ; double newX = this.posX; double newY = this.posY; double newZ = this.posZ; if(oldX < newX) { oldX -= fw; newX += fw; } else { oldX += fw; newX -= fw; } if(oldY < newY) { oldY -= fh; newY += fh; } else { oldY += fh; newY -= fh; } if(oldZ < newZ) { oldZ -= fw; newZ += fw; } else { oldZ += fw; newZ -= fw; } Vec3d oldV = new Vec3d(oldX, oldY, oldZ); Vec3d newV = new Vec3d(newX, newY, newZ); list.removeIf(ent -> { if(ent == thrower && ReflectionUtils.getAge(this) < 5) { return true; } return ent.getEntityBoundingBox().calculateIntercept(oldV, newV) == null; }); if(!list.isEmpty()) { noHit = false; this.setDefaultPickupDelay(); onImpact(list); } } } protected void onImpact(List list) { if(damage == -1) { if(thrower instanceof EntityPlayer) { KajetansMod.scripts.getEvent(ScriptEvents.class).onEntityItemProjectileHit((EntityPlayer) thrower, this.getItem(), list); } } else { list.forEach(ent -> ent.attackEntityFrom(DamageSource.causeThrownDamage(this, thrower), damage)); } } }