diff --git a/common/src/main/java/common/block/Block.java b/common/src/main/java/common/block/Block.java index cc878c5d..f5a627f8 100755 --- a/common/src/main/java/common/block/Block.java +++ b/common/src/main/java/common/block/Block.java @@ -791,8 +791,8 @@ public class Block { return 10; } - public float getResistance(Entity exploder) { - return this.resistance / 5.0F; + public final float getResistance() { + return this.resistance; } public boolean canPlace(World world, BlockPos pos, Facing side) { diff --git a/common/src/main/java/common/block/tech/BlockTNT.java b/common/src/main/java/common/block/tech/BlockTNT.java index e770bdba..8869cd82 100755 --- a/common/src/main/java/common/block/tech/BlockTNT.java +++ b/common/src/main/java/common/block/tech/BlockTNT.java @@ -59,7 +59,7 @@ public class BlockTNT extends Block { if (!worldIn.client) { - EntityTnt entitytntprimed = new EntityTnt(worldIn, (double)((float)pos.getX() + 0.5F), (double)pos.getY(), (double)((float)pos.getZ() + 0.5F), explosionIn.getExplosivePlacedBy(), this.power); + EntityTnt entitytntprimed = new EntityTnt(worldIn, (double)((float)pos.getX() + 0.5F), (double)pos.getY(), (double)((float)pos.getZ() + 0.5F), explosionIn == null ? null : explosionIn.getExplosivePlacedBy(), this.power); entitytntprimed.fuse = worldIn.rand.zrange(entitytntprimed.fuse / 4) + entitytntprimed.fuse / 8; worldIn.spawnEntityInWorld(entitytntprimed); } diff --git a/common/src/main/java/common/entity/Entity.java b/common/src/main/java/common/entity/Entity.java index 0bf2d763..41107b5f 100755 --- a/common/src/main/java/common/entity/Entity.java +++ b/common/src/main/java/common/entity/Entity.java @@ -2276,19 +2276,6 @@ public abstract class Entity return this; } - /** - * Explosion resistance of a block relative to this entity - */ - public float getExplosionResistance(Explosion explosionIn, World worldIn, BlockPos pos, State blockStateIn) - { - return blockStateIn.getBlock().getResistance(this); - } - - public boolean verifyExplosion(Explosion explosionIn, World worldIn, BlockPos pos, State blockStateIn, float p_174816_5_) - { - return true; - } - /** * The maximum height from where the entity is alowed to jump (used in pathfinder) */ diff --git a/common/src/main/java/common/entity/item/EntityExplosion.java b/common/src/main/java/common/entity/item/EntityExplosion.java index 18e5a34c..a626ac74 100755 --- a/common/src/main/java/common/entity/item/EntityExplosion.java +++ b/common/src/main/java/common/entity/item/EntityExplosion.java @@ -62,7 +62,7 @@ public class EntityExplosion extends Entity private boolean explode(double min) { - this.iteration = Explosion.doExplosionAlgo3(this.worldObj, this.posX, this.posY, this.posZ, this.rand, min + 6.0d, min, this.iteration, Vars.maxExplosionIters); + this.iteration = Explosion.doPartial(this.worldObj, this.posX, this.posY, this.posZ, this.rand, min + 6.0d, min, this.iteration, Vars.maxExplosionIters); return this.iteration == 0; } diff --git a/common/src/main/java/common/entity/item/EntityTntCart.java b/common/src/main/java/common/entity/item/EntityTntCart.java index 6da24992..1a807563 100755 --- a/common/src/main/java/common/entity/item/EntityTntCart.java +++ b/common/src/main/java/common/entity/item/EntityTntCart.java @@ -140,15 +140,6 @@ public class EntityTntCart extends EntityCart { return this.minecartTNTFuse > -1; } - public float getExplosionResistance(Explosion explosionIn, World worldIn, BlockPos pos, State blockStateIn) { - return !this.isIgnited() || !BlockRail.isRailBlock(blockStateIn) && !BlockRail.isRailBlock(worldIn, pos.up()) ? super.getExplosionResistance(explosionIn, worldIn, pos, blockStateIn) : 0.0F; - } - - public boolean verifyExplosion(Explosion explosionIn, World worldIn, BlockPos pos, State blockStateIn, float p_174816_5_) { - return !this.isIgnited() || !BlockRail.isRailBlock(blockStateIn) && !BlockRail.isRailBlock(worldIn, pos.up()) ? super.verifyExplosion(explosionIn, worldIn, pos, blockStateIn, p_174816_5_) - : false; - } - protected void readEntity(TagObject tagCompund) { super.readEntity(tagCompund); this.minecartTNTFuse = tagCompund.getInt("TNTFuse"); diff --git a/common/src/main/java/common/world/Explosion.java b/common/src/main/java/common/world/Explosion.java index 922628dd..10930014 100755 --- a/common/src/main/java/common/world/Explosion.java +++ b/common/src/main/java/common/world/Explosion.java @@ -53,10 +53,7 @@ public class Explosion return table; } - /** whether or not the explosion sets fire to blocks around it */ private final boolean isFlaming; - - /** whether or not this explosion spawns smoke particles */ private final boolean isSmoking; private final Random explosionRNG; private final World worldObj; @@ -70,12 +67,7 @@ public class Explosion public Explosion(World worldIn, Entity entityIn, double x, double y, double z, float size, List affectedPositions) { - this(worldIn, entityIn, x, y, z, size, false, true, affectedPositions); - } - - public Explosion(World worldIn, Entity entityIn, double x, double y, double z, float size, boolean flaming, boolean smoking, List affectedPositions) - { - this(worldIn, entityIn, x, y, z, size, flaming, smoking); + this(worldIn, entityIn, x, y, z, size, false, true); this.affectedBlockPositions.addAll(affectedPositions); } @@ -94,9 +86,65 @@ public class Explosion this.isSmoking = smoking; } - public void doExplosionAlgo2(Set set) + public static int doPartial(World world, double explosionX, double explosionY, double explosionZ, Random rand, double radius, double minDist, int iter, int max) { - int d = ((int)this.explosionSize) + 1; + int d = ((int)radius) + 1; + int div = d * 2 + 1; + int[] table = getTable(div); + if(table == null) + return 0; + double falloff = radius * 0.125d; + falloff = falloff > 4.0d ? 4.0d : falloff; + int lmt = div * div * div; + int cnt = 0; + for(; iter < lmt && cnt < max; iter++) + { + int x = table[(iter / div) % div] - d; + int y = table[iter % div] - d; + int z = table[(iter / div) / div] - d; + double dist = (double)ExtMath.sqrtd(((double)x) * ((double)x) + ((double)y) * ((double)y) + ((double)z) * ((double)z)); + if(dist > minDist && (dist < radius - falloff || + (dist < radius && rand.doublev() + ((dist - (radius - falloff)) / falloff) < 1.0d))) { + BlockPos pos = new BlockPos(explosionX + x, explosionY + y, explosionZ + z); + State state = world.getState(pos); + if(state.getBlock() != Blocks.air && (float)radius - (state.getBlock().getResistance() / 5.0F + 0.3F) * 0.3F > 0.0f) { + if(state.getBlock().canDrop(null)) + state.getBlock().drop(world, pos, state, 1.0F / (float)radius, 0); + world.setState(pos, Blocks.air.getState(), radius < 40.0 ? 2 : 10); + state.getBlock().onDestroyedExplosion(world, pos, null, state); + if(rand.chance(1000)) { + world.sendSound(SoundEvent.EXPLODE, explosionX + x, explosionY + y, explosionZ + z, 4.0F); + ((AWorldServer)world).spawnParticles(ParticleType.EXPLOSION_HUGE, explosionX + x, explosionY + y, explosionZ + z); + } + } + cnt++; + } + } + + if(world.client || Vars.damageExplosion) { + List list = world.getEntitiesWithinAABB(Entity.class, new BoundingBox(explosionX - (5.0 + (double)d), explosionY - (5.0 + (double)d), + explosionZ - (5.0 + (double)d), explosionX + 5.0 + (double)d, explosionY + 5.0 + (double)d, explosionZ + 5.0 + (double)d)); + + for (Entity entity : list) + { + if (!entity.isImmuneToExplosions()) + { + double dist = (double)ExtMath.sqrtd((entity.posX - explosionX) * (entity.posX - explosionX) + + (entity.posY - explosionY) * (entity.posY - explosionY) + (entity.posZ - explosionZ) * (entity.posZ - explosionZ)); + if((dist > minDist - 5.0) && (dist < radius + 5.0)) { + entity.attackEntityFrom(DamageSource.causeExplosionDamage(null), 10000); + } + } + } + } + + return iter >= lmt ? 0 : iter; + } + + public void doExplosionA() + { + Set set = Sets.newHashSet(); + int d = ((int)this.explosionSize) + 1; double falloff = this.explosionSize * 0.125d; falloff = falloff > 4.0d ? 4.0d : falloff; for (int x = -d; x <= d; ++x) @@ -108,93 +156,16 @@ public class Explosion double dist = (double)ExtMath.sqrtd(((double)x) * ((double)x) + ((double)y) * ((double)y) + ((double)z) * ((double)z)); if(dist < this.explosionSize - falloff || (dist < this.explosionSize && this.explosionRNG.doublev() + ((dist - (this.explosionSize - falloff)) / falloff) < 1.0d)) { - BlockPos blockpos = new BlockPos(this.explosionX + x, this.explosionY + y, this.explosionZ + z); - State iblockstate = this.worldObj.getState(blockpos); - - float f = this.explosionSize; // * (0.7F + this.worldObj.rand.nextFloat() * 0.6F); - if (iblockstate.getBlock() != Blocks.air) - { - float f2 = this.exploder != null ? this.exploder.getExplosionResistance(this, this.worldObj, blockpos, iblockstate) : iblockstate.getBlock().getResistance((Entity)null); - f -= (f2 + 0.3F) * 0.3F; - } - - if (f > 0.0F && (this.exploder == null || this.exploder.verifyExplosion(this, this.worldObj, blockpos, iblockstate, f))) - { - set.add(blockpos); - } + BlockPos pos = new BlockPos(this.explosionX + x, this.explosionY + y, this.explosionZ + z); + State state = this.worldObj.getState(pos); + if(state.getBlock() != Blocks.air && this.explosionSize - (state.getBlock().getResistance() / 5.0F + 0.3F) * 0.3F > 0.0F) + set.add(pos); } } } } - } - - public static int doExplosionAlgo3(World worldObj, double explosionX, double explosionY, double explosionZ, Random rand, double explosionSize, double minDist, int iter, int max) - { - int d = ((int)explosionSize) + 1; - int div = d * 2 + 1; - int[] table = getTable(div); - if(table == null) - return 0; - double falloff = explosionSize * 0.125d; - falloff = falloff > 4.0d ? 4.0d : falloff; - int lmt = div * div * div; - int cnt = 0; - for(; iter < lmt && cnt < max; iter++) - { - int x = table[(iter / div) % div] - d; - int y = table[iter % div] - d; - int z = table[(iter / div) / div] - d; - double dist = (double)ExtMath.sqrtd(((double)x) * ((double)x) + ((double)y) * ((double)y) + ((double)z) * ((double)z)); - if(dist > minDist && (dist < explosionSize - falloff || - (dist < explosionSize && rand.doublev() + ((dist - (explosionSize - falloff)) / falloff) < 1.0d))) { - BlockPos blockpos = new BlockPos(explosionX + x, explosionY + y, explosionZ + z); - State iblockstate = worldObj.getState(blockpos); - float f = (float)explosionSize; - if(iblockstate.getBlock() != Blocks.air) { - float f2 = iblockstate.getBlock().getResistance(null); - f -= (f2 + 0.3F) * 0.3F; - if(f > 0.0f) { - worldObj.setState(blockpos, Blocks.air.getState(), 10); - if(rand.chance(1000)) { - worldObj.sendSound(SoundEvent.EXPLODE, explosionX + x, explosionY + y, explosionZ + z, 4.0F); - ((AWorldServer)worldObj).spawnParticles(ParticleType.EXPLOSION_HUGE, explosionX + x, explosionY + y, explosionZ + z); - } - } - } - cnt++; - } - } - - if(worldObj.client || Vars.damageExplosion) { - List list = worldObj.getEntitiesWithinAABB(Entity.class, new BoundingBox(explosionX - (5.0 + (double)d), explosionY - (5.0 + (double)d), - explosionZ - (5.0 + (double)d), explosionX + 5.0 + (double)d, explosionY + 5.0 + (double)d, explosionZ + 5.0 + (double)d)); - - for (Entity entity : list) - { - if (!entity.isImmuneToExplosions()) - { - double dist = (double)ExtMath.sqrtd((entity.posX - explosionX) * (entity.posX - explosionX) + - (entity.posY - explosionY) * (entity.posY - explosionY) + (entity.posZ - explosionZ) * (entity.posZ - explosionZ)); - if((dist > minDist - 5.0) && (dist < explosionSize + 5.0)) { - entity.attackEntityFrom(DamageSource.causeExplosionDamage(null), 10000); - } - } - } - } - - return iter >= lmt ? 0 : iter; - } - - /** - * Does the first part of the explosion (destroy blocks) - */ - public void doExplosionA() - { - Set set = Sets.newHashSet(); - - this.doExplosionAlgo2(set); - this.affectedBlockPositions.addAll(set); + set.clear(); float f3 = this.explosionSize * 2.0F; int k1 = ExtMath.floord(this.explosionX - (double)f3 - 1.0D); int l1 = ExtMath.floord(this.explosionX + (double)f3 + 1.0D); @@ -204,22 +175,18 @@ public class Explosion int j1 = ExtMath.floord(this.explosionZ + (double)f3 + 1.0D); List list = this.worldObj.getEntitiesWithinAABBExcludingEntity(this.exploder, new BoundingBox((double)k1, (double)i2, (double)j2, (double)l1, (double)i1, (double)j1)); Vec3 vec3 = new Vec3(this.explosionX, this.explosionY, this.explosionZ); - for (int k2 = 0; k2 < list.size(); ++k2) { Entity entity = (Entity)list.get(k2); - if (!entity.isImmuneToExplosions()) { double d12 = entity.getDistance(this.explosionX, this.explosionY, this.explosionZ) / (double)f3; - if (d12 <= 1.0D) { double d5 = entity.posX - this.explosionX; double d7 = entity.posY + (double)entity.getEyeHeight() - this.explosionY; double d9 = entity.posZ - this.explosionZ; double d13 = (double)ExtMath.sqrtd(d5 * d5 + d7 * d7 + d9 * d9); - if (d13 != 0.0D) { d5 = d5 / d13; @@ -233,20 +200,14 @@ public class Explosion entity.motionX += d5 * d11; entity.motionY += d7 * d11; entity.motionZ += d9 * d11; - - if (entity.isPlayer()) // && !((EntityNPC)entity).creative) - { + if (entity.isPlayer()) this.playerKnockbackMap.put((EntityNPC)entity, new Vec3(d5 * d10, d7 * d10, d9 * d10)); - } } } } } } - /** - * Does the second part of the explosion (sound, particles, drop spawn) - */ public void doExplosionB(boolean spawnParticles, boolean altSound) { this.worldObj.sendSound(altSound ? SoundEvent.EXPLODE_ALT : SoundEvent.EXPLODE, this.explosionX, this.explosionY, this.explosionZ, 4.0F); @@ -267,7 +228,7 @@ public class Explosion State state = this.worldObj.getState(blockpos); Block block = state.getBlock(); - if (this.worldObj.client && spawnParticles /* && (this.explosionSize < 40.0F || this.worldObj.rand.chance(1000)) */) + if (this.worldObj.client && spawnParticles) { double d0 = (double)((float)blockpos.getX() + this.worldObj.rand.floatv()); double d1 = (double)((float)blockpos.getY() + this.worldObj.rand.floatv()); @@ -279,9 +240,7 @@ public class Explosion if (!this.worldObj.client && block != Blocks.air) { if (block.canDrop(this)) - { - block.drop(this.worldObj, blockpos, this.worldObj.getState(blockpos), 1.0F / this.explosionSize, 0); - } + block.drop(this.worldObj, blockpos, state, 1.0F / this.explosionSize, 0); this.worldObj.setState(blockpos, Blocks.air.getState(), this.explosionSize < 40.0F ? 2 : 10); block.onDestroyedExplosion(this.worldObj, blockpos, this, state); diff --git a/common/src/main/java/common/world/World.java b/common/src/main/java/common/world/World.java index 6f575975..532f07e4 100755 --- a/common/src/main/java/common/world/World.java +++ b/common/src/main/java/common/world/World.java @@ -1242,11 +1242,11 @@ public abstract class World implements IWorldAccess { return false; } - public Explosion createExplosion(Entity entityIn, double x, double y, double z, float strength, boolean isSmoking) { + public final Explosion createExplosion(Entity entityIn, double x, double y, double z, float strength, boolean isSmoking) { return this.newExplosion(entityIn, x, y, z, strength, false, isSmoking, false); } - public Explosion createAltExplosion(Entity entityIn, double x, double y, double z, float strength, boolean isSmoking) { + public final Explosion createAltExplosion(Entity entityIn, double x, double y, double z, float strength, boolean isSmoking) { return this.newExplosion(entityIn, x, y, z, strength, false, isSmoking, true); } diff --git a/server/src/main/java/server/command/CommandEnvironment.java b/server/src/main/java/server/command/CommandEnvironment.java index efb13627..ed38d860 100644 --- a/server/src/main/java/server/command/CommandEnvironment.java +++ b/server/src/main/java/server/command/CommandEnvironment.java @@ -285,6 +285,7 @@ public class CommandEnvironment { this.registerExecutable(new CommandSeason()); this.registerExecutable(new CommandCamera()); this.registerExecutable(new CommandNocam()); + this.registerExecutable(new CommandExplode()); this.registerExecutable(new CommandSet()); } diff --git a/server/src/main/java/server/command/commands/CommandExplode.java b/server/src/main/java/server/command/commands/CommandExplode.java new file mode 100644 index 00000000..206626c0 --- /dev/null +++ b/server/src/main/java/server/command/commands/CommandExplode.java @@ -0,0 +1,32 @@ +package server.command.commands; + +import common.util.ExtMath; +import common.util.Vec3; +import server.command.Command; +import server.command.CommandEnvironment; +import server.command.Executor; +import server.world.WorldServer; + +public class CommandExplode extends Command { + public CommandExplode() { + super("explode"); + + this.addVector("position", true, false); + this.addWorld("dim", true); + this.setParamsOptional(); + + this.addInt("radius", 'r', 1, 1024, 4); + this.addFlag("ticked", 't'); + this.addFlag("fire", 'f'); + this.addFlag("noblocks", 'n'); + this.addFlag("altsound", 'a'); + } + + public void exec(CommandEnvironment env, Executor exec, Vec3 pos, WorldServer world, int radius, boolean ticked, boolean fire, boolean noblocks, boolean altsound) { + if(ticked) + world.newExplosion(pos.xCoord, pos.yCoord, pos.zCoord, radius); + else + world.newExplosion(null, pos.xCoord, pos.yCoord, pos.zCoord, radius, fire, !noblocks, altsound); + exec.log("Explosion bei %d, %d, %d in %s erzeugt", ExtMath.floord(pos.xCoord), ExtMath.floord(pos.yCoord), ExtMath.floord(pos.zCoord), world.dimension.getDisplay()); + } +}