1
0
Fork 0

make explosions less laggy

This commit is contained in:
Sen 2025-08-27 09:01:36 +02:00
parent a5bdf39f19
commit 95389455aa
Signed by: sen
GPG key ID: 3AC50A6F47D1B722
6 changed files with 57 additions and 91 deletions

View file

@ -3,11 +3,14 @@ package common.packet;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Set;
import common.collect.Lists; import common.collect.Lists;
import common.collect.Sets;
import common.network.IClientPlayer; import common.network.IClientPlayer;
import common.network.Packet; import common.network.Packet;
import common.network.PacketBuffer; import common.network.PacketBuffer;
import common.rng.Random;
import common.util.BlockPos; import common.util.BlockPos;
import common.util.Vec3; import common.util.Vec3;
@ -34,7 +37,18 @@ public class SPacketExplosion implements Packet<IClientPlayer>
this.posZ = z; this.posZ = z;
this.strength = strengthIn; this.strength = strengthIn;
this.altSound = altSound; this.altSound = altSound;
this.affectedBlockPositions = Lists.newArrayList(affectedBlocksIn); if(affectedBlocksIn.size() > 256) {
Set<BlockPos> pos = Sets.newHashSet();
Random rand = new Random();
for(int n = 0; n < 256; n++) {
pos.add(rand.pick(affectedBlocksIn));
}
this.affectedBlockPositions = Lists.newArrayList(pos);
pos.clear();
}
else {
this.affectedBlockPositions = Lists.newArrayList(affectedBlocksIn);
}
if (p_i45193_9_ != null) if (p_i45193_9_ != null)
{ {

View file

@ -263,8 +263,8 @@ public abstract class Vars {
public static int eggTimer = 6000; public static int eggTimer = 6000;
@Var(name = "spawnMoreZombies") @Var(name = "spawnMoreZombies")
public static int spawnMoreZombie = 25; public static int spawnMoreZombie = 25;
@Var(name = "explosionBlocksPerTick", min = 100, max = 100000) @Var(name = "explosionBlocksPerTick", min = 100, max = 10000000)
public static int maxExplosionIters = 1024; public static int maxExplosionIters = 1000000;
@Var(name = "viewDistance", min = 2, max = 16) @Var(name = "viewDistance", min = 2, max = 16)
public static int distance = 8; public static int distance = 8;
@Var(name = "timeFlow", min = 0) @Var(name = "timeFlow", min = 0)

View file

@ -307,7 +307,7 @@ public abstract class Chunk {
return this.getBlock0(pos.getX() & 15, pos.getY(), pos.getZ() & 15); return this.getBlock0(pos.getX() & 15, pos.getY(), pos.getZ() & 15);
} }
public State setState(BlockPos pos, State state) { public State setState(BlockPos pos, State state, boolean updateLight) {
int x = pos.getX() & 15; int x = pos.getX() & 15;
int y = pos.getY(); int y = pos.getY();
int z = pos.getZ() & 15; int z = pos.getZ() & 15;
@ -354,24 +354,26 @@ public abstract class Chunk {
return null; return null;
} }
else { else {
if(up) { if(updateLight) {
this.genSkyLight(); if(up) {
} this.genSkyLight();
else { }
int b = block.getLightOpacity(); else {
int ob = oldb.getLightOpacity(); int b = block.getLightOpacity();
int ob = oldb.getLightOpacity();
if(b > 0) { if(b > 0) {
if(y >= h) { if(y >= h) {
this.relightBlock(x, y + 1, z); this.relightBlock(x, y + 1, z);
}
}
else if(y == h - 1) {
this.relightBlock(x, y, z);
} }
}
else if(y == h - 1) {
this.relightBlock(x, y, z);
}
if(b != ob && (b < ob || this.getLight(LightType.SKY, pos) > 0 || this.getLight(LightType.BLOCK, pos) > 0)) { if(b != ob && (b < ob || this.getLight(LightType.SKY, pos) > 0 || this.getLight(LightType.BLOCK, pos) > 0)) {
this.propagateOcclusion(x, z); this.propagateOcclusion(x, z);
}
} }
} }

View file

@ -94,56 +94,6 @@ public class Explosion
this.isSmoking = smoking; this.isSmoking = smoking;
} }
public void doExplosionAlgo1(Set<BlockPos> set)
{
int i = 16;
for (int j = 0; j < 16; ++j)
{
for (int k = 0; k < 16; ++k)
{
for (int l = 0; l < 16; ++l)
{
if (j == 0 || j == 15 || k == 0 || k == 15 || l == 0 || l == 15)
{
double d0 = (double)((float)j / 15.0F * 2.0F - 1.0F);
double d1 = (double)((float)k / 15.0F * 2.0F - 1.0F);
double d2 = (double)((float)l / 15.0F * 2.0F - 1.0F);
double d3 = Math.sqrt(d0 * d0 + d1 * d1 + d2 * d2);
d0 = d0 / d3;
d1 = d1 / d3;
d2 = d2 / d3;
float f = this.explosionSize * (0.7F + this.worldObj.rand.floatv() * 0.6F);
double d4 = this.explosionX;
double d6 = this.explosionY;
double d8 = this.explosionZ;
for (float f1 = 0.3F; f > 0.0F; f -= 0.22500001F)
{
BlockPos blockpos = new BlockPos(d4, d6, d8);
State iblockstate = this.worldObj.getState(blockpos);
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);
}
d4 += d0 * 0.30000001192092896D;
d6 += d1 * 0.30000001192092896D;
d8 += d2 * 0.30000001192092896D;
}
}
}
}
}
}
public void doExplosionAlgo2(Set<BlockPos> set) public void doExplosionAlgo2(Set<BlockPos> set)
{ {
int d = ((int)this.explosionSize) + 1; int d = ((int)this.explosionSize) + 1;
@ -199,12 +149,17 @@ public class Explosion
(dist < explosionSize && rand.doublev() + ((dist - (explosionSize - falloff)) / falloff) < 1.0d))) { (dist < explosionSize && rand.doublev() + ((dist - (explosionSize - falloff)) / falloff) < 1.0d))) {
BlockPos blockpos = new BlockPos(explosionX + x, explosionY + y, explosionZ + z); BlockPos blockpos = new BlockPos(explosionX + x, explosionY + y, explosionZ + z);
State iblockstate = worldObj.getState(blockpos); State iblockstate = worldObj.getState(blockpos);
if(iblockstate.getBlock() != Blocks.air && iblockstate.getBlock().getResistance(null) < 60000.0f) { float f = (float)explosionSize;
worldObj.setState(blockpos, Blocks.air.getState(), 3); if(iblockstate.getBlock() != Blocks.air) {
if(rand.chance(1000)) { float f2 = iblockstate.getBlock().getResistance(null);
worldObj.sendSound(SoundEvent.EXPLODE, explosionX + x, explosionY + y, explosionZ + z, 4.0F); f -= (f2 + 0.3F) * 0.3F;
((AWorldServer)worldObj).spawnParticles(ParticleType.EXPLOSION_HUGE, explosionX + x, explosionY + y, explosionZ + z); 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++; cnt++;
} }
@ -237,12 +192,7 @@ public class Explosion
{ {
Set<BlockPos> set = Sets.<BlockPos>newHashSet(); Set<BlockPos> set = Sets.<BlockPos>newHashSet();
if(this.explosionSize <= 8.0d) { this.doExplosionAlgo2(set);
this.doExplosionAlgo1(set);
}
else {
this.doExplosionAlgo2(set);
}
this.affectedBlockPositions.addAll(set); this.affectedBlockPositions.addAll(set);
float f3 = this.explosionSize * 2.0F; float f3 = this.explosionSize * 2.0F;
@ -317,7 +267,7 @@ public class Explosion
State state = this.worldObj.getState(blockpos); State state = this.worldObj.getState(blockpos);
Block block = state.getBlock(); Block block = state.getBlock();
if (spawnParticles) if (this.worldObj.client && spawnParticles /* && (this.explosionSize < 40.0F || this.worldObj.rand.chance(1000)) */)
{ {
double d0 = (double)((float)blockpos.getX() + this.worldObj.rand.floatv()); double d0 = (double)((float)blockpos.getX() + this.worldObj.rand.floatv());
double d1 = (double)((float)blockpos.getY() + this.worldObj.rand.floatv()); double d1 = (double)((float)blockpos.getY() + this.worldObj.rand.floatv());
@ -326,20 +276,20 @@ public class Explosion
this.worldObj.clientParticle(ParticleType.SMOKE, d0, d1, d2); this.worldObj.clientParticle(ParticleType.SMOKE, d0, d1, d2);
} }
if (block != Blocks.air) if (!this.worldObj.client && block != Blocks.air)
{ {
if (block.canDrop(this)) if (block.canDrop(this))
{ {
block.drop(this.worldObj, blockpos, this.worldObj.getState(blockpos), 1.0F / this.explosionSize, 0); block.drop(this.worldObj, blockpos, this.worldObj.getState(blockpos), 1.0F / this.explosionSize, 0);
} }
this.worldObj.setState(blockpos, Blocks.air.getState(), 3); this.worldObj.setState(blockpos, Blocks.air.getState(), this.explosionSize < 40.0F ? 2 : 10);
block.onDestroyedExplosion(this.worldObj, blockpos, this, state); block.onDestroyedExplosion(this.worldObj, blockpos, this, state);
} }
} }
} }
if (this.isFlaming) if (!this.worldObj.client && this.isFlaming)
{ {
for (BlockPos blockpos1 : this.affectedBlockPositions) for (BlockPos blockpos1 : this.affectedBlockPositions)
{ {

View file

@ -176,7 +176,7 @@ public abstract class World implements IWorldAccess {
return false; return false;
Chunk chunk = this.getChunk(pos); Chunk chunk = this.getChunk(pos);
Block block = newState.getBlock(); Block block = newState.getBlock();
State iblockstate = chunk.setState(pos, newState); State iblockstate = chunk.setState(pos, newState, true);
if(iblockstate == null) if(iblockstate == null)
return false; return false;
Block block1 = iblockstate.getBlock(); Block block1 = iblockstate.getBlock();

View file

@ -1867,11 +1867,11 @@ public final class WorldServer extends AWorldServer {
return false; return false;
Chunk chunk = this.getChunk(pos); Chunk chunk = this.getChunk(pos);
Block block = newState.getBlock(); Block block = newState.getBlock();
State iblockstate = chunk.setState(pos, newState); State iblockstate = chunk.setState(pos, newState, (flags & 8) == 0);
if(iblockstate == null) if(iblockstate == null)
return false; return false;
Block block1 = iblockstate.getBlock(); Block block1 = iblockstate.getBlock();
if(block.getLightOpacity() != block1.getLightOpacity() || block.getLight() != block1.getLight()) if((flags & 8) == 0 && (block.getLightOpacity() != block1.getLightOpacity() || block.getLight() != block1.getLight()))
this.checkLight(pos); this.checkLight(pos);
if((flags & 2) != 0 && chunk.isPopulated()) if((flags & 2) != 0 && chunk.isPopulated())
this.markBlockForUpdate(pos); this.markBlockForUpdate(pos);
@ -1894,7 +1894,7 @@ public final class WorldServer extends AWorldServer {
} }
return true; return true;
} }
State successState = chunk.setState(pos, newState); State successState = chunk.setState(pos, newState, true);
boolean successful = successState != null; boolean successful = successState != null;
if(successful) { if(successful) {
if(block.getData() != null) { if(block.getData() != null) {