From 54a9bdd5035163c71af0cb425d3a9945be4d19d2 Mon Sep 17 00:00:00 2001 From: tr7zw Date: Mon, 23 Mar 2020 18:20:58 +0100 Subject: [PATCH] Remove Stream usage This removes streams from the entity collision code, Crafting Manager and some other useless places. --- .../yapfa/collision/CollisionHelper.java | 123 +++++++++++++++ src/main/java/net/minecraft/server/Block.java | 2 +- .../net/minecraft/server/BlockPosition.java | 2 +- .../net/minecraft/server/CraftingManager.java | 58 +++++-- .../java/net/minecraft/server/Entity.java | 145 ++++++++++++++++-- .../net/minecraft/server/EntityLiving.java | 1 + .../net/minecraft/server/VoxelShapes.java | 103 +++++++++++++ 7 files changed, 400 insertions(+), 34 deletions(-) create mode 100644 src/main/java/de/tr7zw/yapfa/collision/CollisionHelper.java diff --git a/src/main/java/de/tr7zw/yapfa/collision/CollisionHelper.java b/src/main/java/de/tr7zw/yapfa/collision/CollisionHelper.java new file mode 100644 index 000000000..d67753937 --- /dev/null +++ b/src/main/java/de/tr7zw/yapfa/collision/CollisionHelper.java @@ -0,0 +1,123 @@ +package de.tr7zw.yapfa.collision; + +import java.util.List; +import java.util.Spliterator; +import java.util.Spliterators; +import java.util.Spliterators.AbstractSpliterator; +import java.util.function.Consumer; + +import javax.annotation.Nullable; + +import com.google.common.collect.Lists; + +import net.minecraft.server.AxisAlignedBB; +import net.minecraft.server.BlockPosition; +import net.minecraft.server.BlockPosition.MutableBlockPosition; +import net.minecraft.server.Blocks; +import net.minecraft.server.CursorPosition; +import net.minecraft.server.Entity; +import net.minecraft.server.IBlockAccess; +import net.minecraft.server.IBlockData; +import net.minecraft.server.ICollisionAccess; +import net.minecraft.server.MathHelper; +import net.minecraft.server.OperatorBoolean; +import net.minecraft.server.StreamAccumulator; +import net.minecraft.server.VoxelShape; +import net.minecraft.server.VoxelShapeCollision; +import net.minecraft.server.VoxelShapes; + +public class CollisionHelper { + + public static AbstractSpliterator b(ICollisionAccess collisionAccess, VoxelShape worldBorder, @Nullable Entity var0, AxisAlignedBB var1) { + int var2 = MathHelper.floor((double) (var1.minX - 1.0E-7)) - 1; + int var3 = MathHelper.floor((double) (var1.maxX + 1.0E-7)) + 1; + int var4 = MathHelper.floor((double) (var1.minY - 1.0E-7)) - 1; + int var5 = MathHelper.floor((double) (var1.maxY + 1.0E-7)) + 1; + int var6 = MathHelper.floor((double) (var1.minZ - 1.0E-7)) - 1; + int var7 = MathHelper.floor((double) (var1.maxZ + 1.0E-7)) + 1; + final VoxelShapeCollision var8 = var0 == null ? VoxelShapeCollision.a() : VoxelShapeCollision.a((Entity) var0); + final CursorPosition var9 = new CursorPosition(var2, var4, var6, var3, var5, var7); + final BlockPosition.MutableBlockPosition var10 = new BlockPosition.MutableBlockPosition(); + final VoxelShape var11 = VoxelShapes.a((AxisAlignedBB) var1); + return new Spliterators.AbstractSpliterator(Long.MAX_VALUE, 1280) { + boolean a; + { + + this.a = var0 == null; + } + + @Override + public boolean tryAdvance(Consumer var02) { + int var2; + int var3; + if (!this.a) { + this.a = true; + VoxelShape var1 = collisionAccess.getWorldBorder().a(); + var2 = VoxelShapes.c((VoxelShape) var1, + (VoxelShape) VoxelShapes.a((AxisAlignedBB) var0.getBoundingBox().shrink(1.0E-7)), + (OperatorBoolean) OperatorBoolean.AND) ? 1 : 0; + var3 = VoxelShapes.c((VoxelShape) var1, + (VoxelShape) VoxelShapes.a((AxisAlignedBB) var0.getBoundingBox().g(1.0E-7)), + (OperatorBoolean) OperatorBoolean.AND) ? 1 : 0; + if (var2 == 0 && var3 != 0) { + var02.accept((VoxelShape) var1); + return true; + } + } + while (var9.a()) { + IBlockAccess var7; + int var6; + int var5; + VoxelShape var92; + VoxelShape var102; + int var1 = var9.b(); + var2 = var9.c(); + var3 = var9.d(); + int var4 = var9.e(); + if (var4 == 3 || (var7 = collisionAccess.c(var5 = var1 >> 4, var6 = var3 >> 4)) == null) + continue; + var10.d(var1, var2, var3); + IBlockData var82 = var7.getType((BlockPosition) var10); + if (var4 == 1 && !var82.f() || var4 == 2 && var82.getBlock() != Blocks.MOVING_PISTON + || !VoxelShapes.c((VoxelShape) var11, + (VoxelShape) (var102 = (var92 = var82.b((IBlockAccess) collisionAccess, + (BlockPosition) var10, var8)).a((double) var1, (double) var2, + (double) var3)), + (OperatorBoolean) OperatorBoolean.AND)) + continue; + var02.accept((VoxelShape) var102); + return true; + } + return false; + } + }; + } + + public static class SpliteratorAccumulator { + private final List a = Lists.newArrayList(); + private final Spliterator b; + + public SpliteratorAccumulator(Spliterator var0) { + this.b = var0; + } + + public Spliterators.AbstractSpliterator a() { + return new Spliterators.AbstractSpliterator(Long.MAX_VALUE, 0) { + private int b; + + @Override + public boolean tryAdvance(Consumer var0) { + while (this.b >= SpliteratorAccumulator.this.a.size()) { + if (SpliteratorAccumulator.this.b.tryAdvance(SpliteratorAccumulator.this.a::add)) + continue; + return false; + } + var0.accept(SpliteratorAccumulator.this.a.get(this.b++)); + return true; + } + }; + } + + } + +} diff --git a/src/main/java/net/minecraft/server/Block.java b/src/main/java/net/minecraft/server/Block.java index 66244a9d0..7b3a71e33 100644 --- a/src/main/java/net/minecraft/server/Block.java +++ b/src/main/java/net/minecraft/server/Block.java @@ -100,7 +100,7 @@ public class Block implements IMaterial { while (iterator.hasNext()) { Entity entity = (Entity) iterator.next(); - double d0 = VoxelShapes.a(EnumDirection.EnumAxis.Y, entity.getBoundingBox().d(0.0D, 1.0D, 0.0D), Stream.of(voxelshape), -1.0D); + double d0 = VoxelShapes.a(EnumDirection.EnumAxis.Y, entity.getBoundingBox().d(0.0D, 1.0D, 0.0D), voxelshape, -1.0D); // YAPFA entity.enderTeleportTo(entity.locX(), entity.locY() + 1.0D + d0, entity.locZ()); } diff --git a/src/main/java/net/minecraft/server/BlockPosition.java b/src/main/java/net/minecraft/server/BlockPosition.java index 4c64798fb..c429470cd 100644 --- a/src/main/java/net/minecraft/server/BlockPosition.java +++ b/src/main/java/net/minecraft/server/BlockPosition.java @@ -72,7 +72,7 @@ public class BlockPosition extends BaseBlockPosition implements MinecraftSeriali @Override public T a(DynamicOps dynamicops) { - return dynamicops.createIntList(IntStream.of(new int[]{this.getX(), this.getY(), this.getZ()})); + return (T) new NBTTagIntArray(new int[]{this.getX(), this.getY(), this.getZ()}); // YAPFA } public static long getAdjacent(int baseX, int baseY, int baseZ, EnumDirection enumdirection) { return asLong(baseX + enumdirection.getAdjacentX(), baseY + enumdirection.getAdjacentY(), baseZ + enumdirection.getAdjacentZ()); } // Paper diff --git a/src/main/java/net/minecraft/server/CraftingManager.java b/src/main/java/net/minecraft/server/CraftingManager.java index f0d7a91fa..15e2439d6 100644 --- a/src/main/java/net/minecraft/server/CraftingManager.java +++ b/src/main/java/net/minecraft/server/CraftingManager.java @@ -8,14 +8,18 @@ import com.google.gson.GsonBuilder; import com.google.gson.JsonObject; import com.google.gson.JsonParseException; import com.google.gson.JsonSyntaxException; + +import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Comparator; +import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Optional; +import java.util.Set; import java.util.Map.Entry; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -82,21 +86,31 @@ public class CraftingManager extends ResourceDataJson { // CraftBukkit end public > Optional craft(Recipes recipes, C c0, World world) { - // CraftBukkit start - Optional recipe = this.a(recipes).values().stream().flatMap((irecipe) -> { - return SystemUtils.a(recipes.a(irecipe, world, c0)); - }).findFirst(); - c0.setCurrentRecipe(recipe.orElse(null)); // CraftBukkit - Clear recipe when no recipe is found - // CraftBukkit end - return recipe; + // YAPFA start + for(IRecipe rep : this.a(recipes).values()) { + Optional optional = recipes.a(rep, world, c0); + if(optional.isPresent()) { + c0.setCurrentRecipe(optional.get()); + return optional; + } + } + c0.setCurrentRecipe(null); // CraftBukkit - Clear recipe when no recipe is found + return Optional.empty(); + // YAPFA end } public > List b(Recipes recipes, C c0, World world) { - return (List) this.a(recipes).values().stream().flatMap((irecipe) -> { - return SystemUtils.a(recipes.a(irecipe, world, c0)); - }).sorted(Comparator.comparing((irecipe) -> { + // YAPFA start + List list = new ArrayList(); + for(IRecipe rec : this.a(recipes).values()) { + Optional optional = recipes.a(rec, world, c0); + optional.ifPresent(list::add); + } + list.sort(Comparator.comparing((irecipe) -> { return irecipe.getResult().j(); - })).collect(Collectors.toList()); + })); + return list; + // YAPFA end } private > Map> a(Recipes recipes) { @@ -120,15 +134,25 @@ public class CraftingManager extends ResourceDataJson { } public Optional> a(MinecraftKey minecraftkey) { - return this.recipes.values().stream().map((map) -> { - return map.get(minecraftkey); // CraftBukkit - decompile error - }).filter(Objects::nonNull).findFirst(); + // YAPFA start + for(Object2ObjectLinkedOpenHashMap> map : this.recipes.values()) { + IRecipe rec = map.get(minecraftkey); + if(rec != null) { + return Optional.of(rec); + } + } + return Optional.empty(); + // YAPFA end } public Collection> b() { - return (Collection) this.recipes.values().stream().flatMap((map) -> { - return map.values().stream(); - }).collect(Collectors.toSet()); + // YAPFA start + Set> recipes = new HashSet>(); + for(Object2ObjectLinkedOpenHashMap> map : this.recipes.values()) { + recipes.addAll(map.values()); + } + return recipes; + // YAPFA end } public Stream c() { diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java index 2e3329bd2..902c98cf8 100644 --- a/src/main/java/net/minecraft/server/Entity.java +++ b/src/main/java/net/minecraft/server/Entity.java @@ -13,6 +13,7 @@ import java.util.Locale; import java.util.Optional; import java.util.Random; import java.util.Set; +import java.util.Spliterators.AbstractSpliterator; import java.util.UUID; import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Stream; @@ -1030,31 +1031,60 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke private Vec3D e(Vec3D vec3d) { AxisAlignedBB axisalignedbb = this.getBoundingBox(); VoxelShapeCollision voxelshapecollision = VoxelShapeCollision.a(this); - - Stream stream = !this.world.getWorldBorder().isInBounds(axisalignedbb) ? Stream.empty() : Stream.of(this.world.getWorldBorder().a()); // Tuinity - optimise voxelshapes - Stream stream1 = de.tr7zw.yapfa.YapfaConfig.disableEntityCollisionboxes ? Stream.empty() : this.world.b(this, axisalignedbb.a(vec3d), (Set) ImmutableSet.of()); // YAPFA - StreamAccumulator streamaccumulator = new StreamAccumulator<>(Stream.concat(stream1, stream)); - Vec3D vec3d1 = vec3d.g() == 0.0D ? vec3d : a(this, vec3d, axisalignedbb, this.world, voxelshapecollision, streamaccumulator); + VoxelShape worldBorder = this.world.getWorldBorder().a(); + // YAPFA start + Vec3D vec3d1; + StreamAccumulator streamaccumulator = new StreamAccumulator<>(Stream.concat(Stream.empty(), Stream.empty())); + //boolean useVoxelShape = false; + if(de.tr7zw.yapfa.YapfaConfig.disableEntityCollisionboxes) { + //useVoxelShape = VoxelShapes.c(worldBorder, VoxelShapes.a(axisalignedbb.shrink(1.0E-7D)), OperatorBoolean.AND); + vec3d1 = vec3d.g() == 0.0D ? vec3d : aNonStream(this, vec3d, axisalignedbb, this.world, voxelshapecollision, worldBorder); + } else { + Stream stream = !this.world.getWorldBorder().isInBounds(axisalignedbb) ? Stream.empty() : Stream.of(this.world.getWorldBorder().a()); // Tuinity - optimise voxelshapes + Stream stream1 = de.tr7zw.yapfa.YapfaConfig.disableEntityCollisionboxes ? Stream.empty() : this.world.b(this, axisalignedbb.a(vec3d), (Set) ImmutableSet.of()); // YAPFA + streamaccumulator = new StreamAccumulator<>(Stream.concat(stream1, stream)); + vec3d1 = vec3d.g() == 0.0D ? vec3d : a(this, vec3d, axisalignedbb, this.world, voxelshapecollision, streamaccumulator); + } boolean flag = vec3d.x != vec3d1.x; boolean flag1 = vec3d.y != vec3d1.y; boolean flag2 = vec3d.z != vec3d1.z; boolean flag3 = this.onGround || flag1 && vec3d.y < 0.0D; if (this.H > 0.0F && flag3 && (flag || flag2)) { - Vec3D vec3d2 = a(this, new Vec3D(vec3d.x, (double) this.H, vec3d.z), axisalignedbb, this.world, voxelshapecollision, streamaccumulator); - Vec3D vec3d3 = a(this, new Vec3D(0.0D, (double) this.H, 0.0D), axisalignedbb.b(vec3d.x, 0.0D, vec3d.z), this.world, voxelshapecollision, streamaccumulator); + if(de.tr7zw.yapfa.YapfaConfig.disableEntityCollisionboxes) { - if (vec3d3.y < (double) this.H) { - Vec3D vec3d4 = a(this, new Vec3D(vec3d.x, 0.0D, vec3d.z), axisalignedbb.b(vec3d3), this.world, voxelshapecollision, streamaccumulator).e(vec3d3); + Vec3D vec3d2 = aNonStream(this, new Vec3D(vec3d.x, (double) this.H, vec3d.z), axisalignedbb, this.world, voxelshapecollision, worldBorder); + Vec3D vec3d3 = aNonStream(this, new Vec3D(0.0D, (double) this.H, 0.0D), axisalignedbb.b(vec3d.x, 0.0D, vec3d.z), this.world, voxelshapecollision, worldBorder); + + if (vec3d3.y < (double) this.H) { + Vec3D vec3d4 = aNonStream(this, new Vec3D(vec3d.x, 0.0D, vec3d.z), axisalignedbb.b(vec3d3), this.world, voxelshapecollision, worldBorder).e(vec3d3); + + if (b(vec3d4) > b(vec3d2)) { + vec3d2 = vec3d4; + } + } - if (b(vec3d4) > b(vec3d2)) { - vec3d2 = vec3d4; + if (b(vec3d2) > b(vec3d1)) { + return vec3d2.e(aNonStream(this, new Vec3D(0.0D, -vec3d2.y + vec3d.y, 0.0D), axisalignedbb.b(vec3d2), this.world, voxelshapecollision, worldBorder)); } - } + } else { + Vec3D vec3d2 = a(this, new Vec3D(vec3d.x, (double) this.H, vec3d.z), axisalignedbb, this.world, voxelshapecollision, streamaccumulator); + Vec3D vec3d3 = a(this, new Vec3D(0.0D, (double) this.H, 0.0D), axisalignedbb.b(vec3d.x, 0.0D, vec3d.z), this.world, voxelshapecollision, streamaccumulator); - if (b(vec3d2) > b(vec3d1)) { - return vec3d2.e(a(this, new Vec3D(0.0D, -vec3d2.y + vec3d.y, 0.0D), axisalignedbb.b(vec3d2), this.world, voxelshapecollision, streamaccumulator)); - } + if (vec3d3.y < (double) this.H) { + Vec3D vec3d4 = a(this, new Vec3D(vec3d.x, 0.0D, vec3d.z), axisalignedbb.b(vec3d3), this.world, voxelshapecollision, streamaccumulator).e(vec3d3); + + if (b(vec3d4) > b(vec3d2)) { + vec3d2 = vec3d4; + } + } + + if (b(vec3d2) > b(vec3d1)) { + return vec3d2.e(a(this, new Vec3D(0.0D, -vec3d2.y + vec3d.y, 0.0D), axisalignedbb.b(vec3d2), this.world, voxelshapecollision, streamaccumulator)); + } + } + // YAPFA end + } return vec3d1; @@ -1078,6 +1108,91 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke return a(vec3d, axisalignedbb, world, voxelshapecollision, streamaccumulator); } } + + // YAPFA start + public static Vec3D aNonStream(@Nullable Entity entity, Vec3D vec3d, AxisAlignedBB axisalignedbb, World world, VoxelShapeCollision voxelshapecollision, VoxelShape worldBorder) { + boolean flag = vec3d.x == 0.0D; + boolean flag1 = vec3d.y == 0.0D; + boolean flag2 = vec3d.z == 0.0D; + + if ((!flag || !flag1) && (!flag || !flag2) && (!flag1 || !flag2)) { + return a(vec3d, axisalignedbb, de.tr7zw.yapfa.collision.CollisionHelper.b(world, worldBorder, entity, axisalignedbb.a(vec3d))); + } else { + return a(vec3d, axisalignedbb, world, voxelshapecollision, worldBorder); + } + } + + public static Vec3D a(Vec3D vec3d, AxisAlignedBB axisalignedbb, AbstractSpliterator split) { + double d0 = vec3d.x; + double d1 = vec3d.y; + double d2 = vec3d.z; + de.tr7zw.yapfa.collision.CollisionHelper.SpliteratorAccumulator acc = new de.tr7zw.yapfa.collision.CollisionHelper.SpliteratorAccumulator(split); + if (d1 != 0.0D) { + d1 = VoxelShapes.a(EnumDirection.EnumAxis.Y, axisalignedbb, acc.a(), d1); + if (d1 != 0.0D) { + axisalignedbb = axisalignedbb.d(0.0D, d1, 0.0D); + } + } + + boolean flag = Math.abs(d0) < Math.abs(d2); + + if (flag && d2 != 0.0D) { + d2 = VoxelShapes.a(EnumDirection.EnumAxis.Z, axisalignedbb, acc.a(), d2); + if (d2 != 0.0D) { + axisalignedbb = axisalignedbb.d(0.0D, 0.0D, d2); + } + } + + if (d0 != 0.0D) { + d0 = VoxelShapes.a(EnumDirection.EnumAxis.X, axisalignedbb, acc.a(), d0); + if (!flag && d0 != 0.0D) { + axisalignedbb = axisalignedbb.d(d0, 0.0D, 0.0D); + } + } + + if (!flag && d2 != 0.0D) { + d2 = VoxelShapes.a(EnumDirection.EnumAxis.Z, axisalignedbb, acc.a(), d2); + } + + return new Vec3D(d0, d1, d2); + } + + public static Vec3D a(Vec3D vec3d, AxisAlignedBB axisalignedbb, IWorldReader iworldreader, VoxelShapeCollision voxelshapecollision, VoxelShape voxelShape) { + double d0 = vec3d.x; + double d1 = vec3d.y; + double d2 = vec3d.z; + + if (d1 != 0.0D) { + d1 = VoxelShapes.a(EnumDirection.EnumAxis.Y, axisalignedbb, iworldreader, d1, voxelshapecollision, voxelShape); + if (d1 != 0.0D) { + axisalignedbb = axisalignedbb.d(0.0D, d1, 0.0D); + } + } + + boolean flag = Math.abs(d0) < Math.abs(d2); + + if (flag && d2 != 0.0D) { + d2 = VoxelShapes.a(EnumDirection.EnumAxis.Z, axisalignedbb, iworldreader, d2, voxelshapecollision, voxelShape); + if (d2 != 0.0D) { + axisalignedbb = axisalignedbb.d(0.0D, 0.0D, d2); + } + } + + if (d0 != 0.0D) { + d0 = VoxelShapes.a(EnumDirection.EnumAxis.X, axisalignedbb, iworldreader, d0, voxelshapecollision, voxelShape); + if (!flag && d0 != 0.0D) { + axisalignedbb = axisalignedbb.d(d0, 0.0D, 0.0D); + } + } + + if (!flag && d2 != 0.0D) { + d2 = VoxelShapes.a(EnumDirection.EnumAxis.Z, axisalignedbb, iworldreader, d2, voxelshapecollision, voxelShape); + } + + return new Vec3D(d0, d1, d2); + } + + // YAPFA end public static Vec3D a(Vec3D vec3d, AxisAlignedBB axisalignedbb, StreamAccumulator streamaccumulator) { double d0 = vec3d.x; diff --git a/src/main/java/net/minecraft/server/EntityLiving.java b/src/main/java/net/minecraft/server/EntityLiving.java index b77960710..65685734d 100644 --- a/src/main/java/net/minecraft/server/EntityLiving.java +++ b/src/main/java/net/minecraft/server/EntityLiving.java @@ -2662,6 +2662,7 @@ public abstract class EntityLiving extends Entity { this.a(axisalignedbb, this.getBoundingBox()); } + if(!de.tr7zw.yapfa.YapfaConfig.disableEntityCollisions) // YAPFA this.collideNearby(); this.world.getMethodProfiler().exit(); } diff --git a/src/main/java/net/minecraft/server/VoxelShapes.java b/src/main/java/net/minecraft/server/VoxelShapes.java index 5e24ce485..d651ed5fb 100644 --- a/src/main/java/net/minecraft/server/VoxelShapes.java +++ b/src/main/java/net/minecraft/server/VoxelShapes.java @@ -5,9 +5,12 @@ import com.google.common.math.DoubleMath; import com.google.common.math.IntMath; import it.unimi.dsi.fastutil.doubles.DoubleArrayList; import it.unimi.dsi.fastutil.doubles.DoubleList; + import java.util.Arrays; import java.util.Iterator; import java.util.Objects; +import java.util.Spliterators; +import java.util.Spliterators.AbstractSpliterator; import java.util.stream.Stream; public final class VoxelShapes { @@ -256,6 +259,106 @@ public final class VoxelShapes { return d0; } + + // YAPFA start + + public static double a(EnumDirection.EnumAxis enumdirection_enumaxis, AxisAlignedBB axisalignedbb, VoxelShape voxel, double d0) { + d0 = voxel.a(enumdirection_enumaxis, axisalignedbb, d0); + if (Math.abs(d0) < 1.0E-7D) { + return 0.0D; + } + + return d0; + } + + public static double a(EnumDirection.EnumAxis enumdirection_enumaxis, AxisAlignedBB axisalignedbb, AbstractSpliterator stream, double d0) { + for (Iterator iterator = Spliterators.iterator(stream); iterator.hasNext(); d0 = ((VoxelShape) iterator.next()).a(enumdirection_enumaxis, axisalignedbb, d0)) { + if (Math.abs(d0) < 1.0E-7D) { + return 0.0D; + } + } + + return d0; + } + + public static double a(EnumDirection.EnumAxis enumdirection_enumaxis, AxisAlignedBB axisalignedbb, IWorldReader iworldreader, double d0, VoxelShapeCollision voxelshapecollision, VoxelShape voxel) { + return a(axisalignedbb, iworldreader, d0, voxelshapecollision, EnumAxisCycle.a(enumdirection_enumaxis, EnumDirection.EnumAxis.Z), voxel); + } + + private static double a(AxisAlignedBB axisalignedbb, IWorldReader iworldreader, double d0, VoxelShapeCollision voxelshapecollision, EnumAxisCycle enumaxiscycle, VoxelShape voxelshape) { + if (axisalignedbb.b() >= 1.0E-6D && axisalignedbb.c() >= 1.0E-6D && axisalignedbb.d() >= 1.0E-6D) { + if (Math.abs(d0) < 1.0E-7D) { + return 0.0D; + } else { + EnumAxisCycle enumaxiscycle1 = enumaxiscycle.a(); + EnumDirection.EnumAxis enumdirection_enumaxis = enumaxiscycle1.a(EnumDirection.EnumAxis.X); + EnumDirection.EnumAxis enumdirection_enumaxis1 = enumaxiscycle1.a(EnumDirection.EnumAxis.Y); + EnumDirection.EnumAxis enumdirection_enumaxis2 = enumaxiscycle1.a(EnumDirection.EnumAxis.Z); + BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition(); + int i = MathHelper.floor(axisalignedbb.a(enumdirection_enumaxis) - 1.0E-7D) - 1; + int j = MathHelper.floor(axisalignedbb.b(enumdirection_enumaxis) + 1.0E-7D) + 1; + int k = MathHelper.floor(axisalignedbb.a(enumdirection_enumaxis1) - 1.0E-7D) - 1; + int l = MathHelper.floor(axisalignedbb.b(enumdirection_enumaxis1) + 1.0E-7D) + 1; + double d1 = axisalignedbb.a(enumdirection_enumaxis2) - 1.0E-7D; + double d2 = axisalignedbb.b(enumdirection_enumaxis2) + 1.0E-7D; + boolean flag = d0 > 0.0D; + int i1 = flag ? MathHelper.floor(axisalignedbb.b(enumdirection_enumaxis2) - 1.0E-7D) - 1 : MathHelper.floor(axisalignedbb.a(enumdirection_enumaxis2) + 1.0E-7D) + 1; + int j1 = a(d0, d1, d2); + int k1 = flag ? 1 : -1; + int l1 = i1; + + while (true) { + if (flag) { + if (l1 > j1) { + break; + } + } else if (l1 < j1) { + break; + } + + for (int i2 = i; i2 <= j; ++i2) { + for (int j2 = k; j2 <= l; ++j2) { + int k2 = 0; + + if (i2 == i || i2 == j) { + ++k2; + } + + if (j2 == k || j2 == l) { + ++k2; + } + + if (l1 == i1 || l1 == j1) { + ++k2; + } + + if (k2 < 3) { + blockposition_mutableblockposition.a(enumaxiscycle1, i2, j2, l1); + IBlockData iblockdata = iworldreader.getType(blockposition_mutableblockposition); + + if ((k2 != 1 || iblockdata.f()) && (k2 != 2 || iblockdata.getBlock() == Blocks.MOVING_PISTON)) { + d0 = iblockdata.b((IBlockAccess) iworldreader, blockposition_mutableblockposition, voxelshapecollision).a(enumdirection_enumaxis2, axisalignedbb.d((double) (-blockposition_mutableblockposition.getX()), (double) (-blockposition_mutableblockposition.getY()), (double) (-blockposition_mutableblockposition.getZ())), d0); + if (Math.abs(d0) < 1.0E-7D) { + return 0.0D; + } + + j1 = a(d0, d1, d2); + } + } + } + } + + l1 += k1; + } + + return voxelshape.a(enumdirection_enumaxis2, axisalignedbb, d0); + } + } else { + return d0; + } + } + + // YAPFA end public static double a(EnumDirection.EnumAxis enumdirection_enumaxis, AxisAlignedBB axisalignedbb, IWorldReader iworldreader, double d0, VoxelShapeCollision voxelshapecollision, Stream stream) { return a(axisalignedbb, iworldreader, d0, voxelshapecollision, EnumAxisCycle.a(enumdirection_enumaxis, EnumDirection.EnumAxis.Z), stream); -- 2.25.1.windows.1