1
0
Fork 0

fix explosions for real this time

This commit is contained in:
Sen 2025-08-27 19:43:14 +02:00
parent 11db0e57cb
commit aaad753263
Signed by: sen
GPG key ID: 3AC50A6F47D1B722
36 changed files with 338 additions and 495 deletions

View file

@ -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)

View file

@ -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) {

View file

@ -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) {

View file

@ -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() {

View file

@ -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)
{

View file

@ -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)
{

View file

@ -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)
{

View file

@ -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;

View file

@ -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)
{

View file

@ -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())
{

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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();
}
/**

View file

@ -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;

View file

@ -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);
// }
// }
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;

View file

@ -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();
}
}

View file

@ -410,4 +410,8 @@ public class EntityXp extends Entity implements IObjectData
public EntityType getType() {
return EntityType.OBJECT;
}
public boolean isImmuneToExplosions() {
return true;
}
}

View file

@ -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);
}

View file

@ -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();
}
}

View file

@ -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();
}
}

View file

@ -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) {

View file

@ -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)

View file

@ -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();
}
}

View file

@ -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) {

View file

@ -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<IClientPlayer>
{
private double posX;
private double posY;
private double posZ;
private float strength;
private List<BlockPos> affectedBlockPositions;
private float field_149152_f;
private float field_149153_g;
private float field_149159_h;
private boolean altSound;
private List<BlockPos> blocks;
private boolean large;
public SPacketExplosion()
{
}
public SPacketExplosion(double p_i45193_1_, double y, double z, float strengthIn, List<BlockPos> affectedBlocksIn, Vec3 p_i45193_9_, boolean altSound)
public SPacketExplosion(double x, double y, double z, List<BlockPos> 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<BlockPos> 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<BlockPos>(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<BlockPos>(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<IClientPlayer>
return this.posZ;
}
public float getStrength()
public boolean isLarge()
{
return this.strength;
return this.large;
}
public boolean hasAltSound()
public List<BlockPos> getBlocks()
{
return this.altSound;
}
public List<BlockPos> getAffectedBlockPositions()
{
return this.affectedBlockPositions;
return this.blocks;
}
}

View file

@ -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() {

View file

@ -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;
}

View file

@ -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) {

View file

@ -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<BlockPos> affectedBlockPositions;
private final Map<EntityNPC, Vec3> playerKnockbackMap;
public Explosion(World worldIn, Entity entityIn, double x, double y, double z, float size, List<BlockPos> 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.<BlockPos>newArrayList();
this.playerKnockbackMap = Maps.<EntityNPC, Vec3>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<Entity> 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<BlockPos> set = Sets.<BlockPos>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<Entity> 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<EntityNPC, Vec3> 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<BlockPos> getAffectedBlockPositions()
{
return this.affectedBlockPositions;
}
}

View file

@ -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) {

View file

@ -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());
}
}

View file

@ -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<EntityNPC> 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<Entity> 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<EntityNPC> 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<BlockPos> set = Sets.<BlockPos>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<BlockPos> blocks = Lists.<BlockPos>newArrayList(set);
set.clear();
Set<EntityNPC> 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<EntityNPC> 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() {