Paper/patches/server/1008-Optimize-explosion-with-cache.patch
Lixfel c903985792
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Fix patch order
2023-08-19 10:42:16 +02:00

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);