EntityItemProjectile.java 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. package me.km.entities;
  2. import java.util.List;
  3. import me.km.KajetansMod;
  4. import me.km.snuviscript.ScriptEvents;
  5. import me.km.utils.ReflectionUtils;
  6. import net.minecraft.entity.Entity;
  7. import net.minecraft.entity.EntityLivingBase;
  8. import net.minecraft.entity.IProjectile;
  9. import net.minecraft.entity.item.EntityItem;
  10. import net.minecraft.entity.player.EntityPlayer;
  11. import net.minecraft.item.ItemStack;
  12. import net.minecraft.util.DamageSource;
  13. import net.minecraft.util.math.AxisAlignedBB;
  14. import net.minecraft.util.math.MathHelper;
  15. import net.minecraft.util.math.Vec3d;
  16. public class EntityItemProjectile extends EntityItem implements IProjectile
  17. {
  18. private final EntityLivingBase thrower;
  19. private boolean noHit;
  20. private final float damage;
  21. public EntityItemProjectile(EntityLivingBase thrower, ItemStack stack, float damage)
  22. {
  23. super(thrower.world, thrower.posX, thrower.posY + thrower.getEyeHeight() - 0.1d, thrower.posZ, stack);
  24. this.thrower = thrower;
  25. this.noHit = true;
  26. super.setInfinitePickupDelay();
  27. this.damage = damage;
  28. }
  29. public EntityItemProjectile(EntityLivingBase thrower, ItemStack stack)
  30. {
  31. this(thrower, stack, -1);
  32. }
  33. public EntityLivingBase getItemThrower()
  34. {
  35. return thrower;
  36. }
  37. public void setHeadingFromThrower(Entity entityThrower, float rotationPitchIn, float rotationYawIn, float pitchOffset, float velocity, float inaccuracy)
  38. {
  39. float f = -MathHelper.sin(rotationYawIn * 0.017453292F) * MathHelper.cos(rotationPitchIn * 0.017453292F);
  40. float f1 = -MathHelper.sin((rotationPitchIn + pitchOffset) * 0.017453292F);
  41. float f2 = MathHelper.cos(rotationYawIn * 0.017453292F) * MathHelper.cos(rotationPitchIn * 0.017453292F);
  42. this.setThrowableHeading(f, f1, f2, velocity, inaccuracy);
  43. this.motionX += entityThrower.motionX;
  44. this.motionZ += entityThrower.motionZ;
  45. if (!entityThrower.onGround)
  46. {
  47. this.motionY += entityThrower.motionY;
  48. }
  49. }
  50. @Override
  51. public void setThrowableHeading(double x, double y, double z, float velocity, float inaccuracy)
  52. {
  53. float f = MathHelper.sqrt(x * x + y * y + z * z);
  54. x = x / (double)f;
  55. y = y / (double)f;
  56. z = z / (double)f;
  57. x = x + this.rand.nextGaussian() * 0.0075d * (double)inaccuracy;
  58. y = y + this.rand.nextGaussian() * 0.0075d * (double)inaccuracy;
  59. z = z + this.rand.nextGaussian() * 0.0075d * (double)inaccuracy;
  60. x = x * (double)velocity;
  61. y = y * (double)velocity;
  62. z = z * (double)velocity;
  63. this.motionX = x;
  64. this.motionY = y;
  65. this.motionZ = z;
  66. float f1 = MathHelper.sqrt(x * x + z * z);
  67. this.rotationYaw = (float)(MathHelper.atan2(x, z) * (180D / Math.PI));
  68. this.rotationPitch = (float)(MathHelper.atan2(y, (double)f1) * (180D / Math.PI));
  69. this.prevRotationYaw = this.rotationYaw;
  70. this.prevRotationPitch = this.rotationPitch;
  71. }
  72. @Override
  73. public void onUpdate()
  74. {
  75. super.onUpdate();
  76. if(noHit)
  77. {
  78. if(this.onGround)
  79. {
  80. noHit = false;
  81. this.setDefaultPickupDelay();
  82. return;
  83. }
  84. float fw = this.width / 2;
  85. float fh = this.height / 2;
  86. List<Entity> list = this.world.getEntitiesWithinAABBExcludingEntity(this, new AxisAlignedBB(prevPosX, prevPosY, prevPosZ, posX, posY, posZ).expand(fw, fh, fw));
  87. if(list.isEmpty())
  88. {
  89. return;
  90. }
  91. double oldX = this.prevPosX;
  92. double oldY = this.prevPosY;
  93. double oldZ = this.prevPosZ;
  94. double newX = this.posX;
  95. double newY = this.posY;
  96. double newZ = this.posZ;
  97. if(oldX < newX)
  98. {
  99. oldX -= fw;
  100. newX += fw;
  101. }
  102. else
  103. {
  104. oldX += fw;
  105. newX -= fw;
  106. }
  107. if(oldY < newY)
  108. {
  109. oldY -= fh;
  110. newY += fh;
  111. }
  112. else
  113. {
  114. oldY += fh;
  115. newY -= fh;
  116. }
  117. if(oldZ < newZ)
  118. {
  119. oldZ -= fw;
  120. newZ += fw;
  121. }
  122. else
  123. {
  124. oldZ += fw;
  125. newZ -= fw;
  126. }
  127. Vec3d oldV = new Vec3d(oldX, oldY, oldZ);
  128. Vec3d newV = new Vec3d(newX, newY, newZ);
  129. list.removeIf(ent ->
  130. {
  131. if(ent == thrower && ReflectionUtils.getAge(this) < 5)
  132. {
  133. return true;
  134. }
  135. return ent.getEntityBoundingBox().calculateIntercept(oldV, newV) == null;
  136. });
  137. if(!list.isEmpty())
  138. {
  139. noHit = false;
  140. this.setDefaultPickupDelay();
  141. onImpact(list);
  142. }
  143. }
  144. }
  145. protected void onImpact(List<Entity> list)
  146. {
  147. if(damage == -1)
  148. {
  149. if(thrower instanceof EntityPlayer)
  150. {
  151. KajetansMod.scripts.getEvent(ScriptEvents.class).onEntityItemProjectileHit((EntityPlayer) thrower, this.getItem(), list);
  152. }
  153. }
  154. else
  155. {
  156. list.forEach(ent -> ent.attackEntityFrom(DamageSource.causeThrownDamage(this, thrower), damage));
  157. }
  158. }
  159. }