9
0
mirror of https://github.com/Winds-Studio/Leaf.git synced 2025-12-19 15:09:25 +00:00
Files
Leaf/leaf-server/minecraft-patches/features/0295-optimize-getOnPos.patch
2025-08-20 16:44:05 +09:00

351 lines
18 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: hayanesuru <hayanesuru@outlook.jp>
Date: Sat, 9 Aug 2025 15:43:17 +0900
Subject: [PATCH] optimize getOnPos
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
index bc02ce9093adb0ec09252ce00f60dd84335cca70..bb16f3ebffcafcb11d3112e03f5767ac71b359f6 100644
--- a/net/minecraft/world/entity/Entity.java
+++ b/net/minecraft/world/entity/Entity.java
@@ -895,6 +895,8 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
// CraftBukkit end
public void baseTick() {
+ this.leaf$onBlockState = null; // Leaf - optimize getOnPos
+ this.leaf$cacheOnBlock = true; // Leaf - optimize getOnPos
if (firstTick && this instanceof net.minecraft.world.entity.NeutralMob neutralMob) neutralMob.tickInitialPersistentAnger(level); // Paper - Prevent entity loading causing async lookups
this.inBlockState = null;
if (this.isPassenger() && this.getVehicle().isRemoved()) {
@@ -954,6 +956,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
if (this.level() instanceof ServerLevel serverLevelx && this instanceof Leashable) {
Leashable.tickLeash(serverLevelx, (Entity & Leashable)this);
}
+ this.leaf$cacheOnBlock = false; // Leaf - optimize getOnPos
}
public void setSharedFlagOnFire(boolean isOnFire) {
@@ -1118,11 +1121,19 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
AABB aabb = new AABB(boundingBox.minX, boundingBox.minY - 1.0E-6, boundingBox.minZ, boundingBox.maxX, boundingBox.minY, boundingBox.maxZ);
Optional<BlockPos> optional = this.level.findSupportingBlock(this, aabb);
if (optional.isPresent() || this.onGroundNoBlocks) {
- this.mainSupportingBlockPos = optional;
+ // Leaf start - optimize getOnPos
+ if (mainSupportingBlockPos.isEmpty() || optional.isEmpty() || !mainSupportingBlockPos.get().equals(optional.get())) {
+ this.mainSupportingBlockPos = optional;
+ }
+ // Leaf end - optimize getOnPos
} else if (movement != null) {
AABB aabb1 = aabb.move(-movement.x, 0.0, -movement.z);
optional = this.level.findSupportingBlock(this, aabb1);
- this.mainSupportingBlockPos = optional;
+ // Leaf start - optimize getOnPos
+ if (mainSupportingBlockPos.isEmpty() || optional.isEmpty() || !mainSupportingBlockPos.get().equals(optional.get())) {
+ this.mainSupportingBlockPos = optional;
+ }
+ // Leaf end - optimize getOnPos
}
this.onGroundNoBlocks = optional.isEmpty();
@@ -1207,8 +1218,8 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
this.minorHorizontalCollision = false;
}
- BlockPos onPosLegacy = this.getOnPosLegacy();
- BlockState blockState = this.level().getBlockState(onPosLegacy);
+ BlockState blockState = this.leaf$getOnBlockLegacy(); // Leaf - optimize getOnPos
+ BlockPos onPosLegacy = this.leaf$getOnBlockPos(); // Leaf - optimize getOnPos
if (this.isLocalInstanceAuthoritative()) {
this.checkFallDamage(vec3.y, this.onGround(), blockState, onPosLegacy);
}
@@ -1275,9 +1286,8 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
float f = 0.6F;
float f1 = (float)(movement.length() * 0.6F);
float f2 = (float)(movement.horizontalDistance() * 0.6F);
- BlockPos onPos = this.getOnPos();
- BlockState blockState = this.level.getBlockStateIfLoadedUnchecked(onPos.getX(), onPos.getY(), onPos.getZ());
- if (blockState == null) { blockState = this.level.getBlockState(onPos); }
+ BlockState blockState = this.leaf$getOnBlock0(); // Leaf - optimize getOnPos
+ BlockPos onPos = this.leaf$getOnBlockPos(); // Leaf - optimize getOnPos
boolean isStateClimbable = this.isStateClimbable(blockState);
this.moveDist += isStateClimbable ? f1 : f2;
this.flyDist += f1;
@@ -1346,8 +1356,8 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
private void applyEffectsFromBlocks(List<Entity.Movement> movements) {
if (this.isAffectedByBlocks()) {
if (this.onGround()) {
- BlockPos onPosLegacy = this.getOnPosLegacy();
- BlockState blockState = this.level().getBlockState(onPosLegacy);
+ BlockState blockState = this.leaf$getOnBlockLegacy(); // Leaf - optimize getOnPos
+ BlockPos onPosLegacy = this.leaf$getOnBlockPos(); // Leaf - optimize getOnPos
blockState.getBlock().stepOn(this.level(), onPosLegacy, blockState, this);
}
@@ -1442,34 +1452,124 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
return this.getOnPos(0.2F);
}
+ // Leaf start - optimize getOnPos
+ @Deprecated
+ public BlockState leaf$getOnBlockLegacy() {
+ return this.leaf$getOnBlock(0.2F);
+ }
+ // Leaf end - optimize getOnPos
+
public BlockPos getBlockPosBelowThatAffectsMyMovement() {
return this.getOnPos(0.500001F);
}
+ // Leaf start - optimize getOnPos
+ public net.minecraft.world.level.block.state.BlockState leaf$getBlockBelow() {
+ return this.leaf$getOnBlock(0.500001F);
+ }
+ // Leaf end - optimize getOnPos
+
public BlockPos getOnPos() {
return this.getOnPos(1.0E-5F);
}
+ // Leaf start - optimize getOnPos
+ public BlockState leaf$getOnBlock0() {
+ return this.leaf$getOnBlock(1.0E-5F);
+ }
+ // Leaf end - optimize getOnPos
+
protected BlockPos getOnPos(float yOffset) {
- if (this.mainSupportingBlockPos.isPresent() && this.level().getChunkIfLoadedImmediately(this.mainSupportingBlockPos.get()) != null) { // Paper - ensure no loads
+ // Leaf start - optimize getOnPos
+ if (this.mainSupportingBlockPos.isPresent()) {
BlockPos blockPos = this.mainSupportingBlockPos.get();
+ int x = blockPos.getX();
+ int y = blockPos.getY();
+ int z = blockPos.getZ();
+ net.minecraft.world.level.chunk.LevelChunk chunk = this.level.getChunkAtIfLoadedUnchecked(x >> 4, z >> 4);
+ if (chunk == null) { chunk = this.level.getChunk(x >> 4, z >> 4); }
+ BlockState blockState = chunk.getBlockStateFinal(x, y, z);
if (!(yOffset > 1.0E-5F)) {
return blockPos;
- } else {
- BlockState blockState = this.level().getBlockState(blockPos);
- return (!(yOffset <= 0.5) || !blockState.is(BlockTags.FENCES))
- && !blockState.is(BlockTags.WALLS)
- && !(blockState.getBlock() instanceof FenceGateBlock)
- ? blockPos.atY(Mth.floor(this.position.y - yOffset))
- : blockPos;
}
+ final int flags = blockState.tagFlag;
+ return (!(yOffset <= 0.5) || ((flags & org.dreeam.leaf.util.BlockMasks.FENCE_TAG) == 0))
+ && ((flags & org.dreeam.leaf.util.BlockMasks.WALL_TAG) == 0)
+ && ((flags & org.dreeam.leaf.util.BlockMasks.FENCE_GATE_CL) == 0)
+ ? blockPos.atY(Mth.floor(this.position.y - yOffset))
+ : blockPos;
} else {
int floor = Mth.floor(this.position.x);
int floor1 = Mth.floor(this.position.y - yOffset);
int floor2 = Mth.floor(this.position.z);
return new BlockPos(floor, floor1, floor2);
}
+ // Leaf end - optimize getOnPos
+ }
+
+ // Leaf start - optimize getOnPos
+ @Nullable private BlockState leaf$onBlockState = null;
+ private BlockPos leaf$onBlockPos = BlockPos.ZERO;
+ public boolean leaf$cacheOnBlock = false;
+
+ protected final BlockPos leaf$getOnBlockPos() {
+ return leaf$onBlockPos;
+ }
+
+ protected final BlockState leaf$getOnBlock(float yOffset) {
+ if (this.mainSupportingBlockPos.isPresent()) {
+ BlockPos blockPos = this.mainSupportingBlockPos.get();
+ int x = blockPos.getX();
+ int y = blockPos.getY();
+ int z = blockPos.getZ();
+ net.minecraft.world.level.chunk.LevelChunk chunk = null;
+ if (leaf$onBlockPos != blockPos || leaf$onBlockState == null || !leaf$cacheOnBlock) {
+ chunk = this.level.getChunkAtIfLoadedUnchecked(x >> 4, z >> 4);
+ if (chunk == null) {
+ chunk = this.level.getChunk(x >> 4, z >> 4);
+ }
+ leaf$onBlockState = chunk.getBlockStateFinal(x, y, z);
+ leaf$onBlockPos = blockPos;
+ }
+ if (!(yOffset > 1.0E-5F)) {
+ return leaf$onBlockState;
+ }
+ final int flags = leaf$onBlockState.tagFlag;
+ if ((!(yOffset <= 0.5) || ((flags & org.dreeam.leaf.util.BlockMasks.FENCE_TAG) == 0))
+ && ((flags & org.dreeam.leaf.util.BlockMasks.WALL_TAG) == 0)
+ && ((flags & org.dreeam.leaf.util.BlockMasks.FENCE_GATE_CL) == 0)) {
+ int y1 = Mth.floor(this.position.y - yOffset);
+ if (y1 != y) {
+ if (chunk == null) {
+ chunk = this.level.getChunk(x >> 4, z >> 4);
+ }
+ leaf$onBlockPos = new BlockPos(x, y1, z);
+ return leaf$onBlockState = chunk.getBlockStateFinal(x, y1, z);
+ } else {
+ return leaf$onBlockState;
+ }
+ } else {
+ return leaf$onBlockState;
+ }
+ } else {
+ int x = Mth.floor(this.position.x);
+ int y = Mth.floor(this.position.y - yOffset);
+ int z = Mth.floor(this.position.z);
+ boolean flag = leaf$onBlockPos.getX() != x || leaf$onBlockPos.getY() != y || leaf$onBlockPos.getZ() != z;
+ if (flag) {
+ leaf$onBlockPos = new BlockPos(x, y, z);
+ }
+ if (flag || leaf$onBlockState == null || !leaf$cacheOnBlock) {
+ net.minecraft.world.level.chunk.LevelChunk chunk = this.level.getChunkAtIfLoadedUnchecked(x >> 4, z >> 4);
+ if (chunk == null) {
+ chunk = this.level.getChunk(x >> 4, z >> 4);
+ }
+ leaf$onBlockState = chunk.getBlockStateFinal(x, y, z);
+ }
+ return leaf$onBlockState;
+ }
}
+ // Leaf end - optimize getOnPos
protected float getBlockJumpFactor() {
float jumpFactor = this.level().getBlockState(this.blockPosition()).getBlock().getJumpFactor();
@@ -1481,7 +1581,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
BlockState blockState = this.level().getBlockState(this.blockPosition());
float speedFactor = blockState.getBlock().getSpeedFactor();
if (!blockState.is(Blocks.WATER) && !blockState.is(Blocks.BUBBLE_COLUMN)) {
- return speedFactor == 1.0 ? this.level().getBlockState(this.getBlockPosBelowThatAffectsMyMovement()).getBlock().getSpeedFactor() : speedFactor;
+ return speedFactor == 1.0 ? this.leaf$getBlockBelow().getBlock().getSpeedFactor() : speedFactor; // Leaf - optimize getOnPos
} else {
return speedFactor;
}
@@ -2103,7 +2203,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
@Deprecated
protected BlockState getBlockStateOnLegacy() {
- return this.level().getBlockState(this.getOnPosLegacy());
+ return this.leaf$getOnBlockLegacy(); // Leaf - optimize getOnPos
}
public BlockState getBlockStateOn() {
@@ -2115,8 +2215,8 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
}
protected void spawnSprintParticle() {
- BlockPos onPosLegacy = this.getOnPosLegacy();
- BlockState blockState = this.level().getBlockState(onPosLegacy);
+ BlockState blockState = this.leaf$getOnBlockLegacy(); // Leaf - optimize getOnPos
+ BlockPos onPosLegacy = this.leaf$getOnBlockPos(); // Leaf - optimize getOnPos
if (blockState.getRenderShape() != RenderShape.INVISIBLE) {
Vec3 deltaMovement = this.getDeltaMovement();
BlockPos blockPos = this.blockPosition();
diff --git a/net/minecraft/world/entity/ExperienceOrb.java b/net/minecraft/world/entity/ExperienceOrb.java
index 3ee788b172240ccf38cb31385dff13364ccc4142..d88fc291f3c6ea7dd8293d39a435607937d877bc 100644
--- a/net/minecraft/world/entity/ExperienceOrb.java
+++ b/net/minecraft/world/entity/ExperienceOrb.java
@@ -243,6 +243,13 @@ public class ExperienceOrb extends Entity {
return this.getOnPos(0.999999F);
}
+ // Leaf start - optimize getOnPos
+ @Override
+ public net.minecraft.world.level.block.state.BlockState leaf$getBlockBelow() {
+ return this.leaf$getOnBlock(0.999999F);
+ }
+ // Leaf end - optimize getOnPos
+
private void scanForMerges() {
if (this.level() instanceof ServerLevel) {
for (ExperienceOrb experienceOrb : this.level()
diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java
index f0a0a19e2adff03e73e75c3db831dbf74ebf3861..b8665f74bc5592b0022636e62482e21c84692d39 100644
--- a/net/minecraft/world/entity/LivingEntity.java
+++ b/net/minecraft/world/entity/LivingEntity.java
@@ -3087,7 +3087,11 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
}
public void travel(Vec3 travelVector) {
- FluidState fluidState = this.level().getFluidState(this.blockPosition());
+ // Leaf start - optimize getOnPos
+ BlockPos blockPos = this.blockPosition();
+ FluidState fluidState = this.level().getFluidStateIfLoadedUnchecked(blockPos.getX(), blockPos.getY(), blockPos.getZ());
+ if (fluidState == null) { this.level().getFluidState(blockPos); }
+ // Leaf end - optimize getOnPos
if ((this.isInWater() || this.isInLava()) && this.isAffectedByFluids() && !this.canStandOnFluid(fluidState)) {
this.travelInFluid(travelVector);
} else if (this.isFallFlying()) {
@@ -3115,7 +3119,7 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
if (this.getRider() != null && this.isControllable()) {
float friction = 0.91F;
if (this.onGround()) {
- friction = this.level().getBlockState(this.getBlockPosBelowThatAffectsMyMovement()).getBlock().getFriction() * 0.91F;
+ friction = this.leaf$getBlockBelow().getBlock().getFriction() * 0.91F; // Leaf
}
float frictionCompensation = 0.16277137F / (friction * friction * friction);
@@ -3133,15 +3137,14 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
}
private void travelInAir(Vec3 travelVector) {
- BlockPos blockPosBelowThatAffectsMyMovement = this.getBlockPosBelowThatAffectsMyMovement();
- float f = this.onGround() ? this.level().getBlockState(blockPosBelowThatAffectsMyMovement).getBlock().getFriction() : 1.0F;
+ float f = this.onGround() ? leaf$getBlockBelow().getBlock().getFriction() : 1.0F; // Leaf
float f1 = f * 0.91F;
Vec3 vec3 = this.handleRelativeFrictionAndCalculateMovement(travelVector, f);
double d = vec3.y;
MobEffectInstance effect = this.getEffect(MobEffects.LEVITATION);
if (effect != null) {
d += (0.05 * (effect.getAmplifier() + 1) - vec3.y) * 0.2;
- } else if (!this.level().isClientSide || this.level().hasChunkAt(blockPosBelowThatAffectsMyMovement)) {
+ } else if (!this.level().isClientSide) { // Leaf
d -= this.getEffectiveGravity();
} else if (this.getY() > this.level().getMinY()) {
d = -0.1;
@@ -3682,6 +3685,7 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
this.resetFallDistance();
}
+ this.leaf$cacheOnBlock = true; // Leaf
if (this.getControllingPassenger() instanceof Player player && this.isAlive()) {
this.travelRidden(player, vec3);
} else if (this.canSimulateMovement() && this.isEffectiveAi()) {
@@ -3691,6 +3695,7 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin
if (!this.level().isClientSide() || this.isLocalInstanceAuthoritative()) {
this.applyEffectsFromBlocks();
}
+ this.leaf$cacheOnBlock = false; // Leaf
if (this.level().isClientSide()) {
this.calculateEntityAnimation(this instanceof FlyingAnimal);
diff --git a/net/minecraft/world/entity/item/ItemEntity.java b/net/minecraft/world/entity/item/ItemEntity.java
index 52314a8fe4188689431f9a1261226859b967f5f1..b4f72a15b117e1e5438f509a2d7392aa14886316 100644
--- a/net/minecraft/world/entity/item/ItemEntity.java
+++ b/net/minecraft/world/entity/item/ItemEntity.java
@@ -204,7 +204,7 @@ public class ItemEntity extends Entity implements TraceableEntity {
f = 1F;
} else if (this.onGround()) {
// Paper end - Friction API
- f = this.level().getBlockState(this.getBlockPosBelowThatAffectsMyMovement()).getBlock().getFriction() * 0.98F;
+ f = this.leaf$getBlockBelow().getBlock().getFriction() * 0.98F; // Leaf
}
this.setDeltaMovement(this.getDeltaMovement().multiply(f, 0.98, f));
@@ -279,6 +279,13 @@ public class ItemEntity extends Entity implements TraceableEntity {
return this.getOnPos(0.999999F);
}
+ // Leaf start - optimize getOnPos
+ @Override
+ public net.minecraft.world.level.block.state.BlockState leaf$getBlockBelow() {
+ return this.leaf$getOnBlock(0.999999F);
+ }
+ // Leaf end - optimize getOnPos
+
private void setUnderwaterMovement() {
this.setFluidMovement(0.99F);
}