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