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 getAffectedBlocks(Explosion ex, World w, float size, double x, double y, double z, Entity exploder) { Set 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; } }