Better protection against mods like FTB Chunks that block explosions from happening causing infinite meltdowns by making sure to remove actual blocks that are part of the reactor instead of potentially removing air positions
package mekanism.common.lib.radiation;
+import java.util.Collections;
+import java.util.List;
import mekanism.common.util.WorldUtils;
-import net.minecraft.block.Blocks;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.Explosion;
import net.minecraft.world.World;
+import net.minecraftforge.event.ForgeEventFactory;
public class Meltdown {
@@ -31,9 +33,14 @@ public class Meltdown {
int x = minPos.getX() + world.rand.nextInt(maxPos.getX() - minPos.getX());
int y = minPos.getY() + world.rand.nextInt(maxPos.getY() - minPos.getY());
int z = minPos.getZ() + world.rand.nextInt(maxPos.getZ() - minPos.getZ());
- if (!createExplosion(world, x, y, z, 8, true, Explosion.Mode.DESTROY)) {
- //If explosion cancelled, just set the position to air to prevent infinite explosion attempts
- world.setBlockState(new BlockPos(x,y,z), Blocks.AIR.getDefaultState());
+ List<BlockPos> needsRemoval = createExplosion(world, x, y, z, 8, true, Explosion.Mode.DESTROY);
+ //If the explosion has blocks that should be removed (aka it got canceled)
+ for (BlockPos pos : needsRemoval) {
+ //And the position is inside our bounds, remove the block to prevent infinite explosion attempts
+ if (minPos.getX() <= pos.getX() && minPos.getY() <= pos.getY() && minPos.getZ() <= pos.getZ() &&
+ pos.getX() <= maxPos.getX() && pos.getY() <= maxPos.getY() && pos.getZ() <= maxPos.getZ()) {
+ world.removeBlock(pos, false);
+ }
}
}
@@ -47,11 +54,13 @@ public class Meltdown {
/**
* Copy of world.createExplosion which we can use to determine if it got cancelled by the Forge event.
*/
- private static boolean createExplosion(World worldIn, double x, double y, double z, float size, boolean causesFire, Explosion.Mode mode) {
+ private static List<BlockPos> createExplosion(World worldIn, double x, double y, double z, float size, boolean causesFire, Explosion.Mode mode) {
Explosion explosion = new Explosion(worldIn, null, null, null, x, y, z, size, causesFire, mode);
- if (net.minecraftforge.event.ForgeEventFactory.onExplosionStart(worldIn, explosion)) return false;
+ if (ForgeEventFactory.onExplosionStart(worldIn, explosion)) {
+ return explosion.getAffectedBlockPositions();
+ }
explosion.doExplosionA();
explosion.doExplosionB(true);
- return true;
+ return Collections.emptyList();
}
}
