From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Samsuik Date: Fri, 8 Nov 2024 19:35:49 +0000 Subject: [PATCH] Optimise check inside blocks and traverse blocks diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java index 679a377f068ce4f37b2a3e6f446cccc51fb29bf9..d2bd693934b27815e388387b9b9a707d75999cad 100644 --- a/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java @@ -1938,6 +1938,7 @@ public abstract class Entity implements SyncedDataHolder, DebugValueSource, Name if (this.isAffectedByBlocks()) { LongSet set = this.visitedBlocks; final me.samsuik.sakura.mechanics.MinecraftMechanicsTarget mechanicsTarget = this.mechanicsTarget; // Sakura - configure server mechanics + final net.minecraft.world.level.chunk.ChunkAccess[] chunkCache = new net.minecraft.world.level.chunk.ChunkAccess[4]; // Sakura - optimise check inside blocks for (Entity.Movement movement : movements) { Vec3 vec3 = movement.from; @@ -1955,7 +1956,7 @@ public abstract class Entity implements SyncedDataHolder, DebugValueSource, Name double d = vec31.get(axis); if (d != 0.0) { Vec3 vec32 = vec3.relative(axis.getPositive(), d); - final int stepsTaken = this.checkInsideBlocks(vec3, vec32, stepBasedCollector, set, i); + final int stepsTaken = this.checkInsideBlocks(vec3, vec32, stepBasedCollector, set, i, chunkCache); // Sakura - optimise check inside blocks if (mechanicsTarget.atLeast(me.samsuik.sakura.mechanics.MechanicVersion.v1_21_9)) { i -= stepsTaken; } @@ -1963,12 +1964,12 @@ public abstract class Entity implements SyncedDataHolder, DebugValueSource, Name } } } else if (mechanicsTarget.atLeast(me.samsuik.sakura.mechanics.MechanicVersion.v1_21_2)) { - i -= this.checkInsideBlocks(movement.from(), movement.to(), stepBasedCollector, set, 16); + i -= this.checkInsideBlocks(movement.from(), movement.to(), stepBasedCollector, set, 16, chunkCache); // Sakura - optimise check inside blocks } if (i <= 0 || mechanicsTarget.before(me.samsuik.sakura.mechanics.MechanicVersion.v1_21_2)) { // Sakura end - configure server mechanics - this.checkInsideBlocks(movement.to(), movement.to(), stepBasedCollector, set, 1); + this.checkInsideBlocks(movement.to(), movement.to(), stepBasedCollector, set, 1, chunkCache); // Sakura - optimise check inside blocks } } @@ -1976,7 +1977,16 @@ public abstract class Entity implements SyncedDataHolder, DebugValueSource, Name } } - private int checkInsideBlocks(Vec3 from, Vec3 to, InsideBlockEffectApplier.StepBasedCollector stepBasedCollector, LongSet visited, int maxSteps) { + // Sakura start - optimise check inside blocks + private int checkInsideBlocks( + final Vec3 from, + final Vec3 to, + final InsideBlockEffectApplier.StepBasedCollector stepBasedCollector, + final LongSet visited, + final int maxSteps, + final net.minecraft.world.level.chunk.ChunkAccess[] chunkCache + ) { + // Sakura end - optimise check inside blocks // Sakura start - configure server mechanics final me.samsuik.sakura.mechanics.MinecraftMechanicsTarget mechanicsTarget = this.mechanicsTarget; final double margin; @@ -2006,7 +2016,20 @@ public abstract class Entity implements SyncedDataHolder, DebugValueSource, Name return false; } else { atomicInteger.set(index); - BlockState blockState = this.level().getBlockState(pos); + // Sakura start - optimise check inside blocks + final int chunkX = pos.getX() >> 4; + final int chunkZ = pos.getZ() >> 4; + final int chunkKey = ((chunkX << 2) | chunkZ) & 3; + net.minecraft.world.level.chunk.ChunkAccess chunk = chunkCache[chunkKey]; + if (chunk == null || chunk.locX != chunkX || chunk.locZ != chunkZ) { + chunk = this.level().getChunkIfLoadedImmediately(chunkX, chunkZ); + if (chunk == null) { + return true; + } + chunkCache[chunkKey] = chunk; + } + final BlockState blockState = chunk.getBlockState(pos); + // Sakura end - optimise check inside blocks if (blockState.isAir()) { if (flag1) { this.debugBlockIntersection((ServerLevel)this.level(), pos.immutable(), false, false); diff --git a/net/minecraft/world/level/BlockGetter.java b/net/minecraft/world/level/BlockGetter.java index ba2e7efe147b26bea5d73eac1f4b2fe6ee4bd5c2..b9ed6671edc98fe7a4bb30fdd25a6629e852da4f 100644 --- a/net/minecraft/world/level/BlockGetter.java +++ b/net/minecraft/world/level/BlockGetter.java @@ -231,7 +231,7 @@ public interface BlockGetter extends LevelHeightAccessor { : 0.99999F; if (vec3.lengthSqr() < Mth.square(margin) || mechanicsTarget != null && mechanicsTarget.before(me.samsuik.sakura.mechanics.MechanicVersion.v1_21_2)) { // Sakura end - configure server mechanics - for (BlockPos blockPos : BlockPos.betweenClosed(boundingBox)) { + for (final BlockPos blockPos : me.samsuik.sakura.utils.BlockPosIterator.iterable(boundingBox)) { // Sakura - optimise check inside blocks if (!visitor.visit(blockPos, 0)) { return false; } @@ -239,9 +239,22 @@ public interface BlockGetter extends LevelHeightAccessor { return true; } else { + // Sakura start - optimise check inside blocks + final boolean xZero = vec3.x() == 0.0; + final boolean yZero = vec3.y() == 0.0; + final boolean zZero = vec3.z() == 0.0; + if (xZero && yZero || yZero && zZero || xZero && zZero) { + for (final BlockPos blockPos : me.samsuik.sakura.utils.BlockPosIterator.traverseArea(vec3, boundingBox)) { + if (!visitor.visit(blockPos, 0)) { + return false; + } + } + return true; + } + // Sakura end - optimise check inside blocks LongSet set = new LongOpenHashSet(); - for (BlockPos blockPos1 : BlockPos.betweenCornersInDirection(boundingBox.move(vec3.scale(-1.0)), vec3)) { + for (final BlockPos blockPos1 : me.samsuik.sakura.utils.BlockPosIterator.iterable(boundingBox.move(vec3.scale(-1.0)))) { // Sakura - optimise check inside blocks if (!visitor.visit(blockPos1, 0)) { return false; } @@ -253,7 +266,7 @@ public interface BlockGetter extends LevelHeightAccessor { if (i < 0) { return false; } else { - for (BlockPos blockPos2 : BlockPos.betweenCornersInDirection(boundingBox, vec3)) { + for (final BlockPos blockPos2 : me.samsuik.sakura.utils.BlockPosIterator.iterable(boundingBox)) { // Sakura - optimise check inside blocks if (set.add(blockPos2.asLong()) && !visitor.visit(blockPos2, i + 1)) { return false; }