Redid Nuclear blast algorithm

-localized block variable: reduces number of getBlock calls.
-blast code checks blast resistance of block: adds mod compatibility
-added crude shielding model: blast code returns int corresponding to how many blocks are shielded by a blast resistant block. Vertical behavior only
This commit is contained in:
grangerave 2017-12-02 20:17:37 -06:00
parent c379755dfe
commit 4237435a09
2 changed files with 135 additions and 122 deletions

View File

@ -66,7 +66,7 @@ public class ExplosionNukeAdvanced
this.radius = rad; this.radius = rad;
this.radius2 = this.radius * this.radius; this.radius2 = this.radius * this.radius;
this.explosionCoefficient = coefficient; this.explosionCoefficient = Math.min(Math.max((rad + coefficient * (y - 60))/(coefficient*rad), 1/coefficient),1.0f); //scale the coefficient depending on detonation height
this.type = typ; this.type = typ;
this.nlimit = this.radius2 * 4; //How many total columns should be broken (radius ^ 2 is one quadrant, there are 4 quadrants) this.nlimit = this.radius2 * 4; //How many total columns should be broken (radius ^ 2 is one quadrant, there are 4 quadrants)
@ -99,11 +99,13 @@ public class ExplosionNukeAdvanced
if (dist > 0) //check if any blocks have to be broken here if (dist > 0) //check if any blocks have to be broken here
{ {
dist = (int) Math.sqrt(dist); //calculate sphere height at this (x,z) coordinate dist = (int) Math.sqrt(dist); //calculate sphere height at this (x,z) coordinate
for (int y = dist; y > -dist / this.explosionCoefficient; y--) //go from top to bottom to favor light updates for (int y = dist; y > -dist * this.explosionCoefficient; y--) //go from top to bottom to favor light updates
{ {
//this.worldObj.setBlock(this.posX+x, this.posY+y, this.posZ+z, Blocks.air); //set block to air relative to epicenter if(y<8){//only spare blocks that are mostly below epicenter
y-= ExplosionNukeGeneric.destruction(this.worldObj, this.posX + x, this.posY + y, this.posZ + z);//spare blocks below
ExplosionNukeGeneric.destruction(this.worldObj, this.posX + x, this.posY + y, this.posZ + z); }else{//don't spare blocks above epicenter
ExplosionNukeGeneric.destruction(this.worldObj, this.posX + x, this.posY + y, this.posZ + z);
}
} }
} }
} }
@ -114,10 +116,18 @@ public class ExplosionNukeAdvanced
if (dist > 0) if (dist > 0)
{ {
dist = (int) Math.sqrt(dist); dist = (int) Math.sqrt(dist);
for (int y = dist; y > -dist; y--) //int dist0 = (int)Math.sqrt(this.radius2*0.15f - (x * x + z * z));
for (int y = dist; y > -dist * this.explosionCoefficient; y--)
{ {
y-=ExplosionNukeGeneric.vaporDest(this.worldObj, this.posX + x, this.posY + y, this.posZ + z);
ExplosionNukeGeneric.vaporDest(this.worldObj, this.posX + x, this.posY + y, this.posZ + z); /*
if(dist0>0){//skip blocks already in the destruction zone: we will
if(y>=dist0 || y<=-dist0*this.explosionCoefficient){
y-=ExplosionNukeGeneric.vaporDest(this.worldObj, this.posX + x, this.posY + y, this.posZ + z);
}
}else{
y-=ExplosionNukeGeneric.vaporDest(this.worldObj, this.posX + x, this.posY + y, this.posZ + z);
}*/
} }
} }
} }
@ -128,7 +138,7 @@ public class ExplosionNukeAdvanced
if (dist > 0) if (dist > 0)
{ {
dist = (int) Math.sqrt(dist); dist = (int) Math.sqrt(dist);
for (int y = dist; y > -dist; y--) for (int y = dist; y > -dist * this.explosionCoefficient; y--)
{ {
if(radius >= 95) if(radius >= 95)
ExplosionNukeGeneric.wasteDest(this.worldObj, this.posX + x, this.posY + y, this.posZ + z); ExplosionNukeGeneric.wasteDest(this.worldObj, this.posX + x, this.posY + y, this.posZ + z);

View File

@ -4,6 +4,11 @@ import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Random; import java.util.Random;
import net.minecraft.block.Block;
import net.minecraft.block.BlockLiquid;
import net.minecraft.block.BlockSlab;
import net.minecraft.block.BlockStairs;
import net.minecraft.block.material.Material;
import net.minecraft.enchantment.EnchantmentProtection; import net.minecraft.enchantment.EnchantmentProtection;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.EntityLivingBase;
@ -316,73 +321,70 @@ public class ExplosionNukeGeneric {
} }
} }
public static void destruction(World world, int x, int y, int z) { public static int destruction(World world, int x, int y, int z) {
int rand; int rand;
if (!world.isRemote) { if (!world.isRemote) {
if (world.getBlock(x, y, z) != Blocks.bedrock && world.getBlock(x, y, z) != ModBlocks.reinforced_brick Block b = world.getBlock(x,y,z);
&& world.getBlock(x, y, z) != ModBlocks.reinforced_glass if (b.getExplosionResistance(null)>=200f) { //500 is the resistance of liquids
&& world.getBlock(x, y, z) != ModBlocks.reinforced_light //blocks to be spared
&& world.getBlock(x, y, z) != ModBlocks.reinforced_sand int protection = (int)(b.getExplosionResistance(null)/300f);
&& world.getBlock(x, y, z) != ModBlocks.reinforced_lamp_off if (b == ModBlocks.brick_concrete) {
&& world.getBlock(x, y, z) != ModBlocks.reinforced_lamp_on
&& world.getBlock(x, y, z) != ModBlocks.cmb_brick
&& world.getBlock(x, y, z) != ModBlocks.crystal_virus
&& world.getBlock(x, y, z) != ModBlocks.crystal_hardened
&& world.getBlock(x, y, z) != ModBlocks.crystal_pulsar
&& world.getBlock(x, y, z) != ModBlocks.cmb_brick_reinforced
&& !(world.getBlock(x, y, z) instanceof DecoBlockAlt)) {
if (world.getBlock(x, y, z) == ModBlocks.brick_concrete) {
rand = field_149933_a.nextInt(8); rand = field_149933_a.nextInt(8);
if (rand == 0) { if (rand == 0) {
world.setBlock(x, y, z, Blocks.gravel, 0, 3); world.setBlock(x, y, z, Blocks.gravel, 0, 3);
return 0;
} }
} else if (world.getBlock(x, y, z) == ModBlocks.brick_light) { } else if (b == ModBlocks.brick_light) {
rand = field_149933_a.nextInt(2); rand = field_149933_a.nextInt(3);
if (rand == 0) { if (rand == 0) {
world.setBlock(x, y, z, ModBlocks.waste_planks, 0, 3); world.setBlock(x, y, z, ModBlocks.waste_planks, 0, 3);
return 0;
}else if (rand == 1){
world.setBlock(x,y,z,ModBlocks.block_scrap,0,3);
return 0;
} }
} else if (world.getBlock(x, y, z) == ModBlocks.brick_obsidian) { } else if (b == ModBlocks.brick_obsidian) {
rand = field_149933_a.nextInt(20); rand = field_149933_a.nextInt(20);
if (rand == 0) { if (rand == 0) {
world.setBlock(x, y, z, Blocks.obsidian, 0, 3); world.setBlock(x, y, z, Blocks.obsidian, 0, 3);
} }
} else if (world.getBlock(x, y, z) == Blocks.obsidian) { } else if (b == Blocks.obsidian) {
world.setBlock(x, y, z, ModBlocks.gravel_obsidian, 0, 3); world.setBlock(x, y, z, ModBlocks.gravel_obsidian, 0, 3);
} else { return 0;
world.setBlock(x, y, z, Blocks.air, 0, 3); } else if(field_149933_a.nextInt(protection+3)==0){
world.setBlock(x, y, z, ModBlocks.block_scrap,0,3);
} }
return protection;
}else{//otherwise, kill the block!
world.setBlock(x, y, z, Blocks.air,0, 2);
} }
} }
return 0;
} }
public static void vaporDest(World world, int x, int y, int z) { public static int vaporDest(World world, int x, int y, int z) {
if (!world.isRemote) { if (!world.isRemote) {
if (world.getBlock(x, y, z) == Blocks.water || world.getBlock(x, y, z) == Blocks.flowing_water Block b = world.getBlock(x,y,z);
|| world.getBlock(x, y, z) == Blocks.tallgrass || world.getBlock(x, y, z) == Blocks.leaves if (b.getExplosionResistance(null)<0.5f //most light things
|| world.getBlock(x, y, z) == Blocks.leaves2 || world.getBlock(x, y, z) == Blocks.double_plant || b == Blocks.web || b == ModBlocks.red_cable
|| world.getBlock(x, y, z) == Blocks.cactus || world.getBlock(x, y, z) == Blocks.snow_layer || b instanceof BlockLiquid) {
|| world.getBlock(x, y, z) == Blocks.reeds || world.getBlock(x, y, z) == Blocks.glass_pane world.setBlock(x, y, z, Blocks.air,0, 2);
|| world.getBlock(x, y, z) == Blocks.stained_glass_pane || world.getBlock(x, y, z) == Blocks.carrots return 0;
|| world.getBlock(x, y, z) == Blocks.potatoes || world.getBlock(x, y, z) == Blocks.wheat } else if (b.getExplosionResistance(null)<=3.0f && !b.isOpaqueCube()){
|| world.getBlock(x, y, z) == Blocks.ladder || world.getBlock(x, y, z) == Blocks.torch if(b != Blocks.chest && b != Blocks.farmland){
|| world.getBlock(x, y, z) == Blocks.redstone_torch //destroy all medium resistance blocks that aren't chests or farmland
|| world.getBlock(x, y, z) == Blocks.unlit_redstone_torch world.setBlock(x, y, z, Blocks.air,0,2);
|| world.getBlock(x, y, z) == Blocks.redstone_wire return 0;
|| world.getBlock(x, y, z) == Blocks.unpowered_repeater }
|| world.getBlock(x, y, z) == Blocks.powered_repeater
|| world.getBlock(x, y, z) == Blocks.wooden_pressure_plate
|| world.getBlock(x, y, z) == Blocks.stone_pressure_plate
|| world.getBlock(x, y, z) == Blocks.wooden_button || world.getBlock(x, y, z) == Blocks.stone_button
|| world.getBlock(x, y, z) == Blocks.lever || world.getBlock(x, y, z) == Blocks.deadbush
|| world.getBlock(x, y, z) == ModBlocks.red_cable) {
world.setBlock(x, y, z, Blocks.air);
} }
if (world.getBlock(x, y, z).isFlammable(world, x, y, z, ForgeDirection.UP) if (b.isFlammable(world, x, y, z, ForgeDirection.UP)
&& world.getBlock(x, y + 1, z) == Blocks.air) { && world.getBlock(x, y + 1, z) == Blocks.air) {
world.setBlock(x, y + 1, z, Blocks.fire); world.setBlock(x, y + 1, z, Blocks.fire,0,2);
} }
return (int)( b.getExplosionResistance(null)/300f);
} }
return 0;
} }
public static void waste(World world, int x, int y, int z, int radius) { public static void waste(World world, int x, int y, int z, int radius) {
@ -410,21 +412,20 @@ public class ExplosionNukeGeneric {
public static void wasteDest(World world, int x, int y, int z) { public static void wasteDest(World world, int x, int y, int z) {
if (!world.isRemote) { if (!world.isRemote) {
int rand; int rand;
Block b = world.getBlock(x,y,z);
if (world.getBlock(x, y, z) == Blocks.glass || world.getBlock(x, y, z) == Blocks.stained_glass if (b == Blocks.wooden_door || b == Blocks.iron_door) {
|| world.getBlock(x, y, z) == Blocks.wooden_door || world.getBlock(x, y, z) == Blocks.iron_door) { world.setBlock(x, y, z, Blocks.air,0,2);
world.setBlock(x, y, z, Blocks.air);
} }
else if (world.getBlock(x, y, z) == Blocks.grass) { else if (b == Blocks.grass) {
world.setBlock(x, y, z, ModBlocks.waste_earth); world.setBlock(x, y, z, ModBlocks.waste_earth);
} }
else if (world.getBlock(x, y, z) == Blocks.mycelium) { else if (b == Blocks.mycelium) {
world.setBlock(x, y, z, ModBlocks.waste_mycelium); world.setBlock(x, y, z, ModBlocks.waste_mycelium);
} }
else if (world.getBlock(x, y, z) == Blocks.sand) { else if (b == Blocks.sand) {
rand = field_149933_a.nextInt(20); rand = field_149933_a.nextInt(20);
if (rand == 1 && world.getBlockMetadata(x, y, z) == 0) { if (rand == 1 && world.getBlockMetadata(x, y, z) == 0) {
world.setBlock(x, y, z, ModBlocks.waste_trinitite); world.setBlock(x, y, z, ModBlocks.waste_trinitite);
@ -434,15 +435,15 @@ public class ExplosionNukeGeneric {
} }
} }
else if (world.getBlock(x, y, z) == Blocks.clay) { else if (b == Blocks.clay) {
world.setBlock(x, y, z, Blocks.hardened_clay); world.setBlock(x, y, z, Blocks.hardened_clay);
} }
else if (world.getBlock(x, y, z) == Blocks.mossy_cobblestone) { else if (b == Blocks.mossy_cobblestone) {
world.setBlock(x, y, z, Blocks.coal_ore); world.setBlock(x, y, z, Blocks.coal_ore);
} }
else if (world.getBlock(x, y, z) == Blocks.coal_ore) { else if (b == Blocks.coal_ore) {
rand = field_149933_a.nextInt(10); rand = field_149933_a.nextInt(10);
if (rand == 1 || rand == 2 || rand == 3) { if (rand == 1 || rand == 2 || rand == 3) {
world.setBlock(x, y, z, Blocks.diamond_ore); world.setBlock(x, y, z, Blocks.diamond_ore);
@ -452,43 +453,44 @@ public class ExplosionNukeGeneric {
} }
} }
else if (world.getBlock(x, y, z) == Blocks.log || world.getBlock(x, y, z) == Blocks.log2) { else if (b == Blocks.log || b == Blocks.log2) {
world.setBlock(x, y, z, ModBlocks.waste_log); world.setBlock(x, y, z, ModBlocks.waste_log);
} }
else if (world.getBlock(x, y, z) == Blocks.planks) { else if (b == Blocks.brown_mushroom_block) {
if (world.getBlockMetadata(x, y, z) == 10) {
world.setBlock(x, y, z, ModBlocks.waste_log);
} else {
world.setBlock(x, y, z, Blocks.air,0,2);
}
}
else if (b == Blocks.red_mushroom_block) {
if (world.getBlockMetadata(x, y, z) == 10) {
world.setBlock(x, y, z, ModBlocks.waste_log);
} else {
world.setBlock(x, y, z, Blocks.air,0,2);
}
}
else if (b.getMaterial() == Material.wood && b.isOpaqueCube() && b != ModBlocks.waste_log) {
world.setBlock(x, y, z, ModBlocks.waste_planks); world.setBlock(x, y, z, ModBlocks.waste_planks);
} }
else if (world.getBlock(x, y, z) == ModBlocks.ore_uranium) { else if (b == ModBlocks.ore_uranium) {
rand = field_149933_a.nextInt(30); rand = field_149933_a.nextInt(30);
if (rand == 1) { if (rand == 1) {
world.setBlock(x, y, z, ModBlocks.ore_schrabidium); world.setBlock(x, y, z, ModBlocks.ore_schrabidium);
} }
} }
else if (world.getBlock(x, y, z) == ModBlocks.ore_nether_uranium) { else if (b == ModBlocks.ore_nether_uranium) {
rand = field_149933_a.nextInt(30); rand = field_149933_a.nextInt(30);
if (rand == 1) { if (rand == 1) {
world.setBlock(x, y, z, ModBlocks.ore_nether_schrabidium); world.setBlock(x, y, z, ModBlocks.ore_nether_schrabidium);
} }
} }
else if (world.getBlock(x, y, z) == Blocks.brown_mushroom_block) {
if (world.getBlockMetadata(x, y, z) == 10) {
world.setBlock(x, y, z, ModBlocks.waste_log);
} else {
world.setBlock(x, y, z, Blocks.air);
}
}
else if (world.getBlock(x, y, z) == Blocks.red_mushroom_block) {
if (world.getBlockMetadata(x, y, z) == 10) {
world.setBlock(x, y, z, ModBlocks.waste_log);
} else {
world.setBlock(x, y, z, Blocks.air);
}
}
} }
} }
@ -572,7 +574,7 @@ public class ExplosionNukeGeneric {
if (world.getBlockMetadata(x, y, z) == 10) { if (world.getBlockMetadata(x, y, z) == 10) {
world.setBlock(x, y, z, ModBlocks.waste_log); world.setBlock(x, y, z, ModBlocks.waste_log);
} else { } else {
world.setBlock(x, y, z, Blocks.air); world.setBlock(x, y, z, Blocks.air,0,2);
} }
} }
@ -580,7 +582,7 @@ public class ExplosionNukeGeneric {
if (world.getBlockMetadata(x, y, z) == 10) { if (world.getBlockMetadata(x, y, z) == 10) {
world.setBlock(x, y, z, ModBlocks.waste_log); world.setBlock(x, y, z, ModBlocks.waste_log);
} else { } else {
world.setBlock(x, y, z, Blocks.air); world.setBlock(x, y, z, Blocks.air,0,2);
} }
} }
} }
@ -589,52 +591,53 @@ public class ExplosionNukeGeneric {
public static void emp(World world, int x, int y, int z) { public static void emp(World world, int x, int y, int z) {
if (!world.isRemote) { if (!world.isRemote) {
Block b = world.getBlock(x,y,z);
if (world.getTileEntity(x, y, z) != null && (world.getTileEntity(x, y, z) instanceof ISource if (world.getTileEntity(x, y, z) != null && (world.getTileEntity(x, y, z) instanceof ISource
|| world.getTileEntity(x, y, z) instanceof IConsumer || world.getTileEntity(x, y, z) instanceof IConsumer
|| world.getTileEntity(x, y, z) instanceof TileEntityDummy)) { || world.getTileEntity(x, y, z) instanceof TileEntityDummy)) {
world.setBlock(x, y, z, ModBlocks.block_electrical_scrap); world.setBlock(x, y, z, ModBlocks.block_electrical_scrap,0,2);
} }
else if (world.getBlock(x, y, z) == ModBlocks.red_wire_coated || else if (b == ModBlocks.red_wire_coated ||
world.getBlock(x, y, z) == ModBlocks.factory_titanium_furnace || b == ModBlocks.factory_titanium_furnace ||
world.getBlock(x, y, z) == ModBlocks.factory_titanium_conductor || b == ModBlocks.factory_titanium_conductor ||
world.getBlock(x, y, z) == ModBlocks.factory_advanced_furnace || b == ModBlocks.factory_advanced_furnace ||
world.getBlock(x, y, z) == ModBlocks.factory_advanced_conductor || b == ModBlocks.factory_advanced_conductor ||
world.getBlock(x, y, z) == ModBlocks.reactor_conductor || b == ModBlocks.reactor_conductor ||
world.getBlock(x, y, z) == ModBlocks.fusion_conductor || b == ModBlocks.fusion_conductor ||
world.getBlock(x, y, z) == ModBlocks.fusion_center || b == ModBlocks.fusion_center ||
world.getBlock(x, y, z) == ModBlocks.fusion_motor || b == ModBlocks.fusion_motor ||
world.getBlock(x, y, z) == ModBlocks.watz_conductor || b == ModBlocks.watz_conductor ||
world.getBlock(x, y, z) == ModBlocks.fwatz_conductor || b == ModBlocks.fwatz_conductor ||
world.getBlock(x, y, z) == ModBlocks.fwatz_hatch || b == ModBlocks.fwatz_hatch ||
world.getBlock(x, y, z) == ModBlocks.fwatz_computer) { b == ModBlocks.fwatz_computer) {
world.setBlock(x, y, z, ModBlocks.block_electrical_scrap); world.setBlock(x, y, z, ModBlocks.block_electrical_scrap,0,2);
} }
else if (world.getBlock(x, y, z) == ModBlocks.red_cable || else if (b == ModBlocks.red_cable ||
world.getBlock(x, y, z) == Blocks.redstone_wire || b == Blocks.redstone_wire ||
world.getBlock(x, y, z) == Blocks.powered_repeater || b == Blocks.powered_repeater ||
world.getBlock(x, y, z) == Blocks.unpowered_repeater || b == Blocks.unpowered_repeater ||
world.getBlock(x, y, z) == Blocks.activator_rail || b == Blocks.activator_rail ||
world.getBlock(x, y, z) == Blocks.detector_rail || b == Blocks.detector_rail ||
world.getBlock(x, y, z) == Blocks.golden_rail || b == Blocks.golden_rail ||
world.getBlock(x, y, z) == Blocks.redstone_block || b == Blocks.redstone_block ||
world.getBlock(x, y, z) == Blocks.redstone_lamp || b == Blocks.redstone_lamp ||
world.getBlock(x, y, z) == Blocks.redstone_ore || b == Blocks.redstone_ore ||
world.getBlock(x, y, z) == Blocks.redstone_torch || b == Blocks.redstone_torch ||
world.getBlock(x, y, z) == Blocks.unlit_redstone_torch || b == Blocks.unlit_redstone_torch ||
world.getBlock(x, y, z) == Blocks.powered_comparator || b == Blocks.powered_comparator ||
world.getBlock(x, y, z) == Blocks.unpowered_comparator) { b == Blocks.unpowered_comparator) {
world.setBlock(x, y, z, Blocks.air); world.setBlock(x, y, z, Blocks.air,0,2);
} }
else if (world.getBlock(x, y, z) == Blocks.dispenser || else if (b == Blocks.dispenser ||
world.getBlock(x, y, z) == Blocks.dropper || b == Blocks.dropper ||
world.getBlock(x, y, z) == Blocks.piston || b == Blocks.piston ||
world.getBlock(x, y, z) == Blocks.piston_extension || b == Blocks.piston_extension ||
world.getBlock(x, y, z) == Blocks.piston_head || b == Blocks.piston_head ||
world.getBlock(x, y, z) == Blocks.sticky_piston) { b == Blocks.sticky_piston) {
world.setBlock(x, y, z, Blocks.gravel); world.setBlock(x, y, z, Blocks.gravel,0,2);
} }
} }
//world.setBlock(x, y, z, Blocks.air); //world.setBlock(x, y, z, Blocks.air);