mirror of
https://github.com/Winds-Studio/Leaf.git
synced 2025-12-25 18:09:17 +00:00
i pushed this but need someone to test before and after for sake of testing
This commit is contained in:
@@ -0,0 +1,246 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Taiyou06 <kaandindar21@gmail.com>
|
||||
Date: Wed, 9 Apr 2025 18:46:23 +0200
|
||||
Subject: [PATCH] Optimize applyEffectsFromBlocks and checkInsideBlocks
|
||||
|
||||
|
||||
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
|
||||
index 075fcbcde23b5bb7b27ff622e8d188c3a2583973..3a791927fa33be4346f28b55325a0340445731ae 100644
|
||||
--- a/net/minecraft/world/entity/Entity.java
|
||||
+++ b/net/minecraft/world/entity/Entity.java
|
||||
@@ -9,6 +9,8 @@ import com.mojang.logging.LogUtils;
|
||||
import it.unimi.dsi.fastutil.floats.FloatArraySet;
|
||||
import it.unimi.dsi.fastutil.floats.FloatArrays;
|
||||
import it.unimi.dsi.fastutil.floats.FloatSet;
|
||||
+import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
+import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
|
||||
import it.unimi.dsi.fastutil.longs.LongSet;
|
||||
import it.unimi.dsi.fastutil.objects.Object2DoubleArrayMap;
|
||||
@@ -832,7 +834,12 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
}
|
||||
|
||||
protected AABB makeBoundingBox(Vec3 position) {
|
||||
- return this.dimensions.makeBoundingBox(position);
|
||||
+ if (this.lastDimensions == null || this.lastDimensions.width() != this.dimensions.width() || this.lastDimensions.height() != this.dimensions.height()) {
|
||||
+ this.lastDimensions = this.dimensions;
|
||||
+ this.cachedBoundingBox = this.dimensions.makeBoundingBox(Vec3.ZERO);
|
||||
+ }
|
||||
+
|
||||
+ return this.cachedBoundingBox.move(position);
|
||||
}
|
||||
|
||||
protected void reapplyPosition() {
|
||||
@@ -1351,33 +1358,56 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
}
|
||||
|
||||
public void applyEffectsFromBlocks(Vec3 oldPosition, Vec3 position) {
|
||||
- if (this.isAffectedByBlocks()) {
|
||||
- if (this.onGround()) {
|
||||
- BlockPos onPosLegacy = this.getOnPosLegacy();
|
||||
+ if (!this.isAffectedByBlocks()) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (this.onGround()) {
|
||||
+ BlockPos onPosLegacy = this.getOnPosLegacy();
|
||||
+ if (this.cachedSupportingBlockState == null || !this.isSupportedBy(onPosLegacy)) {
|
||||
BlockState blockState = this.level().getBlockState(onPosLegacy);
|
||||
blockState.getBlock().stepOn(this.level(), onPosLegacy, blockState, this);
|
||||
+ this.cachedSupportingBlockState = blockState;
|
||||
+ } else {
|
||||
+ this.cachedSupportingBlockState.getBlock().stepOn(this.level(), onPosLegacy, this.cachedSupportingBlockState, this);
|
||||
}
|
||||
+ }
|
||||
|
||||
+ if (oldPosition.distanceToSqr(position) > 1.0E-8) {
|
||||
this.movementThisTick.add(new Entity.Movement(oldPosition, position));
|
||||
- List<Entity.Movement> list = List.copyOf(this.movementThisTick);
|
||||
- this.movementThisTick.clear();
|
||||
- this.checkInsideBlocks(list, this.blocksInside);
|
||||
- boolean flag = Iterables.any(this.blocksInside, state -> state.is(BlockTags.FIRE) || state.is(Blocks.LAVA));
|
||||
- this.blocksInside.clear();
|
||||
- if (!flag && this.isAlive()) {
|
||||
- if (this.remainingFireTicks <= 0) {
|
||||
- this.setRemainingFireTicks(-this.getFireImmuneTicks());
|
||||
- }
|
||||
+ }
|
||||
|
||||
- if (this.wasOnFire && (this.isInPowderSnow || this.isInWaterRainOrBubble())) {
|
||||
- this.playEntityOnFireExtinguishedSound();
|
||||
- }
|
||||
+ if (this.movementThisTick.isEmpty()) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ this.checkInsideBlocks(this.movementThisTick, this.blocksInside);
|
||||
+
|
||||
+ boolean inFireOrLava = false;
|
||||
+ for (BlockState state : this.blocksInside) {
|
||||
+ if (state.is(BlockTags.FIRE) || state.is(Blocks.LAVA)) {
|
||||
+ inFireOrLava = true;
|
||||
+ break;
|
||||
}
|
||||
+ }
|
||||
+
|
||||
+ this.movementThisTick.clear();
|
||||
|
||||
- if (this.isOnFire() && (this.isInPowderSnow || this.isInWaterRainOrBubble())) {
|
||||
+ if (!inFireOrLava && this.isAlive()) {
|
||||
+ if (this.remainingFireTicks <= 0) {
|
||||
this.setRemainingFireTicks(-this.getFireImmuneTicks());
|
||||
}
|
||||
+
|
||||
+ if (this.wasOnFire && (this.isInPowderSnow || this.isInWaterRainOrBubble())) {
|
||||
+ this.playEntityOnFireExtinguishedSound();
|
||||
+ }
|
||||
}
|
||||
+
|
||||
+ if (this.isOnFire() && (this.isInPowderSnow || this.isInWaterRainOrBubble())) {
|
||||
+ this.setRemainingFireTicks(-this.getFireImmuneTicks());
|
||||
+ }
|
||||
+
|
||||
+ this.blocksInside.clear();
|
||||
}
|
||||
|
||||
public boolean isAffectedByBlocks() {
|
||||
@@ -1706,50 +1736,109 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
public void recordMovementThroughBlocks(Vec3 oldPosition, Vec3 position) {
|
||||
this.movementThisTick.add(new Entity.Movement(oldPosition, position));
|
||||
}
|
||||
+ private final Int2ObjectMap<BlockState> blockStateCache = new Int2ObjectOpenHashMap<>(16);
|
||||
+ private BlockPos lastBlockPos = BlockPos.ZERO;
|
||||
+ private BlockState lastBlockState = null;
|
||||
|
||||
private void checkInsideBlocks(List<Entity.Movement> movements, Set<BlockState> blocksInside) {
|
||||
- if (this.isAffectedByBlocks()) {
|
||||
- LongSet set = this.visitedBlocks;
|
||||
+ if (!this.isAffectedByBlocks()) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ this.visitedBlocks.clear();
|
||||
+ this.blockStateCache.clear();
|
||||
+
|
||||
+ for (Entity.Movement movement : movements) {
|
||||
+ Vec3 fromPos = movement.from();
|
||||
+ Vec3 toPos = movement.to();
|
||||
|
||||
- for (Entity.Movement movement : movements) {
|
||||
- Vec3 vec3 = movement.from();
|
||||
- Vec3 vec31 = movement.to();
|
||||
- AABB aabb = this.makeBoundingBox(vec31).deflate(1.0E-5F);
|
||||
+ if (fromPos.distanceToSqr(toPos) < 1.0E-8) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ AABB aabb = this.makeBoundingBox(toPos).deflate(1.0E-5F);
|
||||
+
|
||||
+ int minX = Mth.floor(Math.min(fromPos.x, toPos.x) - aabb.getXsize()/2);
|
||||
+ int maxX = Mth.ceil(Math.max(fromPos.x, toPos.x) + aabb.getXsize()/2);
|
||||
+ int minY = Mth.floor(Math.min(fromPos.y, toPos.y) - aabb.getYsize()/2);
|
||||
+ int maxY = Mth.ceil(Math.max(fromPos.y, toPos.y) + aabb.getYsize()/2);
|
||||
+ int minZ = Mth.floor(Math.min(fromPos.z, toPos.z) - aabb.getZsize()/2);
|
||||
+ int maxZ = Mth.ceil(Math.max(fromPos.z, toPos.z) + aabb.getZsize()/2);
|
||||
+
|
||||
+ int minChunkX = minX >> 4;
|
||||
+ int maxChunkX = maxX >> 4;
|
||||
+ int minChunkZ = minZ >> 4;
|
||||
+ int maxChunkZ = maxZ >> 4;
|
||||
|
||||
- for (BlockPos blockPos : BlockGetter.boxTraverseBlocks(vec3, vec31, aabb)) {
|
||||
- if (!this.isAlive()) {
|
||||
- return;
|
||||
+ BlockPos.MutableBlockPos mutablePos = new BlockPos.MutableBlockPos();
|
||||
+
|
||||
+ for (int chunkX = minChunkX; chunkX <= maxChunkX; chunkX++) {
|
||||
+ for (int chunkZ = minChunkZ; chunkZ <= maxChunkZ; chunkZ++) {
|
||||
+ if (!level().hasChunkAt(chunkX, chunkZ)) {
|
||||
+ continue;
|
||||
}
|
||||
|
||||
- BlockState blockState = this.level().getBlockState(blockPos);
|
||||
- if (!blockState.isAir() && set.add(blockPos.asLong())) {
|
||||
- try {
|
||||
- VoxelShape entityInsideCollisionShape = blockState.getEntityInsideCollisionShape(this.level(), blockPos);
|
||||
- if (entityInsideCollisionShape != Shapes.block()
|
||||
- && !this.collidedWithShapeMovingFrom(vec3, vec31, blockPos, entityInsideCollisionShape)) {
|
||||
- continue;
|
||||
- }
|
||||
+ int xStart = Math.max(minX, chunkX << 4);
|
||||
+ int xEnd = Math.min(maxX, (chunkX << 4) + 15);
|
||||
+ int zStart = Math.max(minZ, chunkZ << 4);
|
||||
+ int zEnd = Math.min(maxZ, (chunkZ << 4) + 15);
|
||||
|
||||
- blockState.entityInside(this.level(), blockPos, this);
|
||||
- this.onInsideBlock(blockState);
|
||||
- } catch (Throwable var16) {
|
||||
- CrashReport crashReport = CrashReport.forThrowable(var16, "Colliding entity with block");
|
||||
- CrashReportCategory crashReportCategory = crashReport.addCategory("Block being collided with");
|
||||
- CrashReportCategory.populateBlockDetails(crashReportCategory, this.level(), blockPos, blockState);
|
||||
- CrashReportCategory crashReportCategory1 = crashReport.addCategory("Entity being checked for collision");
|
||||
- this.fillCrashReportCategory(crashReportCategory1);
|
||||
- throw new ReportedException(crashReport);
|
||||
- }
|
||||
+ for (int x = xStart; x <= xEnd; x++) {
|
||||
+ for (int z = zStart; z <= zEnd; z++) {
|
||||
+ for (int y = minY; y <= maxY; y++) {
|
||||
+ if (!this.isAlive()) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ mutablePos.set(x, y, z);
|
||||
+ long posLong = mutablePos.asLong();
|
||||
+
|
||||
+ if (!this.visitedBlocks.add(posLong)) {
|
||||
+ continue;
|
||||
+ }
|
||||
|
||||
- blocksInside.add(blockState);
|
||||
+ BlockState blockState;
|
||||
+ if (mutablePos.equals(this.lastBlockPos)) {
|
||||
+ blockState = this.lastBlockState;
|
||||
+ } else {
|
||||
+ blockState = this.level().getBlockState(mutablePos);
|
||||
+ this.lastBlockPos = mutablePos.immutable();
|
||||
+ this.lastBlockState = blockState;
|
||||
+ }
|
||||
+
|
||||
+ if (blockState.isAir()) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ try {
|
||||
+ VoxelShape entityInsideCollisionShape = blockState.getEntityInsideCollisionShape(this.level(), mutablePos);
|
||||
+ if (entityInsideCollisionShape != Shapes.block() &&
|
||||
+ !this.collidedWithShapeMovingFrom(fromPos, toPos, mutablePos, entityInsideCollisionShape)) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ blockState.entityInside(this.level(), mutablePos, this);
|
||||
+ this.onInsideBlock(blockState);
|
||||
+ blocksInside.add(blockState);
|
||||
+ } catch (Throwable var16) {
|
||||
+ CrashReport crashReport = CrashReport.forThrowable(var16, "Colliding entity with block");
|
||||
+ CrashReportCategory crashReportCategory = crashReport.addCategory("Block being collided with");
|
||||
+ CrashReportCategory.populateBlockDetails(crashReportCategory, this.level(), mutablePos, blockState);
|
||||
+ CrashReportCategory crashReportCategory1 = crashReport.addCategory("Entity being checked for collision");
|
||||
+ this.fillCrashReportCategory(crashReportCategory1);
|
||||
+ throw new ReportedException(crashReport);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
}
|
||||
}
|
||||
-
|
||||
- set.clear();
|
||||
}
|
||||
}
|
||||
|
||||
+ private EntityDimensions lastDimensions = null;
|
||||
+ private AABB cachedBoundingBox = null;
|
||||
+
|
||||
private boolean collidedWithShapeMovingFrom(Vec3 oldPosition, Vec3 position, BlockPos pos, VoxelShape shape) {
|
||||
AABB aabb = this.makeBoundingBox(oldPosition);
|
||||
Vec3 vec3 = position.subtract(oldPosition);
|
||||
Reference in New Issue
Block a user