From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Samsuik Date: Fri, 13 Oct 2023 14:36:19 +0100 Subject: [PATCH] Optimise cannon entity movement diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java index 68e2b26835a2588a047e9ea175eb8e4912041976..98107921d7251e1b7fc621103a31afdfd3bb5af7 100644 --- a/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java @@ -1169,7 +1169,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess Vec3 vec3 = this.collide(movement); double d = vec3.lengthSqr(); if (d > 1.0E-7 || movement.lengthSqr() - d < 1.0E-7) { - if (this.fallDistance != 0.0 && d >= 1.0) { + if (this.fallDistance != 0.0 && d >= 1.0 && !this.isFallingBlock) { // Sakura - optimise cannon entity movement BlockHitResult blockHitResult = this.level() .clip( new ClipContext(this.position(), this.position().add(vec3), ClipContext.Block.FALLDAMAGE_RESETTING, ClipContext.Fluid.WATER, this) @@ -1510,6 +1510,131 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess return distance; } + // Sakura start - optimise cannon entity movement + protected final Vec3 sakura_collide(Vec3 movement) { + if (movement.x == 0.0 && movement.y == 0.0 && movement.z == 0.0) { + return movement; + } + + List potentialCollisionsVoxel = new it.unimi.dsi.fastutil.objects.ObjectArrayList<>(0); + List potentialCollisionsBB = new it.unimi.dsi.fastutil.objects.ObjectArrayList<>(4); + AABB currBoundingBox = this.getBoundingBox(); + + if (movement.lengthSqr() >= 12.0) { // axis scan on large movement + return this.collideAxisScan(movement, currBoundingBox, potentialCollisionsVoxel, potentialCollisionsBB); + } else { + return this.collideCube(movement, currBoundingBox, potentialCollisionsVoxel, potentialCollisionsBB); + } + } + + private Vec3 collideCube(Vec3 movement, AABB currBoundingBox, List voxelList, List bbList) { + final AABB bb; + if (movement.x() == 0.0 && movement.z() == 0.0) { + if (movement.y > 0.0) { + bb = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.cutUpwards(currBoundingBox, movement.y); + } else { + bb = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.cutDownwards(currBoundingBox, movement.y); + } + } else { + bb = currBoundingBox.expandTowards(movement.x, movement.y, movement.z); + } + this.collectCollisions(bb, voxelList, bbList, ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_FLAG_CHECK_BORDER); + return ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.performCollisions(movement, currBoundingBox, voxelList, bbList); + } + + private Vec3 collideAxisScan(Vec3 movement, AABB currBoundingBox, List voxelList, List bbList) { + double x = movement.x; + double y = movement.y; + double z = movement.z; + + boolean xSmaller = Math.abs(x) < Math.abs(z); + + if (y != 0.0) { + y = this.scanY(currBoundingBox, y, voxelList, bbList); + if (y != 0.0) { + currBoundingBox = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.offsetY(currBoundingBox, y); + } + } + + if (xSmaller && z != 0.0) { + z = this.scanZ(currBoundingBox, z, voxelList, bbList); + if (z != 0.0) { + currBoundingBox = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.offsetZ(currBoundingBox, z); + } + } + + if (x != 0.0) { + x = this.scanX(currBoundingBox, x, voxelList, bbList); + if (x != 0.0) { + currBoundingBox = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.offsetX(currBoundingBox, x); + } + } + + if (!xSmaller && z != 0.0) { + z = this.scanZ(currBoundingBox, z, voxelList, bbList); + } + + return new Vec3(x, y, z); + } + + private void collectCollisions(AABB collisionBox, List voxelList, List bbList, int flags) { + // Copied from the collide method below + ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.getCollisionsForBlocksOrWorldBorder( + this.level, this, collisionBox, voxelList, bbList, + flags | this.getExtraCollisionFlags(), null // Sakura - load chunks on movement + ); + + ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.getEntityHardCollisions( + this.level, this, collisionBox, bbList, 0, null + ); + } + + private double scanX(AABB currBoundingBox, double x, List voxelList, List bbList) { + AABB scanBox = cutBoundingBoxX(currBoundingBox, x); + this.collectCollisions(scanBox, voxelList, bbList, ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_FLAG_CHECK_BORDER); + x = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.performAABBCollisionsX(currBoundingBox, x, bbList); + return ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.performVoxelCollisionsX(currBoundingBox, x, voxelList); + } + + private double scanY(AABB currBoundingBox, double y, List voxelList, List bbList) { + AABB scanBox = cutBoundingBoxY(currBoundingBox, y); + this.collectCollisions(scanBox, voxelList, bbList, 0); + y = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.performAABBCollisionsY(currBoundingBox, y, bbList); + return ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.performVoxelCollisionsY(currBoundingBox, y, voxelList); + } + + private double scanZ(AABB currBoundingBox, double z, List voxelList, List bbList) { + AABB scanBox = cutBoundingBoxZ(currBoundingBox, z); + this.collectCollisions(scanBox, voxelList, bbList, ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.COLLISION_FLAG_CHECK_BORDER); + z = ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.performAABBCollisionsZ(currBoundingBox, z, bbList); + return ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.performVoxelCollisionsZ(currBoundingBox, z, voxelList); + } + + private static AABB cutBoundingBoxX(AABB bb, double x) { + if (x > 0.0) { + return ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.cutRight(bb, x); + } else { + return ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.cutLeft(bb, x); + } + } + + private static AABB cutBoundingBoxY(AABB bb, double y) { + if (y > 0.0) { + return ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.cutUpwards(bb, y); + } else { + return ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.cutDownwards(bb, y); + } + } + + private static AABB cutBoundingBoxZ(AABB bb, double z) { + if (z > 0.0) { + return ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.cutForwards(bb, z); + } else { + return ca.spottedleaf.moonrise.patches.collisions.CollisionUtil.cutBackwards(bb, z); + } + } + // Sakura end - optimise cannon entity movement + // Paper start - optimise collisions protected Vec3 collide(Vec3 movement) { final boolean xZero = movement.x == 0.0; diff --git a/net/minecraft/world/entity/item/FallingBlockEntity.java b/net/minecraft/world/entity/item/FallingBlockEntity.java index 3af6e04bb4dcd91de2794bbc8d3eff16def9efa8..e0cee4cda2fb2d55e1da0cedc71cdc0c445108d0 100644 --- a/net/minecraft/world/entity/item/FallingBlockEntity.java +++ b/net/minecraft/world/entity/item/FallingBlockEntity.java @@ -121,6 +121,12 @@ public class FallingBlockEntity extends Entity implements me.samsuik.sakura.enti return itemEntity; } // Sakura end - merge cannon entities + // Sakura start - optimise cannon entity movement + @Override + protected final Vec3 collide(Vec3 movement) { + return this.sakura_collide(movement); + } + // Sakura end - optimise cannon entity movement public FallingBlockEntity(EntityType entityType, Level level) { super(entityType, level); diff --git a/net/minecraft/world/entity/item/PrimedTnt.java b/net/minecraft/world/entity/item/PrimedTnt.java index 3511e852aebabed8d5f40611db4573f55ca21875..d523cc4e7089e04d577248d26d7d4e911cd87434 100644 --- a/net/minecraft/world/entity/item/PrimedTnt.java +++ b/net/minecraft/world/entity/item/PrimedTnt.java @@ -83,6 +83,12 @@ public class PrimedTnt extends Entity implements TraceableEntity, me.samsuik.sak this.mergeData.count = count; // Sakura - specialised explosions } // Sakura end - merge cannon entities + // Sakura start - optimise cannon entity movement + @Override + protected final net.minecraft.world.phys.Vec3 collide(net.minecraft.world.phys.Vec3 movement) { + return this.sakura_collide(movement); + } + // Sakura end - optimise cannon entity movement public PrimedTnt(EntityType entityType, Level level) { super(entityType, level);