diff --git a/client/src/main/java/client/network/ClientPlayer.java b/client/src/main/java/client/network/ClientPlayer.java index 35d541b6..a59e1f37 100755 --- a/client/src/main/java/client/network/ClientPlayer.java +++ b/client/src/main/java/client/network/ClientPlayer.java @@ -135,7 +135,6 @@ import common.util.ParticleType; import common.util.BlockPos.MutableBlockPos; import common.util.Equipment; import common.village.MerchantRecipeList; -import common.world.Explosion; import common.world.State; import common.world.Weather; import common.world.World; @@ -1046,17 +1045,22 @@ public class ClientPlayer implements IClientPlayer // this.gameController.controller.setCheat(packetIn.getCheat()); } - /** - * Initiates a new explosion (sound, particles, drop spawn) for the affected blocks indicated by the packet. - */ public void handleExplosion(SPacketExplosion packetIn) { NetHandler.checkThread(packetIn, this, this.gm, this.world); - Explosion explosion = new Explosion(this.gm.world, (Entity)null, packetIn.getX(), packetIn.getY(), packetIn.getZ(), packetIn.getStrength(), packetIn.getAffectedBlockPositions()); - explosion.doExplosionB(true, packetIn.hasAltSound()); - this.gm.player.motionX += (double)packetIn.func_149149_c(); - this.gm.player.motionY += (double)packetIn.func_149144_d(); - this.gm.player.motionZ += (double)packetIn.func_149147_e(); + if(packetIn.isLarge()) + this.gm.world.clientParticle(ParticleType.EXPLOSION_HUGE, packetIn.getX(), packetIn.getY(), packetIn.getZ()); + else + this.gm.world.clientParticle(ParticleType.EXPLOSION_LARGE, packetIn.getX(), packetIn.getY(), packetIn.getZ(), 100); + if(packetIn.getBlocks() != null) { + for(BlockPos pos : packetIn.getBlocks()) { + double d0 = (double)((float)pos.getX() + this.gm.world.rand.floatv()); + double d1 = (double)((float)pos.getY() + this.gm.world.rand.floatv()); + double d2 = (double)((float)pos.getZ() + this.gm.world.rand.floatv()); + this.gm.world.clientParticle(ParticleType.EXPLOSION_NORMAL, (d0 + packetIn.getX() * 1.0D) / 2.0D, (d1 + packetIn.getY() * 1.0D) / 2.0D, (d2 + packetIn.getZ() * 1.0D) / 2.0D); + this.gm.world.clientParticle(ParticleType.SMOKE, d0, d1, d2); + } + } } public void handleOpenWindow(SPacketOpenWindow packet) diff --git a/common/src/main/java/common/block/Block.java b/common/src/main/java/common/block/Block.java index f5a627f8..23ceee3d 100755 --- a/common/src/main/java/common/block/Block.java +++ b/common/src/main/java/common/block/Block.java @@ -53,7 +53,6 @@ import common.util.Pair; import common.util.Serverside; import common.util.Color; import common.vars.Vars; -import common.world.Explosion; import common.world.IBlockAccess; import common.world.IWorldAccess; import common.world.State; @@ -826,7 +825,7 @@ public class Block { return true; } - public boolean canDrop(Explosion explosion) { + public boolean canExplosionDrop() { return true; } @@ -897,19 +896,13 @@ public class Block { } } - public final void drop(World world, BlockPos pos, State state, int fortune) { - this.drop(world, pos, state, 1.0F, fortune); - } - - public void drop(World world, BlockPos pos, State state, float chance, int fortune) { + public void drop(World world, BlockPos pos, State state, int fortune) { if(!world.client) { int amount = this.getDropAmount(fortune, world.rand); for(int z = 0; z < amount; z++) { - if(world.rand.floatv() <= chance) { - Item item = this.getDrop(state, world.rand, fortune); - if(item != null) - dropItem(world, pos, new ItemStack(item)); - } + Item item = this.getDrop(state, world.rand, fortune); + if(item != null) + dropItem(world, pos, new ItemStack(item)); } } } @@ -917,7 +910,7 @@ public class Block { public void onDestroyedFire(World world, BlockPos pos, State state) { } - public void onDestroyedExplosion(World world, BlockPos pos, Explosion explosion, State state) { + public void onDestroyedExplosion(World world, BlockPos pos, EntityLiving source, State state) { } public boolean onUse(World world, BlockPos pos, State state, EntityNPC player, Facing side, float hitX, float hitY, float hitZ) { diff --git a/common/src/main/java/common/block/BlockAir.java b/common/src/main/java/common/block/BlockAir.java index 678b31af..cee20e5d 100755 --- a/common/src/main/java/common/block/BlockAir.java +++ b/common/src/main/java/common/block/BlockAir.java @@ -22,7 +22,7 @@ public final class BlockAir extends Block { return false; } - public void drop(World world, BlockPos pos, State state, float chance, int fortune) { + public void drop(World world, BlockPos pos, State state, int fortune) { } public boolean canReplace(World world, BlockPos pos) { diff --git a/common/src/main/java/common/block/artificial/BlockBed.java b/common/src/main/java/common/block/artificial/BlockBed.java index 6b7563ce..0d9c07cd 100755 --- a/common/src/main/java/common/block/artificial/BlockBed.java +++ b/common/src/main/java/common/block/artificial/BlockBed.java @@ -157,9 +157,9 @@ public class BlockBed extends Block implements Rotatable { && !worldIn.getState(pos.up()).getBlock().getMaterial().isSolid(); } - public void drop(World worldIn, BlockPos pos, State state, float chance, int fortune) { + public void drop(World worldIn, BlockPos pos, State state, int fortune) { if(state.getValue(PART) == BlockBed.EnumPartType.FOOT) - super.drop(worldIn, pos, state, chance, 0); + super.drop(worldIn, pos, state, fortune); } public int getMobilityFlag() { diff --git a/common/src/main/java/common/block/foliage/BlockCrops.java b/common/src/main/java/common/block/foliage/BlockCrops.java index 727bc855..4bf25742 100755 --- a/common/src/main/java/common/block/foliage/BlockCrops.java +++ b/common/src/main/java/common/block/foliage/BlockCrops.java @@ -146,9 +146,9 @@ public class BlockCrops extends BlockBush implements IGrowable /** * Spawns this Block's drops into the World as EntityItems. */ - public void drop(World worldIn, BlockPos pos, State state, float chance, int fortune) + public void drop(World worldIn, BlockPos pos, State state, int fortune) { - super.drop(worldIn, pos, state, chance, 0); + super.drop(worldIn, pos, state, fortune); if (!worldIn.client) { diff --git a/common/src/main/java/common/block/foliage/BlockLeaves.java b/common/src/main/java/common/block/foliage/BlockLeaves.java index 85a540e6..5914123f 100755 --- a/common/src/main/java/common/block/foliage/BlockLeaves.java +++ b/common/src/main/java/common/block/foliage/BlockLeaves.java @@ -236,7 +236,7 @@ public class BlockLeaves extends BlockLeavesBase /** * Spawns this Block's drops into the World as EntityItems. */ - public void drop(World worldIn, BlockPos pos, State state, float chance, int fortune) + public void drop(World worldIn, BlockPos pos, State state, int fortune) { if (!worldIn.client) { diff --git a/common/src/main/java/common/block/foliage/BlockPotato.java b/common/src/main/java/common/block/foliage/BlockPotato.java index decbb579..8d123406 100755 --- a/common/src/main/java/common/block/foliage/BlockPotato.java +++ b/common/src/main/java/common/block/foliage/BlockPotato.java @@ -23,9 +23,9 @@ public class BlockPotato extends BlockCrops /** * Spawns this Block's drops into the World as EntityItems. */ - public void drop(World worldIn, BlockPos pos, State state, float chance, int fortune) + public void drop(World worldIn, BlockPos pos, State state, int fortune) { - super.drop(worldIn, pos, state, chance, fortune); + super.drop(worldIn, pos, state, fortune); if (!worldIn.client) { diff --git a/common/src/main/java/common/block/foliage/BlockSoulGrass.java b/common/src/main/java/common/block/foliage/BlockSoulGrass.java index 0360e9d6..727fa928 100755 --- a/common/src/main/java/common/block/foliage/BlockSoulGrass.java +++ b/common/src/main/java/common/block/foliage/BlockSoulGrass.java @@ -50,7 +50,7 @@ public class BlockSoulGrass extends BlockBush { super.tick(worldIn, pos, state, rand); } - public void drop(World worldIn, BlockPos pos, State state, float chance, int fortune) { + public void drop(World worldIn, BlockPos pos, State state, int fortune) { if(!worldIn.client) { int i = 1; diff --git a/common/src/main/java/common/block/foliage/BlockStem.java b/common/src/main/java/common/block/foliage/BlockStem.java index c353f1c3..b13e3e3c 100755 --- a/common/src/main/java/common/block/foliage/BlockStem.java +++ b/common/src/main/java/common/block/foliage/BlockStem.java @@ -94,9 +94,9 @@ public class BlockStem extends BlockBush implements IGrowable /** * Spawns this Block's drops into the World as EntityItems. */ - public void drop(World worldIn, BlockPos pos, State state, float chance, int fortune) + public void drop(World worldIn, BlockPos pos, State state, int fortune) { - super.drop(worldIn, pos, state, chance, fortune); + super.drop(worldIn, pos, state, fortune); if (!worldIn.client) { diff --git a/common/src/main/java/common/block/natural/BlockOre.java b/common/src/main/java/common/block/natural/BlockOre.java index 2d0e2da4..1eca4564 100755 --- a/common/src/main/java/common/block/natural/BlockOre.java +++ b/common/src/main/java/common/block/natural/BlockOre.java @@ -83,17 +83,14 @@ public class BlockOre extends Block } } - public void drop(World worldIn, BlockPos pos, State state, float chance, int fortune) + public void drop(World worldIn, BlockPos pos, State state, int fortune) { if(!worldIn.client && this.smeltItem != null && Vars.cleanCut) { - if (worldIn.rand.floatv() <= chance) - { - dropItem(worldIn, pos, this.smeltItem.copy()); - } + dropItem(worldIn, pos, this.smeltItem.copy()); return; } - super.drop(worldIn, pos, state, chance, fortune); + super.drop(worldIn, pos, state, fortune); if (this.getDrop(state, worldIn.rand, fortune) != this.getItem()) { diff --git a/common/src/main/java/common/block/tech/BlockNuke.java b/common/src/main/java/common/block/tech/BlockNuke.java index 73a7546a..02a7af1b 100755 --- a/common/src/main/java/common/block/tech/BlockNuke.java +++ b/common/src/main/java/common/block/tech/BlockNuke.java @@ -3,14 +3,18 @@ package common.block.tech; import common.block.Block; import common.block.Material; import common.entity.item.EntityNuke; +import common.entity.npc.EntityNPC; +import common.entity.types.EntityLiving; import common.init.Blocks; +import common.init.Items; import common.init.SoundEvent; import common.item.CheatTab; +import common.item.Item; import common.model.Model; import common.model.Model.ModelProvider; import common.util.BlockPos; import common.util.Color; -import common.world.Explosion; +import common.util.Facing; import common.world.State; import common.world.World; @@ -22,7 +26,7 @@ public class BlockNuke extends Block this.setTab(CheatTab.TECHNOLOGY); } - public void onDestroyedExplosion(World worldIn, BlockPos pos, Explosion explosionIn, State prevState) + public void onDestroyedExplosion(World worldIn, BlockPos pos, EntityLiving source, State prevState) { if (!worldIn.client) { @@ -30,17 +34,30 @@ public class BlockNuke extends Block } } - public void explode(World worldIn, BlockPos pos) + public void explode(World worldIn, BlockPos pos, EntityLiving source) { if (!worldIn.client) { - EntityNuke entitytntprimed = new EntityNuke(worldIn, (double)((float)pos.getX() + 0.5F), (double)pos.getY(), (double)((float)pos.getZ() + 0.5F)); - worldIn.spawnEntityInWorld(entitytntprimed); - worldIn.playSoundAtEntity(entitytntprimed, SoundEvent.FUSE, 1.0F); + EntityNuke nuke = new EntityNuke(worldIn, (double)((float)pos.getX() + 0.5F), (double)pos.getY(), (double)((float)pos.getZ() + 0.5F), source); + worldIn.spawnEntityInWorld(nuke); + worldIn.playSoundAtEntity(nuke, SoundEvent.FUSE, 1.0F); } } + + public boolean onUse(World worldIn, BlockPos pos, State state, EntityNPC playerIn, Facing side, float hitX, float hitY, float hitZ) { + if(playerIn.getHeldItem() != null) { + Item item = playerIn.getHeldItem().getItem(); + if(item == Items.charged_powder) { + this.explode(worldIn, pos, playerIn); + worldIn.setBlockToAir(pos); + playerIn.getHeldItem().decrSize(); + return true; + } + } + return super.onUse(worldIn, pos, state, playerIn, side, hitX, hitY, hitZ); + } - public boolean canDrop(Explosion explosionIn) + public boolean canExplosionDrop() { return false; } diff --git a/common/src/main/java/common/block/tech/BlockTNT.java b/common/src/main/java/common/block/tech/BlockTNT.java index 8869cd82..9de6b5e0 100755 --- a/common/src/main/java/common/block/tech/BlockTNT.java +++ b/common/src/main/java/common/block/tech/BlockTNT.java @@ -23,7 +23,6 @@ import common.util.Facing; import common.util.Color; import common.util.Vec3; import common.world.AWorldServer; -import common.world.Explosion; import common.world.State; import common.world.World; @@ -55,13 +54,13 @@ public class BlockTNT extends Block /** * Called when this Block is destroyed by an Explosion */ - public void onDestroyedExplosion(World worldIn, BlockPos pos, Explosion explosionIn, State prevState) + public void onDestroyedExplosion(World worldIn, BlockPos pos, EntityLiving source, State prevState) { if (!worldIn.client) { - 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); + EntityTnt tnt = new EntityTnt(worldIn, (double)((float)pos.getX() + 0.5F), (double)pos.getY(), (double)((float)pos.getZ() + 0.5F), source, this.power); + tnt.fuse = worldIn.rand.zrange(tnt.fuse / 4) + tnt.fuse / 8; + worldIn.spawnEntityInWorld(tnt); } } @@ -133,7 +132,7 @@ public class BlockTNT extends Block /** * Return whether this block can drop from an explosion. */ - public boolean canDrop(Explosion explosionIn) + public boolean canExplosionDrop() { return false; } diff --git a/common/src/main/java/common/entity/DamageSource.java b/common/src/main/java/common/entity/DamageSource.java index 17353a68..8cb26a58 100755 --- a/common/src/main/java/common/entity/DamageSource.java +++ b/common/src/main/java/common/entity/DamageSource.java @@ -3,7 +3,6 @@ package common.entity; import common.entity.projectile.EntityProjectile; import common.entity.types.EntityLiving; import common.util.Color; -import common.world.Explosion; public class DamageSource { @@ -97,9 +96,9 @@ public class DamageSource return (new EntityDamageSource(Color.ORK, "%s wurde beim Versuch %s zu verletzen getötet", "%s durch Dornen getötet", source)).setIsThornsDamage().setMagicDamage(); } - public static DamageSource causeExplosionDamage(Explosion explosion) + public static DamageSource causeExplosionDamage(EntityLiving source) { - return explosion != null && explosion.getExplosivePlacedBy() != null ? (new EntityDamageSource(Color.YELLOW, "%s wurde durch %s in die Luft gesprengt", "%s in die Luft gesprengt", explosion.getExplosivePlacedBy())).setExplosion() : (new DamageSource(Color.YELLOW, "%s wurde in die Luft gesprengt")).setExplosion(); + return source != null && source != null ? (new EntityDamageSource(Color.YELLOW, "%s wurde durch %s in die Luft gesprengt", "%s in die Luft gesprengt", source)).setExplosion() : (new DamageSource(Color.YELLOW, "%s wurde in die Luft gesprengt")).setExplosion(); } /** diff --git a/common/src/main/java/common/entity/Entity.java b/common/src/main/java/common/entity/Entity.java index 41107b5f..2253a473 100755 --- a/common/src/main/java/common/entity/Entity.java +++ b/common/src/main/java/common/entity/Entity.java @@ -40,7 +40,6 @@ import common.util.Serverside; import common.util.Color; import common.util.Vec3; import common.vars.Vars; -import common.world.Explosion; import common.world.State; import common.world.World; import common.world.AWorldServer; diff --git a/common/src/main/java/common/entity/item/EntityCrystal.java b/common/src/main/java/common/entity/item/EntityCrystal.java index 6fb1c6f6..f86f4a72 100755 --- a/common/src/main/java/common/entity/item/EntityCrystal.java +++ b/common/src/main/java/common/entity/item/EntityCrystal.java @@ -97,7 +97,7 @@ public class EntityCrystal extends Entity // if (!this.worldObj.client) // { - this.worldObj.createExplosion(null, this.posX, this.posY, this.posZ, 6.0F, true); + this.worldObj.explode(null, this, this.posX, this.posY, this.posZ, 6.0F, false, true, false); // } // } } diff --git a/common/src/main/java/common/entity/item/EntityExplosion.java b/common/src/main/java/common/entity/item/EntityExplosion.java index a626ac74..8cb4489f 100755 --- a/common/src/main/java/common/entity/item/EntityExplosion.java +++ b/common/src/main/java/common/entity/item/EntityExplosion.java @@ -2,9 +2,9 @@ package common.entity.item; import common.entity.Entity; import common.entity.EntityType; +import common.entity.types.EntityLiving; import common.tags.TagObject; import common.vars.Vars; -import common.world.Explosion; import common.world.World; public class EntityExplosion extends Entity @@ -12,6 +12,7 @@ public class EntityExplosion extends Entity private int progress; private int radius; private int iteration; + private EntityLiving placer; public EntityExplosion(World worldIn) { @@ -22,10 +23,10 @@ public class EntityExplosion extends Entity public EntityExplosion(World worldIn, double x, double y, double z) { - this(worldIn, x, y, z, 70); + this(worldIn, x, y, z, 70, null); } - public EntityExplosion(World worldIn, double x, double y, double z, int radius) + public EntityExplosion(World worldIn, double x, double y, double z, int radius, EntityLiving placer) { this(worldIn); this.setPosition(x, y, z); @@ -33,6 +34,7 @@ public class EntityExplosion extends Entity this.prevY = y; this.prevZ = z; this.radius = radius; + this.placer = placer; } protected void entityInit() @@ -62,7 +64,7 @@ public class EntityExplosion extends Entity private boolean explode(double min) { - this.iteration = Explosion.doPartial(this.worldObj, this.posX, this.posY, this.posZ, this.rand, min + 6.0d, min, this.iteration, Vars.maxExplosionIters); + this.iteration = this.worldObj.explodePartial(this.placer, this, this.posX, this.posY, this.posZ, min + 6.0d, min, this.iteration, Vars.maxExplosionIters); return this.iteration == 0; } @@ -100,4 +102,8 @@ public class EntityExplosion extends Entity public EntityType getType() { return EntityType.EXPLOSIVE; } + + public EntityLiving getPlacedBy() { + return this.placer; + } } diff --git a/common/src/main/java/common/entity/item/EntityItem.java b/common/src/main/java/common/entity/item/EntityItem.java index fcd00d8a..6235224d 100755 --- a/common/src/main/java/common/entity/item/EntityItem.java +++ b/common/src/main/java/common/entity/item/EntityItem.java @@ -72,7 +72,7 @@ public class EntityItem extends Entity } this.worldObj.playEffect(1023, this.getPosition(), 0); if(Vars.itemExplosion && distance >= 2.0f && this.getEntityItem().getItem().getExplosive() > 0 && !this.getEntityItem().isEmpty()) - this.worldObj.newExplosion(this, this.posX, this.posY, this.posZ, (float)this.getEntityItem().getItem().getExplosive() * (1.0f + (float)(this.getEntityItem().getSize() - 1) / 24.0f), true, true, true); + this.worldObj.explode(null, this, this.posX, this.posY, this.posZ, (float)this.getEntityItem().getItem().getExplosive() * (1.0f + (float)(this.getEntityItem().getSize() - 1) / 24.0f), true, true, true); this.setDead(); } } @@ -602,4 +602,8 @@ public class EntityItem extends Entity public EntityType getType() { return EntityType.OBJECT; } + + public boolean isImmuneToExplosions() { + return true; + } } diff --git a/common/src/main/java/common/entity/item/EntityNuke.java b/common/src/main/java/common/entity/item/EntityNuke.java index 85bd5bf5..65ab2f74 100755 --- a/common/src/main/java/common/entity/item/EntityNuke.java +++ b/common/src/main/java/common/entity/item/EntityNuke.java @@ -2,6 +2,7 @@ package common.entity.item; import common.entity.Entity; import common.entity.EntityType; +import common.entity.types.EntityLiving; import common.tags.TagObject; import common.util.ParticleType; import common.world.World; @@ -9,6 +10,7 @@ import common.world.World; public class EntityNuke extends Entity { public int fuse; + private EntityLiving placer; public EntityNuke(World worldIn) { @@ -17,7 +19,7 @@ public class EntityNuke extends Entity this.setSize(0.98F, 0.98F); } - public EntityNuke(World worldIn, double x, double y, double z) + public EntityNuke(World worldIn, double x, double y, double z, EntityLiving placer) { this(worldIn); this.setPosition(x, y, z); @@ -29,6 +31,11 @@ public class EntityNuke extends Entity this.prevX = x; this.prevY = y; this.prevZ = z; + this.placer = placer; + } + + public EntityNuke(World worldIn, double x, double y, double z) { + this(worldIn, x, y, z, null); } protected void entityInit() @@ -71,7 +78,7 @@ public class EntityNuke extends Entity // if(this.fuse < -70) { this.setDead(); if(!this.worldObj.client) - this.worldObj.newExplosion(this.posX, this.posY + (double)(this.height / 2.0F), this.posZ, 70); + this.worldObj.explodeTicked(this.placer, this.posX, this.posY + (double)(this.height / 2.0F), this.posZ, 70); // } // else if(!this.worldObj.client) { // this.setInvisible(true); @@ -123,4 +130,8 @@ public class EntityNuke extends Entity public EntityType getType() { return EntityType.EXPLOSIVE; } + + public EntityLiving getNukePlacedBy() { + return this.placer; + } } diff --git a/common/src/main/java/common/entity/item/EntityTnt.java b/common/src/main/java/common/entity/item/EntityTnt.java index 655d0718..ce1dddad 100755 --- a/common/src/main/java/common/entity/item/EntityTnt.java +++ b/common/src/main/java/common/entity/item/EntityTnt.java @@ -103,7 +103,7 @@ public class EntityTnt extends Entity implements IObjectData private void explode() { float f = 4.0F * (((float)this.explosionSize)+1.0f); - this.worldObj.createExplosion(this, this.posX, this.posY + (double)(this.height / 16.0F), this.posZ, f, true); + this.worldObj.explode(this.tntPlacedBy, this, this.posX, this.posY + (double)(this.height / 16.0F), this.posZ, f, false, true, false); } protected void writeEntity(TagObject tagCompound) @@ -118,9 +118,6 @@ public class EntityTnt extends Entity implements IObjectData this.explosionSize = ((int)tagCompund.getByte("Power")) & 7; } - /** - * returns null or the entityliving it was placed or ignited by - */ public EntityLiving getTntPlacedBy() { return this.tntPlacedBy; diff --git a/common/src/main/java/common/entity/item/EntityTntCart.java b/common/src/main/java/common/entity/item/EntityTntCart.java index 1a807563..a6afedee 100755 --- a/common/src/main/java/common/entity/item/EntityTntCart.java +++ b/common/src/main/java/common/entity/item/EntityTntCart.java @@ -1,6 +1,5 @@ package common.entity.item; -import common.block.tech.BlockRail; import common.entity.DamageSource; import common.entity.Entity; import common.entity.EntityType; @@ -11,11 +10,9 @@ import common.init.SoundEvent; import common.item.Item; import common.item.ItemStack; import common.tags.TagObject; -import common.util.BlockPos; import common.util.Clientside; import common.util.ParticleType; import common.vars.Vars; -import common.world.Explosion; import common.world.State; import common.world.World; @@ -93,7 +90,7 @@ public class EntityTntCart extends EntityCart { d0 = 5.0D; } - this.worldObj.createExplosion(this, this.posX, this.posY, this.posZ, (float)(4.0D + this.rand.doublev() * 1.5D * d0), true); + this.worldObj.explode(null, this, this.posX, this.posY, this.posZ, (float)(4.0D + this.rand.doublev() * 1.5D * d0), false, true, false); this.setDead(); } } diff --git a/common/src/main/java/common/entity/item/EntityXp.java b/common/src/main/java/common/entity/item/EntityXp.java index d31b1a25..77073c2d 100755 --- a/common/src/main/java/common/entity/item/EntityXp.java +++ b/common/src/main/java/common/entity/item/EntityXp.java @@ -410,4 +410,8 @@ public class EntityXp extends Entity implements IObjectData public EntityType getType() { return EntityType.OBJECT; } + + public boolean isImmuneToExplosions() { + return true; + } } diff --git a/common/src/main/java/common/entity/npc/EntityGargoyle.java b/common/src/main/java/common/entity/npc/EntityGargoyle.java index a72eb1cd..e2e0f6a7 100755 --- a/common/src/main/java/common/entity/npc/EntityGargoyle.java +++ b/common/src/main/java/common/entity/npc/EntityGargoyle.java @@ -110,7 +110,7 @@ public class EntityGargoyle extends EntityFlyingNPC if (j1 <= 0) { - this.worldObj.newExplosion(this, this.posX, this.posY + (double)this.getEyeHeight(), this.posZ, 7.0F, false, + this.worldObj.explode(this, this, this.posX, this.posY + (double)this.getEyeHeight(), this.posZ, 7.0F, false, Vars.mobGrief, false); // this.worldObj.broadcastSound(1013, new BlockPos(this), 0); } diff --git a/common/src/main/java/common/entity/npc/EntityHaunter.java b/common/src/main/java/common/entity/npc/EntityHaunter.java index 0fb823e0..46b45402 100755 --- a/common/src/main/java/common/entity/npc/EntityHaunter.java +++ b/common/src/main/java/common/entity/npc/EntityHaunter.java @@ -251,7 +251,7 @@ public class EntityHaunter extends EntityNPC { { boolean flag = Vars.mobGrief; float f = 1.0F + (float)(this.isCharged() ? this.rand.range(3, 5) : 0) / 8.0f; - this.worldObj.createAltExplosion(this, this.posX, this.posY, this.posZ, (float)this.rand.range(3, 5) * f, flag); + this.worldObj.explode(this, this, this.posX, this.posY, this.posZ, (float)this.rand.range(3, 5) * f, false, flag, true); this.setDead(); } } diff --git a/common/src/main/java/common/entity/projectile/EntityBox.java b/common/src/main/java/common/entity/projectile/EntityBox.java index 4bdfc4e8..a8192277 100755 --- a/common/src/main/java/common/entity/projectile/EntityBox.java +++ b/common/src/main/java/common/entity/projectile/EntityBox.java @@ -113,7 +113,7 @@ public class EntityBox extends EntityProjectile } } - this.worldObj.newExplosion(this, this.posX, this.posY, this.posZ, this.rand.frange(1.0f, 3.0f), false, false, false); + this.worldObj.explode(this.shootingEntity, this, this.posX, this.posY, this.posZ, this.rand.frange(1.0f, 3.0f), false, false, false); this.setDead(); } } diff --git a/common/src/main/java/common/entity/projectile/EntityBullet.java b/common/src/main/java/common/entity/projectile/EntityBullet.java index e3b0eaf6..d504debe 100755 --- a/common/src/main/java/common/entity/projectile/EntityBullet.java +++ b/common/src/main/java/common/entity/projectile/EntityBullet.java @@ -22,7 +22,7 @@ import common.world.State; import common.world.World; public class EntityBullet extends Entity implements IProjectile, IObjectData { - protected Entity shooter; + protected EntityLiving shooter; private int ticksMoved; protected int age; protected int damage = 5; @@ -43,8 +43,8 @@ public class EntityBullet extends Entity implements IProjectile, IObjectData { public EntityBullet(World world, double x, double y, double z, int data) { this(world, x, y, z); Entity entity = world.getEntityByID(data); - if(entity instanceof EntityLiving) - this.shooter = entity; + if(entity instanceof EntityLiving living) + this.shooter = living; } public EntityBullet(World world, EntityLiving shooter, EntityLiving target, float velocity, float innacuracy) { diff --git a/common/src/main/java/common/entity/projectile/EntityDynamite.java b/common/src/main/java/common/entity/projectile/EntityDynamite.java index 05a2b841..46d353f1 100755 --- a/common/src/main/java/common/entity/projectile/EntityDynamite.java +++ b/common/src/main/java/common/entity/projectile/EntityDynamite.java @@ -44,7 +44,7 @@ public class EntityDynamite extends EntityThrowable implements IObjectData { float f = 4.0F * (((float)this.explosionSize)+1.0f); EntityLiving thrower = this.getThrower(); - this.worldObj.createAltExplosion(thrower == null ? this : thrower, this.posX, this.posY + (double)(this.height / 2.0F), this.posZ, f, true); + this.worldObj.explode(thrower, this, this.posX, this.posY + (double)(this.height / 2.0F), this.posZ, f, false, true, true); } for (int k = 0; k < 8; ++k) diff --git a/common/src/main/java/common/entity/projectile/EntityFireball.java b/common/src/main/java/common/entity/projectile/EntityFireball.java index b1b025ae..be0095cf 100755 --- a/common/src/main/java/common/entity/projectile/EntityFireball.java +++ b/common/src/main/java/common/entity/projectile/EntityFireball.java @@ -43,7 +43,7 @@ public class EntityFireball extends EntityProjectile this.applyEnchantments(this.shootingEntity, movingObject.entity); } - this.worldObj.newExplosion(this.shootingEntity, this.posX, this.posY, this.posZ, (float)this.explosionPower, Vars.mobGrief, Vars.mobGrief && this.damageBlocks, true); + this.worldObj.explode(this.shootingEntity, this, this.posX, this.posY, this.posZ, (float)this.explosionPower, Vars.mobGrief, Vars.mobGrief && this.damageBlocks, true); this.setDead(); } } diff --git a/common/src/main/java/common/entity/projectile/EntityMissile.java b/common/src/main/java/common/entity/projectile/EntityMissile.java index 72810bf0..04581f9b 100755 --- a/common/src/main/java/common/entity/projectile/EntityMissile.java +++ b/common/src/main/java/common/entity/projectile/EntityMissile.java @@ -46,7 +46,7 @@ public class EntityMissile extends EntityBullet { protected void explode() { this.setDead(); - this.worldObj.newExplosion(this, this.posX, this.posY, this.posZ, (float)this.damage, this.flames, true, false); + this.worldObj.explode(this.shooter, this, this.posX, this.posY, this.posZ, (float)this.damage, this.flames, true, false); } protected void onHitBlock(BlockPos pos) { diff --git a/common/src/main/java/common/packet/SPacketExplosion.java b/common/src/main/java/common/packet/SPacketExplosion.java index ecd1cedc..1c15d96d 100755 --- a/common/src/main/java/common/packet/SPacketExplosion.java +++ b/common/src/main/java/common/packet/SPacketExplosion.java @@ -12,134 +12,93 @@ import common.network.Packet; import common.network.PacketBuffer; import common.rng.Random; import common.util.BlockPos; -import common.util.Vec3; public class SPacketExplosion implements Packet { private double posX; private double posY; private double posZ; - private float strength; - private List affectedBlockPositions; - private float field_149152_f; - private float field_149153_g; - private float field_149159_h; - private boolean altSound; + private List blocks; + private boolean large; public SPacketExplosion() { } - public SPacketExplosion(double p_i45193_1_, double y, double z, float strengthIn, List affectedBlocksIn, Vec3 p_i45193_9_, boolean altSound) + public SPacketExplosion(double x, double y, double z, List blocks, boolean large) { - this.posX = p_i45193_1_; + this.posX = x; this.posY = y; this.posZ = z; - this.strength = strengthIn; - this.altSound = altSound; - if(affectedBlocksIn.size() > 256) { + this.large = large; + if(blocks != null && blocks.size() > 256) { Set pos = Sets.newHashSet(); Random rand = new Random(); for(int n = 0; n < 256; n++) { - pos.add(rand.pick(affectedBlocksIn)); + pos.add(rand.pick(blocks)); } - this.affectedBlockPositions = Lists.newArrayList(pos); + this.blocks = Lists.newArrayList(pos); pos.clear(); } - else { - this.affectedBlockPositions = Lists.newArrayList(affectedBlocksIn); - } - - if (p_i45193_9_ != null) - { - this.field_149152_f = (float)p_i45193_9_.xCoord; - this.field_149153_g = (float)p_i45193_9_.yCoord; - this.field_149159_h = (float)p_i45193_9_.zCoord; + else if(blocks != null) { + this.blocks = Lists.newArrayList(blocks); } } - /** - * Reads the raw packet data from the data stream. - */ public void readPacketData(PacketBuffer buf) throws IOException { this.posX = (double)buf.readFloat(); this.posY = (double)buf.readFloat(); this.posZ = (double)buf.readFloat(); - this.strength = buf.readFloat(); int i = buf.readInt(); - this.affectedBlockPositions = new ArrayList(i); - int j = (int)this.posX; - int k = (int)this.posY; - int l = (int)this.posZ; - - for (int i1 = 0; i1 < i; ++i1) - { - int j1 = buf.readByte() + j; - int k1 = buf.readByte() + k; - int l1 = buf.readByte() + l; - this.affectedBlockPositions.add(new BlockPos(j1, k1, l1)); + if(i > 0) { + this.blocks = new ArrayList(i); + int j = (int)this.posX; + int k = (int)this.posY; + int l = (int)this.posZ; + + for (int i1 = 0; i1 < i; ++i1) + { + int j1 = buf.readShort() + j; + int k1 = buf.readShort() + k; + int l1 = buf.readShort() + l; + this.blocks.add(new BlockPos(j1, k1, l1)); + } } - this.field_149152_f = buf.readFloat(); - this.field_149153_g = buf.readFloat(); - this.field_149159_h = buf.readFloat(); - this.altSound = buf.readBoolean(); + this.large = buf.readBoolean(); } - /** - * Writes the raw packet data to the data stream. - */ public void writePacketData(PacketBuffer buf) throws IOException { buf.writeFloat((float)this.posX); buf.writeFloat((float)this.posY); buf.writeFloat((float)this.posZ); - buf.writeFloat(this.strength); - buf.writeInt(this.affectedBlockPositions.size()); - int i = (int)this.posX; - int j = (int)this.posY; - int k = (int)this.posZ; - - for (BlockPos blockpos : this.affectedBlockPositions) - { - int l = blockpos.getX() - i; - int i1 = blockpos.getY() - j; - int j1 = blockpos.getZ() - k; - buf.writeByte(l); - buf.writeByte(i1); - buf.writeByte(j1); + buf.writeInt(this.blocks == null ? 0 : this.blocks.size()); + if(this.blocks != null) { + int i = (int)this.posX; + int j = (int)this.posY; + int k = (int)this.posZ; + + for (BlockPos blockpos : this.blocks) + { + int l = blockpos.getX() - i; + int i1 = blockpos.getY() - j; + int j1 = blockpos.getZ() - k; + buf.writeShort(l); + buf.writeShort(i1); + buf.writeShort(j1); + } } - buf.writeFloat(this.field_149152_f); - buf.writeFloat(this.field_149153_g); - buf.writeFloat(this.field_149159_h); - buf.writeBoolean(this.altSound); + buf.writeBoolean(this.large); } - /** - * Passes this Packet on to the NetHandler for processing. - */ public void processPacket(IClientPlayer handler) { handler.handleExplosion(this); } - public float func_149149_c() - { - return this.field_149152_f; - } - - public float func_149144_d() - { - return this.field_149153_g; - } - - public float func_149147_e() - { - return this.field_149159_h; - } - public double getX() { return this.posX; @@ -155,18 +114,13 @@ public class SPacketExplosion implements Packet return this.posZ; } - public float getStrength() + public boolean isLarge() { - return this.strength; + return this.large; } - public boolean hasAltSound() + public List getBlocks() { - return this.altSound; - } - - public List getAffectedBlockPositions() - { - return this.affectedBlockPositions; + return this.blocks; } } diff --git a/common/src/main/java/common/tileentity/Device.java b/common/src/main/java/common/tileentity/Device.java index c2a306e2..d2cc26fb 100755 --- a/common/src/main/java/common/tileentity/Device.java +++ b/common/src/main/java/common/tileentity/Device.java @@ -249,7 +249,7 @@ public abstract class Device extends TileEntity implements IInventory, ITickable public void detonate() { this.world.setBlockToAir(getPos()); - this.world.newExplosion(null, this.getXPos(), this.getYPos(), this.getZPos(), 5.0f, true, true, false); + this.world.explode(null, null, this.getXPos(), this.getYPos(), this.getZPos(), 5.0f, true, true, false); } public void update() { diff --git a/common/src/main/java/common/tileentity/DeviceFurnace.java b/common/src/main/java/common/tileentity/DeviceFurnace.java index 2e118fc4..063174dc 100755 --- a/common/src/main/java/common/tileentity/DeviceFurnace.java +++ b/common/src/main/java/common/tileentity/DeviceFurnace.java @@ -77,7 +77,7 @@ public class DeviceFurnace extends Device { if(Vars.itemExplosion && this.getStackInSlot(1).getItem().getExplosive() > 0 && !this.getStackInSlot(1).isEmpty()) { this.world.setBlockToAir(getPos()); - this.world.newExplosion(null, this.getXPos(), this.getYPos(), this.getZPos(), (float)this.getStackInSlot(1).getItem().getExplosive() * (1.0f + (float)(this.getStackInSlot(1).getSize() - 1) / 24.0f), true, true, true); + this.world.explode(null, null, this.getXPos(), this.getYPos(), this.getZPos(), (float)this.getStackInSlot(1).getItem().getExplosive() * (1.0f + (float)(this.getStackInSlot(1).getSize() - 1) / 24.0f), true, true, true); this.setInventorySlotContents(1, null); return false; } diff --git a/common/src/main/java/common/tileentity/DeviceTianReactor.java b/common/src/main/java/common/tileentity/DeviceTianReactor.java index 5e83f539..15e95c3c 100755 --- a/common/src/main/java/common/tileentity/DeviceTianReactor.java +++ b/common/src/main/java/common/tileentity/DeviceTianReactor.java @@ -49,7 +49,7 @@ public class DeviceTianReactor extends Device { public void detonate() { this.world.setBlockToAir(getPos()); - this.world.newExplosion(this.getXPos(), this.getYPos(), this.getZPos(), 120); + this.world.explodeTicked(null, this.getXPos(), this.getYPos(), this.getZPos(), 120); } public String formatDisplay(ContainerTile inv) { diff --git a/common/src/main/java/common/world/Explosion.java b/common/src/main/java/common/world/Explosion.java deleted file mode 100755 index 682b396c..00000000 --- a/common/src/main/java/common/world/Explosion.java +++ /dev/null @@ -1,283 +0,0 @@ -package common.world; - -import java.util.List; -import java.util.Map; -import java.util.Set; - -import common.block.Block; -import common.collect.Lists; -import common.collect.Maps; -import common.collect.Sets; -import common.enchantment.Enchantment; -import common.entity.DamageSource; -import common.entity.Entity; -import common.entity.item.EntityTnt; -import common.entity.npc.EntityNPC; -import common.entity.projectile.EntityMissile; -import common.entity.types.EntityLiving; -import common.init.Blocks; -import common.init.SoundEvent; -import common.rng.Random; -import common.util.BlockPos; -import common.util.BoundingBox; -import common.util.ExtMath; -import common.util.ParticleType; -import common.util.Vec3; -import common.vars.Vars; - -public class Explosion -{ - private static final int[][] TABLES = new int[1024][]; - - private static int[] shuffle(int size) { - int[] table = new int[size]; - Random rand = new Random(8236737136521L); - for(int z = 0; z < size; z++) { - table[z] = z; - } - for(int z = 0; z < size; z++) { - int r = rand.zrange(size); - int n = table[z]; - table[z] = table[r]; - table[r] = n; - } - return table; - } - - private static int[] getTable(int size) { - if(size < 0 || size >= TABLES.length) - return null; - int[] table = TABLES[size]; - if(table == null) - TABLES[size] = table = shuffle(size); - return table; - } - - private final boolean isFlaming; - private final boolean isSmoking; - private final Random explosionRNG; - private final World worldObj; - private final double explosionX; - private final double explosionY; - private final double explosionZ; - private final Entity exploder; - private final float explosionSize; - private final List affectedBlockPositions; - private final Map playerKnockbackMap; - - 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); - this.affectedBlockPositions.addAll(affectedPositions); - } - - public Explosion(World worldIn, Entity entityIn, double x, double y, double z, float size, boolean flaming, boolean smoking) - { - this.explosionRNG = new Random(); - this.affectedBlockPositions = Lists.newArrayList(); - this.playerKnockbackMap = Maps.newHashMap(); - this.worldObj = worldIn; - this.exploder = entityIn; - this.explosionSize = size; - this.explosionX = x; - this.explosionY = y; - this.explosionZ = z; - this.isFlaming = flaming; - this.isSmoking = smoking; - } - - 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)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 && (state.getBlock().getMaterial().isLiquid() || (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) - { - for (int y = -d; y <= d; ++y) - { - for (int z = -d; z <= d; ++z) - { - 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 pos = new BlockPos(this.explosionX + x, this.explosionY + y, this.explosionZ + z); - State state = this.worldObj.getState(pos); - if(state.getBlock() != Blocks.air && (state.getBlock().getMaterial().isLiquid() || this.explosionSize - (state.getBlock().getResistance() / 5.0F + 0.3F) * 0.3F > 0.0F)) - set.add(pos); - } - } - } - } - 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); - int i2 = ExtMath.floord(this.explosionY - (double)f3 - 1.0D); - int i1 = ExtMath.floord(this.explosionY + (double)f3 + 1.0D); - int j2 = ExtMath.floord(this.explosionZ - (double)f3 - 1.0D); - 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; - d7 = d7 / d13; - d9 = d9 / d13; - double d14 = (double)this.worldObj.getBlockDensity(vec3, entity.getEntityBoundingBox()); - double d10 = (1.0D - d12) * d14; - if(this.worldObj.client || Vars.damageExplosion) - entity.attackEntityFrom(DamageSource.causeExplosionDamage(this), ((int)((d10 * d10 + d10) / 2.0D * 8.0D * (double)f3 + 1.0D))); - double d11 = Enchantment.getKnockbackFactor(entity, d10); - entity.motionX += d5 * d11; - entity.motionY += d7 * d11; - entity.motionZ += d9 * d11; - if (entity.isPlayer()) - this.playerKnockbackMap.put((EntityNPC)entity, new Vec3(d5 * d10, d7 * d10, d9 * d10)); - } - } - } - } - } - - public void doExplosionB(boolean spawnParticles, boolean altSound) - { - this.worldObj.sendSound(altSound ? SoundEvent.EXPLODE_ALT : SoundEvent.EXPLODE, this.explosionX, this.explosionY, this.explosionZ, 4.0F); - - if (this.explosionSize >= 2.0F && this.isSmoking) - { - this.worldObj.clientParticle(ParticleType.EXPLOSION_HUGE, this.explosionX, this.explosionY, this.explosionZ); - } - else - { - this.worldObj.clientParticle(ParticleType.EXPLOSION_LARGE, this.explosionX, this.explosionY, this.explosionZ, 100); - } - - if (this.isSmoking) - { - for (BlockPos blockpos : this.affectedBlockPositions) - { - State state = this.worldObj.getState(blockpos); - Block block = state.getBlock(); - - 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()); - double d2 = (double)((float)blockpos.getZ() + this.worldObj.rand.floatv()); - this.worldObj.clientParticle(ParticleType.EXPLOSION_NORMAL, (d0 + this.explosionX * 1.0D) / 2.0D, (d1 + this.explosionY * 1.0D) / 2.0D, (d2 + this.explosionZ * 1.0D) / 2.0D); - this.worldObj.clientParticle(ParticleType.SMOKE, d0, d1, d2); - } - - if (!this.worldObj.client && block != Blocks.air) - { - if (block.canDrop(this)) - 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); - } - } - } - - if (!this.worldObj.client && this.isFlaming) - { - for (BlockPos blockpos1 : this.affectedBlockPositions) - { - if (this.worldObj.getState(blockpos1).getBlock() == Blocks.air && this.worldObj.getState(blockpos1.down()).getBlock().isFullBlock() && this.explosionRNG.zrange(3) == 0) - { - this.worldObj.setState(blockpos1, Blocks.fire.getState()); - } - } - } - } - - public Map getPlayerKnockbackMap() - { - return this.playerKnockbackMap; - } - - public EntityLiving getExplosivePlacedBy() - { - return this.exploder == null ? null : (this.exploder instanceof EntityTnt ? ((EntityTnt)this.exploder).getTntPlacedBy() : - (this.exploder instanceof EntityMissile missile && missile.getShooter() instanceof EntityLiving shooter ? shooter :(this.exploder instanceof EntityLiving ? (EntityLiving)this.exploder : null))); - } - - public void clearAffectedBlockPositions() - { - this.affectedBlockPositions.clear(); - } - - public List getAffectedBlockPositions() - { - return this.affectedBlockPositions; - } -} diff --git a/common/src/main/java/common/world/World.java b/common/src/main/java/common/world/World.java index 532f07e4..2c4d68e9 100755 --- a/common/src/main/java/common/world/World.java +++ b/common/src/main/java/common/world/World.java @@ -20,8 +20,8 @@ import common.collect.Sets; import common.dimension.DimType; import common.dimension.Dimension; import common.entity.Entity; -import common.entity.item.EntityExplosion; import common.entity.npc.EntityNPC; +import common.entity.types.EntityLiving; import common.init.BlockRegistry; import common.init.Blocks; import common.init.SoundEvent; @@ -1242,27 +1242,6 @@ public abstract class World implements IWorldAccess { return false; } - 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 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); - } - - public Explosion newExplosion(Entity entityIn, double x, double y, double z, float strength, boolean isFlaming, boolean isSmoking, boolean altSound) { - Explosion explosion = new Explosion(this, entityIn, x, y, z, strength, isFlaming, isSmoking); - explosion.doExplosionA(); - explosion.doExplosionB(true, altSound); - return explosion; - } - - public EntityExplosion newExplosion(double x, double y, double z, int strength) { - EntityExplosion explosion = new EntityExplosion(this, x, y, z, strength); - this.spawnEntityInWorld(explosion); - return explosion; - } - public float getBlockDensity(Vec3 vec, BoundingBox bb) { double d0 = 1.0D / ((bb.maxX - bb.minX) * 2.0D + 1.0D); double d1 = 1.0D / ((bb.maxY - bb.minY) * 2.0D + 1.0D); @@ -1929,6 +1908,16 @@ public abstract class World implements IWorldAccess { public void sendSound(SoundEvent sound, double x, double y, double z, float volume) { } + + public void explode(EntityLiving source, Entity exploder, double posX, double posY, double posZ, float radius, boolean fire, boolean destroy, boolean altSound) { + } + + public int explodePartial(EntityLiving source, Entity exploder, double posX, double posY, double posZ, double radius, double minDist, int iter, int max) { + return 0; + } + + public void explodeTicked(EntityLiving source, double x, double y, double z, int radius) { + } public void clientSound(SoundEvent sound, double x, double y, double z, float volume) { diff --git a/server/src/main/java/server/command/commands/CommandExplode.java b/server/src/main/java/server/command/commands/CommandExplode.java index 206626c0..c3ab5a74 100644 --- a/server/src/main/java/server/command/commands/CommandExplode.java +++ b/server/src/main/java/server/command/commands/CommandExplode.java @@ -24,9 +24,9 @@ public class CommandExplode extends Command { 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); + world.explodeTicked(null, pos.xCoord, pos.yCoord, pos.zCoord, radius); else - world.newExplosion(null, pos.xCoord, pos.yCoord, pos.zCoord, radius, fire, !noblocks, altsound); + world.explode(null, 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()); } } diff --git a/server/src/main/java/server/world/WorldServer.java b/server/src/main/java/server/world/WorldServer.java index 96a7b93f..dc0f56f4 100755 --- a/server/src/main/java/server/world/WorldServer.java +++ b/server/src/main/java/server/world/WorldServer.java @@ -27,10 +27,13 @@ import common.collect.Maps; import common.collect.Sets; import common.dimension.DimType; import common.dimension.Dimension; +import common.effect.Effect; +import common.enchantment.Enchantment; import common.entity.DamageSource; import common.entity.Entity; import common.entity.EntityTrackerEntry; import common.entity.effect.EntityLightning; +import common.entity.item.EntityExplosion; import common.entity.npc.EntityNPC; import common.entity.types.EntityLiving; import common.init.Blocks; @@ -40,6 +43,7 @@ import common.log.Log; import common.network.IPlayer; import common.network.Packet; import common.packet.SPacketEntityStatus; +import common.packet.SPacketEntityVelocity; import common.packet.SPacketExplosion; import common.packet.SPacketEffect; import common.packet.SPacketSoundEffect; @@ -67,7 +71,6 @@ import common.vars.Vars; import common.village.Village; import common.world.BlockArray; import common.world.Chunk; -import common.world.Explosion; import common.world.AWorldServer; import common.world.LightType; import common.world.State; @@ -111,6 +114,31 @@ import server.worldgen.tree.WorldGenTaiga2; public final class WorldServer extends AWorldServer { private static final int[][] XZ_DIRS = new int[][] {{1, 0}, {0, 1}, {-1, 0}, {0, -1}}; + private static final int[][] TABLES = new int[1024][]; + + private static int[] shuffle(int size) { + int[] table = new int[size]; + Random rand = new Random(8236737136521L); + for(int z = 0; z < size; z++) { + table[z] = z; + } + for(int z = 0; z < size; z++) { + int r = rand.zrange(size); + int n = table[z]; + table[z] = table[r]; + table[r] = n; + } + return table; + } + + private static int[] getTable(int size) { + if(size < 0 || size >= TABLES.length) + return null; + int[] table = TABLES[size]; + if(table == null) + TABLES[size] = table = shuffle(size); + return table; + } private final Server server; private final File chunkDir; @@ -906,24 +934,152 @@ public final class WorldServer extends AWorldServer { public void setEntityState(Entity entityIn, byte state) { this.sendToAllTrackingAndSelf(entityIn, new SPacketEntityStatus(entityIn, state)); } + + private boolean destroyBlock(BlockPos pos, float power, EntityLiving source) { + State state = this.getState(pos); + Block block = state.getBlock(); + if(block != Blocks.air && (block.getMaterial().isLiquid() || power - (block.getResistance() / 5.0F + 0.3F) * 0.3F > 0.0F)) { + if(block.canExplosionDrop() && this.rand.floatv() <= 1.0F / (power * power)) + block.drop(this, pos, state, 0); + this.setState(pos, Blocks.air.getState(), power < 40.0F ? 2 : 10); + block.onDestroyedExplosion(this, pos, source, state); + return true; + } + return false; + } + + private Set damageEntities(Entity exploder, EntityLiving source, double posX, double posY, double posZ, float radius) { + float dmgRadius = radius * 2.0F; + int x1 = ExtMath.floord(posX - (double)dmgRadius - 1.0D); + int x2 = ExtMath.floord(posX + (double)dmgRadius + 1.0D); + int y1 = ExtMath.floord(posY - (double)dmgRadius - 1.0D); + int y2 = ExtMath.floord(posY + (double)dmgRadius + 1.0D); + int z1 = ExtMath.floord(posZ - (double)dmgRadius - 1.0D); + int z2 = ExtMath.floord(posZ + (double)dmgRadius + 1.0D); + List list = this.getEntitiesWithinAABBExcludingEntity(exploder, new BoundingBox((double)x1, (double)y1, (double)z1, (double)x2, (double)y2, (double)z2)); + Vec3 vec3 = new Vec3(posX, posY, posZ); + Set velocity = Sets.newHashSet(); + for (int pos = 0; pos < list.size(); pos++) + { + Entity entity = (Entity)list.get(pos); + if (!entity.isImmuneToExplosions()) + { + double dist = entity.getDistance(posX, posY, posZ) / (double)dmgRadius; + if (dist <= 1.0D) + { + double dx = entity.posX - posX; + double dy = entity.posY + (double)entity.getEyeHeight() - posY; + double dz = entity.posZ - posZ; + double dt = (double)ExtMath.sqrtd(dx * dx + dy * dy + dz * dz); + if (dt != 0.0D) + { + dx = dx / dt; + dy = dy / dt; + dz = dz / dt; + double density = (double)this.getBlockDensity(vec3, entity.getEntityBoundingBox()); + double damage = (1.0D - dist) * density; + if(Vars.damageExplosion) + entity.attackEntityFrom(DamageSource.causeExplosionDamage(source), ((int)((damage * damage + damage) / 2.0D * 8.0D * (double)dmgRadius + 1.0D))); + if(!(entity instanceof EntityLiving living) || !living.hasEffect(Effect.STABILITY)) { + double velo = Enchantment.getKnockbackFactor(entity, damage); + entity.motionX += dx * velo; + entity.motionY += dy * velo; + entity.motionZ += dz * velo; + if(entity.isPlayer()) + velocity.add((EntityNPC)entity); + } + } + } + } + } + return velocity; + } - public Explosion newExplosion(Entity entityIn, double x, double y, double z, float strength, boolean isFlaming, boolean isSmoking, boolean altSound) { - Explosion explosion = new Explosion(this, entityIn, x, y, z, strength, isFlaming, isSmoking); - explosion.doExplosionA(); - explosion.doExplosionB(false, altSound); + public void explode(EntityLiving source, Entity exploder, double posX, double posY, double posZ, float radius, boolean fire, boolean destroy, boolean altSound) { + Set set = Sets.newHashSet(); + int d = ((int)radius) + 1; + double falloff = radius * 0.125d; + falloff = falloff > 4.0d ? 4.0d : falloff; + for (int x = -d; x <= d; ++x) + { + for (int y = -d; y <= d; ++y) + { + for (int z = -d; z <= d; ++z) + { + double dist = (double)ExtMath.sqrtd(((double)x) * ((double)x) + ((double)y) * ((double)y) + ((double)z) * ((double)z)); + if(dist < radius - falloff || + (dist < radius && this.rand.doublev() + ((dist - (radius - falloff)) / falloff) < 1.0d)) { + BlockPos pos = new BlockPos(posX + x, posY + y, posZ + z); + if(this.destroyBlock(pos, radius, source)) + set.add(pos); + } + } + } + } + List blocks = Lists.newArrayList(set); + set.clear(); + + Set velocity = this.damageEntities(exploder, source, posX, posY, posZ, radius); - if(!isSmoking) { - explosion.clearAffectedBlockPositions(); + this.sendSound(altSound ? SoundEvent.EXPLODE_ALT : SoundEvent.EXPLODE, posX, posY, posZ, 4.0F); + + if (fire) + { + for (BlockPos pos : blocks) + { + if(this.getState(pos).getBlock() == Blocks.air && this.getState(pos.down()).getBlock().isFullBlock() && this.rand.zrange(3) == 0) + this.setState(pos, Blocks.fire.getState()); + } + } + + for(EntityNPC player : this.players) { + if(player.getDistanceSq(posX, posY, posZ) < 4096.0D) + player.connection.sendPacket(new SPacketExplosion(posX, posY, posZ, destroy ? blocks : null, radius >= 2.0f && destroy)); + if(velocity.contains(player)) + player.connection.sendPacket(new SPacketEntityVelocity(player)); } - - for(EntityNPC entityplayer : this.players) { - if(entityplayer.getDistanceSq(x, y, z) < 4096.0D) { - entityplayer.connection.sendPacket(new SPacketExplosion(x, y, z, strength, explosion.getAffectedBlockPositions(), - (Vec3)explosion.getPlayerKnockbackMap().get(entityplayer), altSound)); - } + } + + public int explodePartial(EntityLiving source, Entity exploder, double posX, double posY, double posZ, double radius, double minDist, int iter, int max) + { + 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 && this.rand.doublev() + ((dist - (radius - falloff)) / falloff) < 1.0d))) { + BlockPos pos = new BlockPos(posX + x, posY + y, posZ + z); + if(this.destroyBlock(pos, (float)radius, null) && this.rand.chance(1000)) { + this.sendSound(SoundEvent.EXPLODE, posX + x, posY + y, posZ + z, 4.0F); + this.spawnParticles(ParticleType.EXPLOSION_HUGE, posX + x, posY + y, posZ + z); + } + cnt++; + } + } + + Set velocity = this.damageEntities(exploder, source, posX, posY, posZ, (float)radius); + + for(EntityNPC player : this.players) { + if(velocity.contains(player)) + player.connection.sendPacket(new SPacketEntityVelocity(player)); } + + return iter >= lmt ? 0 : iter; + } - return explosion; + public void explodeTicked(EntityLiving source, double x, double y, double z, int radius) { + this.spawnEntityInWorld(new EntityExplosion(this, x, y, z, radius, source)); } public void resetWeather() {