geforkt von Mirrors/Paper
116 Zeilen
5.7 KiB
Diff
116 Zeilen
5.7 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Lixfel <agga-games@gmx.de>
|
|
Date: Fri, 23 Jun 2023 15:59:15 +0200
|
|
Subject: [PATCH] Optimize explosion with cache
|
|
|
|
|
|
diff --git a/src/main/java/net/minecraft/world/level/Explosion.java b/src/main/java/net/minecraft/world/level/Explosion.java
|
|
index 8f97c9df726ac20cfce7bdddd5dd4f8c5aa76c35..0b9211837b0353a09b3202055e27a144e9d7ccfa 100644
|
|
--- a/src/main/java/net/minecraft/world/level/Explosion.java
|
|
+++ b/src/main/java/net/minecraft/world/level/Explosion.java
|
|
@@ -7,6 +7,7 @@ import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
|
import it.unimi.dsi.fastutil.objects.ObjectListIterator;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
+import java.util.HashMap;
|
|
import java.util.Optional;
|
|
import java.util.Set;
|
|
import javax.annotation.Nullable;
|
|
@@ -135,6 +136,33 @@ public class Explosion {
|
|
}
|
|
}
|
|
|
|
+ private class BlockCache {
|
|
+ private final BlockState state;
|
|
+ private final float blastResistance;
|
|
+ private boolean destroyed;
|
|
+
|
|
+ private BlockCache(BlockPos blockPos) {
|
|
+ state = level.getBlockState(blockPos);
|
|
+ if (!state.isDestroyable()) {
|
|
+ blastResistance = 3_600_000.0f;
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ if (!level.isInWorldBounds(blockPos)) {
|
|
+ blastResistance = 3_600_000.0f;
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ Optional<Float> optional = damageCalculator.getBlockExplosionResistance(Explosion.this, level, blockPos, state, state.getFluidState());
|
|
+ blastResistance = optional.map(resistance -> (resistance + 0.3F) * 0.3F).orElse(0.0f);
|
|
+ }
|
|
+
|
|
+ private BlockCache(BlockState state, float blastResistance) {
|
|
+ this.state = state;
|
|
+ this.blastResistance = blastResistance;
|
|
+ }
|
|
+ }
|
|
+
|
|
public void explode() {
|
|
// CraftBukkit start
|
|
if (this.radius < 0.1F) {
|
|
@@ -142,12 +170,12 @@ public class Explosion {
|
|
}
|
|
// CraftBukkit end
|
|
this.level.gameEvent(this.source, GameEvent.EXPLODE, new Vec3(this.x, this.y, this.z));
|
|
- Set<BlockPos> set = Sets.newHashSet();
|
|
boolean flag = true;
|
|
|
|
int i;
|
|
int j;
|
|
|
|
+ Map<BlockPos, BlockCache> cache = new HashMap<>();
|
|
for (int k = 0; k < 16; ++k) {
|
|
for (i = 0; i < 16; ++i) {
|
|
for (j = 0; j < 16; ++j) {
|
|
@@ -167,28 +195,18 @@ public class Explosion {
|
|
|
|
for (float f1 = 0.3F; f > 0.0F; f -= 0.22500001F) {
|
|
BlockPos blockposition = BlockPos.containing(d4, d5, d6);
|
|
- BlockState iblockdata = this.level.getBlockState(blockposition);
|
|
- if (!iblockdata.isDestroyable()) continue; // Paper
|
|
- FluidState fluid = iblockdata.getFluidState(); // Paper
|
|
-
|
|
- if (!this.level.isInWorldBounds(blockposition)) {
|
|
- break;
|
|
- }
|
|
+ BlockCache cacheEntry = cache.computeIfAbsent(blockposition, BlockCache::new);
|
|
|
|
- Optional<Float> optional = this.damageCalculator.getBlockExplosionResistance(this, this.level, blockposition, iblockdata, fluid);
|
|
+ f -= cacheEntry.blastResistance;
|
|
|
|
- if (optional.isPresent()) {
|
|
- f -= ((Float) optional.get() + 0.3F) * 0.3F;
|
|
- }
|
|
-
|
|
- if (f > 0.0F && this.damageCalculator.shouldBlockExplode(this, this.level, blockposition, iblockdata, f)) {
|
|
- set.add(blockposition);
|
|
+ if (f > 0.0F && this.damageCalculator.shouldBlockExplode(this, this.level, blockposition, cacheEntry.state, f)) {
|
|
+ cacheEntry.destroyed = true;
|
|
// Paper start - prevent headless pistons from forming
|
|
- if (!io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.allowHeadlessPistons && iblockdata.getBlock() == Blocks.MOVING_PISTON) {
|
|
+ if (!io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.allowHeadlessPistons && cacheEntry.state.getBlock() == Blocks.MOVING_PISTON) {
|
|
BlockEntity extension = this.level.getBlockEntity(blockposition);
|
|
if (extension instanceof net.minecraft.world.level.block.piston.PistonMovingBlockEntity blockEntity && blockEntity.isSourcePiston()) {
|
|
- net.minecraft.core.Direction direction = iblockdata.getValue(net.minecraft.world.level.block.piston.PistonHeadBlock.FACING);
|
|
- set.add(blockposition.relative(direction.getOpposite()));
|
|
+ net.minecraft.core.Direction direction = cacheEntry.state.getValue(net.minecraft.world.level.block.piston.PistonHeadBlock.FACING);
|
|
+ cache.computeIfAbsent(blockposition.relative(direction.getOpposite()), BlockCache::new).destroyed = true;
|
|
}
|
|
}
|
|
// Paper end
|
|
@@ -203,7 +221,11 @@ public class Explosion {
|
|
}
|
|
}
|
|
|
|
- this.toBlow.addAll(set);
|
|
+ for(Map.Entry<BlockPos, BlockCache> entry : cache.entrySet()) {
|
|
+ if(entry.getValue().destroyed)
|
|
+ toBlow.add(entry.getKey());
|
|
+ }
|
|
+
|
|
float f2 = this.radius * 2.0F;
|
|
|
|
i = Mth.floor(this.x - (double) f2 - 1.0D);
|