|
@@ -0,0 +1,94 @@
|
|
|
|
+package me.km.utils;
|
|
|
|
+
|
|
|
|
+import com.google.common.collect.Sets;
|
|
|
|
+import java.util.Set;
|
|
|
|
+import net.minecraft.block.BlockState;
|
|
|
|
+import net.minecraft.entity.Entity;
|
|
|
|
+import net.minecraft.fluid.IFluidState;
|
|
|
|
+import net.minecraft.util.math.BlockPos;
|
|
|
|
+import net.minecraft.util.math.Vec3d;
|
|
|
|
+import net.minecraft.world.Explosion;
|
|
|
|
+import net.minecraft.world.World;
|
|
|
|
+
|
|
|
|
+public class ExplosionUtils
|
|
|
|
+{
|
|
|
|
+ public static void explosion(Explosion ex, World w)
|
|
|
|
+ {
|
|
|
|
+ ex.getAffectedBlockPositions().clear();
|
|
|
|
+
|
|
|
|
+ ReflectionUtils.setNoBreakMode(ex);
|
|
|
|
+ Vec3d pos = ex.getPosition();
|
|
|
|
+
|
|
|
|
+ Entity exploder = ReflectionUtils.getExploder(ex);
|
|
|
|
+ float size = ReflectionUtils.getSize(ex);
|
|
|
|
+
|
|
|
|
+ ex.getAffectedBlockPositions().addAll(getAffectedBlocks(ex, w, size, pos.x, pos.y, pos.z, exploder));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private static Set<BlockPos> getAffectedBlocks(Explosion ex, World w, float size, double x, double y, double z, Entity exploder)
|
|
|
|
+ {
|
|
|
|
+ Set<BlockPos> set = Sets.newHashSet();
|
|
|
|
+ for(int j = 0; j < 16; ++j)
|
|
|
|
+ {
|
|
|
|
+ for(int k = 0; k < 16; ++k)
|
|
|
|
+ {
|
|
|
|
+ for(int l = 0; l < 16; ++l)
|
|
|
|
+ {
|
|
|
|
+ if(j == 0 || j == 15 || k == 0 || k == 15 || l == 0 || l == 15)
|
|
|
|
+ {
|
|
|
|
+ // calc direction vector
|
|
|
|
+ double dirX = j / 7.5 - 1.0;
|
|
|
|
+ double dirY = k / 7.5 - 1.0;
|
|
|
|
+ double dirZ = l / 7.5 - 1.0;
|
|
|
|
+ double dirLength = Math.sqrt(dirX * dirX + dirY * dirY + dirZ * dirZ);
|
|
|
|
+ dirX /= dirLength;
|
|
|
|
+ dirY /= dirLength;
|
|
|
|
+ dirZ /= dirLength;
|
|
|
|
+ // scale to the right size, moved outside of the loop
|
|
|
|
+ dirX *= 0.3;
|
|
|
|
+ dirY *= 0.3;
|
|
|
|
+ dirZ *= 0.3;
|
|
|
|
+
|
|
|
|
+ float strength = size * (0.7f + w.rand.nextFloat() * 0.6f);
|
|
|
|
+ double currentX = x;
|
|
|
|
+ double currentY = y;
|
|
|
|
+ double currentZ = z;
|
|
|
|
+
|
|
|
|
+ for(; strength > 0.0f; strength -= 0.225f)
|
|
|
|
+ {
|
|
|
|
+ BlockPos pos = new BlockPos(currentX, currentY, currentZ);
|
|
|
|
+ BlockState state = w.getBlockState(pos);
|
|
|
|
+ IFluidState fState = w.getFluidState(pos);
|
|
|
|
+ if(!state.isAir(w, pos) || !fState.isEmpty())
|
|
|
|
+ {
|
|
|
|
+ float resistance = Math.max(state.getExplosionResistance(w, pos, exploder, ex), fState.getExplosionResistance(w, pos, exploder, ex));
|
|
|
|
+ if(exploder != null)
|
|
|
|
+ {
|
|
|
|
+ resistance = exploder.getExplosionResistance(ex, w, pos, state, fState, resistance);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // make explosives stronger, keep strong resistance but lower low resistance
|
|
|
|
+ if(resistance <= 10)
|
|
|
|
+ {
|
|
|
|
+ resistance = Math.min(resistance, 1.0f);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ strength -= (resistance + 0.3F) * 0.3F;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if(strength > 0.0F && (exploder == null || exploder.canExplosionDestroyBlock(ex, w, pos, state, strength)))
|
|
|
|
+ {
|
|
|
|
+ set.add(pos);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ currentX += dirX;
|
|
|
|
+ currentY += dirY;
|
|
|
|
+ currentZ += dirZ;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return set;
|
|
|
|
+ }
|
|
|
|
+}
|