ExplosionUtils.java 3.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. package me.km.utils;
  2. import com.google.common.collect.Sets;
  3. import java.util.Set;
  4. import net.minecraft.block.BlockState;
  5. import net.minecraft.entity.Entity;
  6. import net.minecraft.fluid.IFluidState;
  7. import net.minecraft.util.math.BlockPos;
  8. import net.minecraft.util.math.Vec3d;
  9. import net.minecraft.world.Explosion;
  10. import net.minecraft.world.World;
  11. public class ExplosionUtils {
  12. public static void explosion(Explosion ex, World w) {
  13. ex.getAffectedBlockPositions().clear();
  14. ReflectionUtils.setNoBreakMode(ex);
  15. Vec3d pos = ex.getPosition();
  16. Entity exploder = ReflectionUtils.getExploder(ex);
  17. float size = ReflectionUtils.getSize(ex);
  18. ex.getAffectedBlockPositions().addAll(getAffectedBlocks(ex, w, size, pos.x, pos.y, pos.z, exploder));
  19. }
  20. private static Set<BlockPos> getAffectedBlocks(Explosion ex, World w, float size, double x, double y, double z, Entity exploder) {
  21. Set<BlockPos> set = Sets.newHashSet();
  22. for(int j = 0; j < 16; ++j) {
  23. for(int k = 0; k < 16; ++k) {
  24. for(int l = 0; l < 16; ++l) {
  25. if(j == 0 || j == 15 || k == 0 || k == 15 || l == 0 || l == 15) {
  26. // calc direction vector
  27. double dirX = j / 7.5 - 1.0;
  28. double dirY = k / 7.5 - 1.0;
  29. double dirZ = l / 7.5 - 1.0;
  30. double dirLength = Math.sqrt(dirX * dirX + dirY * dirY + dirZ * dirZ);
  31. dirX /= dirLength;
  32. dirY /= dirLength;
  33. dirZ /= dirLength;
  34. // scale to the right size, moved outside of the loop
  35. dirX *= 0.3;
  36. dirY *= 0.3;
  37. dirZ *= 0.3;
  38. float strength = size * (0.7f + w.rand.nextFloat() * 0.6f);
  39. double currentX = x;
  40. double currentY = y;
  41. double currentZ = z;
  42. for(; strength > 0.0f; strength -= 0.225f) {
  43. BlockPos pos = new BlockPos(currentX, currentY, currentZ);
  44. BlockState state = w.getBlockState(pos);
  45. IFluidState fState = w.getFluidState(pos);
  46. if(!state.isAir(w, pos) || !fState.isEmpty()) {
  47. float resistance = Math.max(state.getExplosionResistance(w, pos, exploder, ex), fState.getExplosionResistance(w, pos, exploder, ex));
  48. if(exploder != null) {
  49. resistance = exploder.getExplosionResistance(ex, w, pos, state, fState, resistance);
  50. }
  51. // make explosives stronger, keep strong resistance but lower low resistance
  52. if(resistance <= 10) {
  53. resistance = Math.min(resistance, 1.0f);
  54. }
  55. strength -= (resistance + 0.3F) * 0.3F;
  56. }
  57. if(strength > 0.0F && (exploder == null || exploder.canExplosionDestroyBlock(ex, w, pos, state, strength))) {
  58. set.add(pos);
  59. }
  60. currentX += dirX;
  61. currentY += dirY;
  62. currentZ += dirZ;
  63. }
  64. }
  65. }
  66. }
  67. }
  68. return set;
  69. }
  70. }