123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139 |
- 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.shoot(f, f1, f2, velocity, inaccuracy);
- this.motionX += entityThrower.motionX;
- this.motionZ += entityThrower.motionZ;
- if (!entityThrower.onGround)
- {
- this.motionY += entityThrower.motionY;
- }
- }
-
- @Override
- public void shoot(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<Entity> list = this.world.getEntitiesWithinAABBExcludingEntity(this,
- new AxisAlignedBB(prevPosX, prevPosY, prevPosZ, posX, posY, posZ).expand(fw, fh, fw));
- if(list.isEmpty())
- {
- return;
- }
-
- Vec3d oldV = new Vec3d(this.prevPosX, prevPosY, prevPosZ);
- Vec3d newV = new Vec3d(this.posX, this.posY, this.posZ);
- list.removeIf(ent ->
- {
- // this prevents the projectile from hitting its shooter during
- // the first ticks
- if(ent == thrower && ReflectionUtils.getAge(this) < 5)
- {
- return true;
- }
- // size of the projectile is 0.25 x 0.25
- return ent.getEntityBoundingBox().grow(0.125f).calculateIntercept(oldV, newV) == null;
- });
- if(!list.isEmpty())
- {
- noHit = false;
- this.setDefaultPickupDelay();
- onImpact(list);
- }
- }
- }
- protected void onImpact(List<Entity> list)
- {
- if(damage == -1)
- {
- if(thrower instanceof EntityPlayer)
- {
- KajetansMod.scripts.getEvent(ScriptEvents.class).onEntityItemProjectileHit(this, (EntityPlayer) thrower, this.getItem(), list);
- }
- }
- else
- {
- list.forEach(ent -> ent.attackEntityFrom(DamageSource.causeThrownDamage(this, thrower), damage));
- }
- }
- }
|