Skip to content

Commit

Permalink
feat: Explosion optimizations (#88)
Browse files Browse the repository at this point in the history
  • Loading branch information
notdevcody authored Apr 29, 2024
1 parent 19db456 commit d1e725b
Showing 1 changed file with 55 additions and 48 deletions.
103 changes: 55 additions & 48 deletions src/main/java/net/minecraft/server/Explosion.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,24 @@
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.entity.EntityExplodeEvent;
import org.jetbrains.annotations.NotNull;

import java.util.*;

// CraftBukkit start
// CraftBukkit end

public class Explosion {

public boolean setFire = false;
private Random h = new Random();
private World world;
private final Random random = new Random();
private final World world;
public double posX;
public double posY;
public double posZ;
public Entity source;
public EntityDamageEvent.DamageCause customDamageCause = null; // Poseidon
public float size;
public Set blocks = new HashSet();
public Set<ChunkPosition> blocks = new HashSet<>(); // UberBukkit: Set -> Set<ChunkPosition>

public boolean wasCanceled = false; // CraftBukkit

Expand Down Expand Up @@ -51,9 +51,9 @@ public void a() {
for (j = 0; j < b0; ++j) {
for (k = 0; k < b0; ++k) {
if (i == 0 || i == b0 - 1 || j == 0 || j == b0 - 1 || k == 0 || k == b0 - 1) {
double d3 = (double) ((float) i / ((float) b0 - 1.0F) * 2.0F - 1.0F);
double d4 = (double) ((float) j / ((float) b0 - 1.0F) * 2.0F - 1.0F);
double d5 = (double) ((float) k / ((float) b0 - 1.0F) * 2.0F - 1.0F);
double d3 = ((float) i / ((float) b0 - 1.0F) * 2.0F - 1.0F);
double d4 = ((float) j / ((float) b0 - 1.0F) * 2.0F - 1.0F);
double d5 = ((float) k / ((float) b0 - 1.0F) * 2.0F - 1.0F);
double d6 = Math.sqrt(d3 * d3 + d4 * d4 + d5 * d5);

d3 /= d6;
Expand Down Expand Up @@ -95,7 +95,7 @@ public void a() {
int l1 = MathHelper.floor(this.posY + (double) this.size + 1.0D);
int i2 = MathHelper.floor(this.posZ - (double) this.size - 1.0D);
int j2 = MathHelper.floor(this.posZ + (double) this.size + 1.0D);
List list = this.world.b(this.source, AxisAlignedBB.b((double) i, (double) k, (double) i2, (double) j, (double) l1, (double) j2));
List list = this.world.b(this.source, AxisAlignedBB.b(i, k, i2, j, l1, j2));
Vec3D vec3d = Vec3D.create(this.posX, this.posY, this.posZ);

/*
Expand All @@ -115,7 +115,7 @@ public void a() {
d0 = entity.locX - this.posX;
d1 = entity.locY - this.posY;
d2 = entity.locZ - this.posZ;
double d8 = (double) MathHelper.a(d0 * d0 + d1 * d1 + d2 * d2);
double d8 = MathHelper.a(d0 * d0 + d1 * d1 + d2 * d2);

d0 /= d8;
d1 /= d8;
Expand All @@ -124,7 +124,7 @@ public void a() {
if (optimizeExplosions) {
d9 = this.getBlockDensity(vec3d, entity); // Paper - Optimize explosions
} else {
d9 = (double) this.world.a(vec3d, entity.boundingBox);
d9 = this.world.a(vec3d, entity.boundingBox);
}
double d10 = (1.0D - d7) * d9;

Expand All @@ -133,19 +133,11 @@ public void a() {
org.bukkit.entity.Entity damagee = (entity == null) ? null : entity.getBukkitEntity();
int damageDone = (int) ((d10 * d10 + d10) / 2.0D * 8.0D * (double) this.size + 1.0D);

if (damagee == null) {
// nothing was hurt
} else if (this.source == null || this.source instanceof EntityTNTPrimed) { // Block explosion
//This event gets fired by tnt, exploding beds, and explosions created by plugins
// Block explosion, damagee is not null
if (damagee != null && (this.source == null || this.source instanceof EntityTNTPrimed)) {
// This event gets fired by tnt, exploding beds, and explosions created by plugins
// TODO: get the x/y/z of the tnt block?
EntityDamageByBlockEvent event;
if (this.customDamageCause != null) {
event = new EntityDamageByBlockEvent(null, damagee, this.customDamageCause, damageDone);
} else if (this.source instanceof EntityTNTPrimed) {
event = new EntityDamageByBlockEvent(null, damagee, EntityDamageEvent.DamageCause.TNT_EXPLOSION, damageDone);
} else {
event = new EntityDamageByBlockEvent(null, damagee, EntityDamageEvent.DamageCause.BLOCK_EXPLOSION, damageDone);
}
EntityDamageByBlockEvent event = getEntityDamageByBlockEvent(damagee, damageDone);
server.getPluginManager().callEvent(event);

if (!event.isCancelled()) {
Expand Down Expand Up @@ -176,39 +168,56 @@ public void a() {
}

this.size = f;
ArrayList arraylist = new ArrayList();

arraylist.addAll(this.blocks);
ArrayList<ChunkPosition> arraylist = new ArrayList<>(this.blocks);
if (this.setFire) {
for (int l2 = arraylist.size() - 1; l2 >= 0; --l2) {
ChunkPosition chunkposition = (ChunkPosition) arraylist.get(l2);
ChunkPosition chunkposition = arraylist.get(l2);
int i3 = chunkposition.x;
int j3 = chunkposition.y;
int k3 = chunkposition.z;
int l3 = this.world.getTypeId(i3, j3, k3);
int i4 = this.world.getTypeId(i3, j3 - 1, k3);

if (l3 == 0 && Block.o[i4] && this.h.nextInt(3) == 0) {
if (l3 == 0 && Block.o[i4] && this.random.nextInt(3) == 0) {
this.world.setTypeId(i3, j3, k3, Block.FIRE.id);
}
}
}
}

@NotNull
private EntityDamageByBlockEvent getEntityDamageByBlockEvent(org.bukkit.entity.Entity damagee, int damageDone) {
EntityDamageByBlockEvent event;
if (this.customDamageCause != null) {
event = new EntityDamageByBlockEvent(null, damagee, this.customDamageCause, damageDone);
} else if (this.source instanceof EntityTNTPrimed) {
event = new EntityDamageByBlockEvent(null, damagee, EntityDamageEvent.DamageCause.TNT_EXPLOSION, damageDone);
} else {
event = new EntityDamageByBlockEvent(null, damagee, EntityDamageEvent.DamageCause.BLOCK_EXPLOSION, damageDone);
}
return event;
}

public void a(boolean flag) {
this.world.makeSound(this.posX, this.posY, this.posZ, "random.explode", 4.0F, (1.0F + (this.world.random.nextFloat() - this.world.random.nextFloat()) * 0.2F) * 0.7F);
ArrayList arraylist = new ArrayList();

arraylist.addAll(this.blocks);
ArrayList<ChunkPosition> blocksCopy = new ArrayList<>(this.blocks);

// CraftBukkit start
org.bukkit.World bworld = this.world.getWorld();
org.bukkit.entity.Entity explode = this.source == null ? null : this.source.getBukkitEntity();
Location location = new Location(bworld, this.posX, this.posY, this.posZ);

List<org.bukkit.block.Block> blockList = new ArrayList<org.bukkit.block.Block>();
for (int j = arraylist.size() - 1; j >= 0; j--) {
ChunkPosition cpos = (ChunkPosition) arraylist.get(j);
List<org.bukkit.block.Block> blockList = new ArrayList<>();
for (int j = blocksCopy.size() - 1; j >= 0; j--) {
ChunkPosition cpos = blocksCopy.get(j);
// UberBukkit - No need to handle blocks that aren't in the world's boundaries
if (cpos.y > 127 || cpos.y < 0) {
blocksCopy.remove(j);
continue;
}

org.bukkit.block.Block block = bworld.getBlockAt(cpos.x, cpos.y, cpos.z);
if (block.getType() != org.bukkit.Material.AIR) {
blockList.add(block);
Expand All @@ -222,44 +231,45 @@ public void a(boolean flag) {
this.wasCanceled = true;
return;
}
//Project Poseidon Start
//Credit to Notcz in Modification Station
arraylist.clear();

// Project Poseidon Start
// Backport from newer CraftBukkit
blocksCopy.clear();
this.blocks.clear();
for (final org.bukkit.block.Block block2 : event.blockList()) {
final ChunkPosition coords = new ChunkPosition(block2.getX(), block2.getY(), block2.getZ());
arraylist.add(coords);
blocksCopy.add(coords);
this.blocks.add(coords);
}
//Project Poseidon End
// Project Poseidon End
// CraftBukkit end

for (int i = arraylist.size() - 1; i >= 0; --i) {
ChunkPosition chunkposition = (ChunkPosition) arraylist.get(i);
for (int i = blocksCopy.size() - 1; i >= 0; --i) {
ChunkPosition chunkposition = blocksCopy.get(i);
int j = chunkposition.x;
int k = chunkposition.y;
int l = chunkposition.z;
int i1 = this.world.getTypeId(j, k, l);

if (flag) {
double d0 = (double) ((float) j + this.world.random.nextFloat());
double d1 = (double) ((float) k + this.world.random.nextFloat());
double d2 = (double) ((float) l + this.world.random.nextFloat());
double d0 = (float) j + this.world.random.nextFloat();
double d1 = (float) k + this.world.random.nextFloat();
double d2 = (float) l + this.world.random.nextFloat();
double d3 = d0 - this.posX;
double d4 = d1 - this.posY;
double d5 = d2 - this.posZ;
double d6 = (double) MathHelper.a(d3 * d3 + d4 * d4 + d5 * d5);
double d6 = MathHelper.a(d3 * d3 + d4 * d4 + d5 * d5);

d3 /= d6;
d4 /= d6;
d5 /= d6;
double d7 = 0.5D / (d6 / (double) this.size + 0.1D);

d7 *= (double) (this.world.random.nextFloat() * this.world.random.nextFloat() + 0.3F);
d7 *= this.world.random.nextFloat() * this.world.random.nextFloat() + 0.3F;
d3 *= d7;
d4 *= d7;
d5 *= d7;
this.world.a("explode", (d0 + this.posX * 1.0D) / 2.0D, (d1 + this.posY * 1.0D) / 2.0D, (d2 + this.posZ * 1.0D) / 2.0D, d3, d4, d5);
this.world.a("explode", (d0 + this.posX) / 2.0D, (d1 + this.posY) / 2.0D, (d2 + this.posZ) / 2.0D, d3, d4, d5);
this.world.a("smoke", d0, d1, d2, d3, d4, d5);
}

Expand All @@ -275,9 +285,6 @@ public void a(boolean flag) {

// Paper start - Optimize explosions
private float getBlockDensity(Vec3D vec3d, Entity entity) {
/*if (!this.world.paperConfig.optimizeExplosions) {
return a(vec3d, entity);
}*/
CacheKey key = new CacheKey(this, entity.boundingBox);
Float blockDensity = this.world.explosionDensityCache.get(key);
if (blockDensity == null) {
Expand Down Expand Up @@ -353,4 +360,4 @@ public int hashCode() {
}
}
// Paper end
}
}

0 comments on commit d1e725b

Please sign in to comment.