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.util.ArrayList;
import java.util.List;
import java.util.Set;
import common.collect.Lists;
import common.collect.Sets;
import common.network.IClientPlayer;
import common.network.Packet;
import common.network.PacketBuffer;
import common.rng.Random;
import common.util.BlockPos;
import common.util.Vec3;
@ -34,7 +37,18 @@ public class SPacketExplosion implements Packet<IClientPlayer>
this.posZ = z;
this.strength = strengthIn;
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)
{

View file

@ -263,8 +263,8 @@ public abstract class Vars {
public static int eggTimer = 6000;
@Var(name = "spawnMoreZombies")
public static int spawnMoreZombie = 25;
@Var(name = "explosionBlocksPerTick", min = 100, max = 100000)
public static int maxExplosionIters = 1024;
@Var(name = "explosionBlocksPerTick", min = 100, max = 10000000)
public static int maxExplosionIters = 1000000;
@Var(name = "viewDistance", min = 2, max = 16)
public static int distance = 8;
@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);
}
public State setState(BlockPos pos, State state) {
public State setState(BlockPos pos, State state, boolean updateLight) {
int x = pos.getX() & 15;
int y = pos.getY();
int z = pos.getZ() & 15;
@ -354,24 +354,26 @@ public abstract class Chunk {
return null;
}
else {
if(up) {
this.genSkyLight();
}
else {
int b = block.getLightOpacity();
int ob = oldb.getLightOpacity();
if(b > 0) {
if(y >= h) {
this.relightBlock(x, y + 1, z);
if(updateLight) {
if(up) {
this.genSkyLight();
}
else {
int b = block.getLightOpacity();
int ob = oldb.getLightOpacity();
if(b > 0) {
if(y >= h) {
this.relightBlock(x, y + 1, 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)) {
this.propagateOcclusion(x, 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)) {
this.propagateOcclusion(x, z);
}
}

View file

@ -94,56 +94,6 @@ public class Explosion
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)
{
int d = ((int)this.explosionSize) + 1;
@ -199,12 +149,17 @@ public class Explosion
(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);
if(iblockstate.getBlock() != Blocks.air && iblockstate.getBlock().getResistance(null) < 60000.0f) {
worldObj.setState(blockpos, Blocks.air.getState(), 3);
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);
}
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++;
}
@ -237,12 +192,7 @@ public class Explosion
{
Set<BlockPos> set = Sets.<BlockPos>newHashSet();
if(this.explosionSize <= 8.0d) {
this.doExplosionAlgo1(set);
}
else {
this.doExplosionAlgo2(set);
}
this.doExplosionAlgo2(set);
this.affectedBlockPositions.addAll(set);
float f3 = this.explosionSize * 2.0F;
@ -317,7 +267,7 @@ public class Explosion
State state = this.worldObj.getState(blockpos);
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 d1 = (double)((float)blockpos.getY() + this.worldObj.rand.floatv());
@ -326,20 +276,20 @@ public class Explosion
this.worldObj.clientParticle(ParticleType.SMOKE, d0, d1, d2);
}
if (block != Blocks.air)
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);
}
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);
}
}
}
if (this.isFlaming)
if (!this.worldObj.client && this.isFlaming)
{
for (BlockPos blockpos1 : this.affectedBlockPositions)
{

View file

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

View file

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