Merge Staging (#458)

* on the latest version now

* MEGA port PR (#459)

* add all of the patches

* cleanup patches

* update README.md and LICENSE.md

* forgot about tic-tacs!

* ...and AI-Improvements

* give JellySquid credit for lithium-gen.patch

* drop AI-improvements

* rebuild

* [CI-SKIP] co-author Hugo for some patches
This commit is contained in:
Simon Gardling 2021-04-17 20:13:30 -04:00 committed by GitHub
parent 08b5fda04e
commit d99cf54b0c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 6136 additions and 2 deletions

View File

@ -3,5 +3,8 @@ All files in the buildSrc folder are licensed under MIT found [here](../buildSrc
All patches (.patch files) marked with "lithium" are licensed under LGPL3 found [here](https://github.com/CaffeineMC/lithium-fabric/blob/1.16.x/dev/LICENSE.txt).<br>
All patches (.patch files) marked with "hydrogen" are licensed under LGPL3 found [here](https://github.com/CaffeineMC/hydrogen-fabric/blob/1.16.x/LICENSE.txt).<br>
All patches (.patch files) marked with "krypton" are licensed under MIT found [here](https://github.com/astei/krypton/blob/master/LICENSE).<br>
All patches (.patch files) marked with "Cadmium" are licensed under MIT found [here](https://github.com/LucilleTea/cadmium-fabric/blob/1.16.x/dev-my-fork/LICENSE.txt).<br>
All patches (.patch files) marked with "LazyDFU" are licensed under MIT found [here](https://github.com/astei/lazydfu/blob/master/LICENSE).<br>
All patches (.patch files) marked with "Tic-Tacs" are licensed under LGPLv3 found [here](https://github.com/Gegy/tic-tacs/blob/1.16.4/LICENSE).<br>
All other patches (.patch files) included in this repo are licensed under the MIT license found [here](MIT.md).<br>
See [EMC](https://github.com/starlis/empirecraft/blob/master/README.md), [Akarin](https://github.com/Akarin-project/Akarin/blob/1.16.5/LICENSE.md), [Purpur](https://github.com/pl3xgaming/Purpur/blob/ver/1.16.5/LICENSE), [Airplane](https://github.com/Technove/Airplane/blob/master/PATCHES-LICENSE), [Origami](https://github.com/Minebench/Origami/blob/1.16/PATCHES-LICENSE), and [Tuinity](https://github.com/Spottedleaf/Tuinity/blob/master/PATCHES-LICENSE) for the license of patches automatically pulled during upstream updates.

View File

@ -252,6 +252,7 @@ This is an overview over all patches that are currently used.
| api | Lagging threshold | William Blake Galbreath | |
| server | Left handed API | BillyGalbreath | |
| api | Left handed API | BillyGalbreath | |
| server | Lithium: CompactSineLUT | JellySquid | |
| server | LivingEntity safeFallDistance | William Blake Galbreath | |
| api | LivingEntity safeFallDistance | William Blake Galbreath | |
| server | LivingEntity#broadcastItemBreak | William Blake Galbreath | |
@ -332,6 +333,8 @@ This is an overview over all patches that are currently used.
| api | PlayerSetSpawnerTypeWithEggEvent | William Blake Galbreath | |
| server | Players should not cram to death | William Blake Galbreath | |
| server | Populator seed controls | Spottedleaf | |
| server | Port Cadmium | Lucy-t | |
| server | Port LazyDFU | Andrew Steinborn | |
| server | Preload ProtocolLib EnumWrappers | ishland | |
| server | Prevent long map entry creation in light engine | Spottedleaf | |
| server | Prevent unload() calls removing tickets for sync loads | Spottedleaf | |
@ -422,6 +425,7 @@ This is an overview over all patches that are currently used.
| server | Zombie horse naturally spawn | William Blake Galbreath | |
| server | add config for logging login location | Simon Gardling | |
| server | dont load chunks for physics | Aikar | |
| server | lithium AI | JellySquid | |
| server | lithium DataTrackerMixin | JellySquid | tr7zw |
| server | lithium HashedList | JellySquid | |
| server | lithium MixinBox | JellySquid | |
@ -430,6 +434,13 @@ This is an overview over all patches that are currently used.
| server | lithium NoiseChunkGeneratorMixin | JellySquid | |
| server | lithium PerlinNoiseSamplerMixin | JellySquid | Bud Gidiere |
| server | lithium VoronoiBiomeAccessTypeMixin | JellySquid | |
| server | lithium block | JellySquid | |
| server | lithium entity | JellySquid | |
| server | lithium enum_values | JellySquid | |
| server | lithium gen | JellySquid | |
| server | lithium reduce allocations | JellySquid | Mykyta Komarnytskyy |
| server | lithium shape | JellySquid | |
| server | lithium: cache chunk gen sea level | SuperCoder7979 | |
| server | lithium: optimize &#96;BlockPos.iterateOutwards&#96; by caching | 2No2Name | |
| server | lithium: skip ticking block entities that are doing nothing | 2No2Name | |
| server | tic-tacs: unblocking | Gegy | |

View File

@ -18,6 +18,9 @@ Yatopia combines the code from many [Paper](https://github.com/PaperMC/Paper) fo
* [Origami](https://github.com/Minebench/Origami)
* [Purpur](https://github.com/pl3xgaming/Purpur)
* [Airplane](https://github.com/Technove/Airplane)
* [Cadmium](https://github.com/LucilleTea/cadmium-fabric)
* [LazyDFU](https://github.com/astei/lazydfu)
* [Tic-Tacs](https://github.com/Gegy/tic-tacs)
## Try it out

View File

@ -24,5 +24,22 @@ val libraryImports = setOf<LibraryImport>(
LibraryImport("com.mojang", "brigadier", "com/mojang/brigadier", "CommandDispatcher"),
LibraryImport("com.mojang", "brigadier", "com/mojang/brigadier/tree", "LiteralCommandNode"),
LibraryImport("com.mojang", "brigadier", "com/mojang/brigadier/suggestion", "SuggestionsBuilder"),
LibraryImport("com.mojang", "brigadier", "com/mojang/brigadier/arguments", "BoolArgumentType")
)
LibraryImport("com.mojang", "brigadier", "com/mojang/brigadier/arguments", "BoolArgumentType"),
LibraryImport("com.mojang", "datafixerupper", "com/mojang/datafixers", "FieldFinder"),
LibraryImport("com.mojang", "datafixerupper", "com/mojang/datafixers", "DataFixUtils"),
LibraryImport("com.mojang", "datafixerupper", "com/mojang/datafixers", "TypeRewriteRule"),
LibraryImport("com.mojang", "datafixerupper", "com/mojang/datafixers", "Typed"),
LibraryImport("com.mojang", "datafixerupper", "com/mojang/datafixers", "TypedOptic"),
LibraryImport("com.mojang", "datafixerupper", "com/mojang/datafixers", "View"),
LibraryImport("com.mojang", "datafixerupper", "com/mojang/datafixers/functions", "Apply"),
LibraryImport("com.mojang", "datafixerupper", "com/mojang/datafixers/functions", "Comp"),
LibraryImport("com.mojang", "datafixerupper", "com/mojang/datafixers/functions", "PointFree"),
LibraryImport("com.mojang", "datafixerupper", "com/mojang/datafixers/functions", "PointFreeRule"),
LibraryImport("com.mojang", "datafixerupper", "com/mojang/datafixers/optics", "IdAdapter"),
LibraryImport("com.mojang", "datafixerupper", "com/mojang/datafixers/optics", "Inj1"),
LibraryImport("com.mojang", "datafixerupper", "com/mojang/datafixers/optics", "Inj2"),
LibraryImport("com.mojang", "datafixerupper", "com/mojang/datafixers/optics", "Optics"),
LibraryImport("com.mojang", "datafixerupper", "com/mojang/datafixers/optics", "Proj1"),
LibraryImport("com.mojang", "datafixerupper", "com/mojang/datafixers/optics", "Proj2"),
LibraryImport("com.mojang", "datafixerupper", "com/mojang/datafixers/types", "Type")
)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,49 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Andrew Steinborn <git@steinborn.me>
Date: Tue, 2 Feb 2021 20:59:35 -0500
Subject: [PATCH] Port LazyDFU
diff --git a/src/main/java/me/steinborn/lazydfu/mod/LazyDataFixerBuilder.java b/src/main/java/me/steinborn/lazydfu/mod/LazyDataFixerBuilder.java
new file mode 100644
index 0000000000000000000000000000000000000000..081aa46531a9df1dc732669a2c1e3180790468c4
--- /dev/null
+++ b/src/main/java/me/steinborn/lazydfu/mod/LazyDataFixerBuilder.java
@@ -0,0 +1,23 @@
+package me.steinborn.lazydfu.mod;
+
+import com.mojang.datafixers.DataFixerBuilder;
+import com.mojang.datafixers.DataFixer;
+
+import java.util.concurrent.Executor;
+
+/**
+ * This version of {@code DataFixerBuilder} does not immediately initialize rules.
+ */
+public class LazyDataFixerBuilder extends DataFixerBuilder {
+
+ private static final Executor NO_OP_EXECUTOR = command -> {};
+
+ public LazyDataFixerBuilder(int dataVersion) {
+ super(dataVersion);
+ }
+
+ @Override
+ public DataFixer build(Executor executor) {
+ return super.build(NO_OP_EXECUTOR);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/net/minecraft/util/datafix/DataConverterRegistry.java b/src/main/java/net/minecraft/util/datafix/DataConverterRegistry.java
index 625dcfaeffb83a0b8b53778c32287cac8daae540..5a22fd08cc2a09d8695ca060dee80183364164a1 100644
--- a/src/main/java/net/minecraft/util/datafix/DataConverterRegistry.java
+++ b/src/main/java/net/minecraft/util/datafix/DataConverterRegistry.java
@@ -202,7 +202,7 @@ public class DataConverterRegistry {
// Yatopia start
private static final DataFixer c;
static {
- DataFixerBuilder datafixerbuilder = new DataFixerBuilder(SharedConstants.getGameVersion().getWorldVersion());
+ DataFixerBuilder datafixerbuilder = new me.steinborn.lazydfu.mod.LazyDataFixerBuilder(SharedConstants.getGameVersion().getWorldVersion()); // Yatopia - Port LazyDFU
a(datafixerbuilder);
c = datafixerbuilder.build(SystemUtils.d);

View File

@ -0,0 +1,138 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: JellySquid <jellysquid+atwork@protonmail.com>
Date: Fri, 5 Feb 2021 00:16:30 -0600
Subject: [PATCH] Lithium: CompactSineLUT
Original code by JellySquid, licensed under GNU Lesser General Public License v3.0
you can find the original code on https://github.com/CaffeineMC/lithium-fabric/ (Yarn mappings)
diff --git a/src/main/java/net/minecraft/util/MathHelper.java b/src/main/java/net/minecraft/util/MathHelper.java
index e9e7fcf2b63febe2a7d055826fabb86bc13a5cf3..b95115aca72ba0cf6451096ddbd8b50a8f3bb5c6 100644
--- a/src/main/java/net/minecraft/util/MathHelper.java
+++ b/src/main/java/net/minecraft/util/MathHelper.java
@@ -5,6 +5,7 @@ import java.util.UUID;
import java.util.function.IntPredicate;
import net.minecraft.SystemUtils;
import net.minecraft.core.BaseBlockPosition;
+import org.yatopiamc.yatopia.server.math.CompactSineLUT;
public class MathHelper {
@@ -15,6 +16,7 @@ public class MathHelper {
}
});
+ public static float[] getSinTable() { return b; } // Yatopia - OBFHELPER
private static final Random c = new Random();
private static final int[] d = new int[]{0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9};
private static final double e = Double.longBitsToDouble(4805340802404319232L);
@@ -22,11 +24,11 @@ public class MathHelper {
private static final double[] g = new double[257];
public static float sin(float f) {
- return MathHelper.b[(int) (f * 10430.378F) & '\uffff'];
+ return CompactSineLUT.sin(f); // Yatopia - CompactSineLUT
}
public static float cos(float f) {
- return MathHelper.b[(int) (f * 10430.378F + 16384.0F) & '\uffff'];
+ return CompactSineLUT.cos(f); // Yatopia - CompactSineLUT
}
public static float c(float f) {
diff --git a/src/main/java/org/yatopiamc/yatopia/server/math/CompactSineLUT.java b/src/main/java/org/yatopiamc/yatopia/server/math/CompactSineLUT.java
new file mode 100644
index 0000000000000000000000000000000000000000..1bb8ba3836af872bc2e58898f16a0b91036b9b02
--- /dev/null
+++ b/src/main/java/org/yatopiamc/yatopia/server/math/CompactSineLUT.java
@@ -0,0 +1,90 @@
+package org.yatopiamc.yatopia.server.math;
+
+import net.minecraft.util.MathHelper;
+
+/**
+ * A replacement for the sine angle lookup table used in {@link MathHelper}, both reducing the size of LUT and improving
+ * the access patterns for common paired sin/cos operations.
+ *
+ * sin(-x) = -sin(x)
+ * ... to eliminate negative angles from the LUT.
+ *
+ * sin(x) = sin(pi/2 - x)
+ * ... to eliminate supplementary angles from the LUT.
+ *
+ * Using these identities allows us to reduce the LUT from 64K entries (256 KB) to just 16K entries (64 KB), enabling
+ * it to better fit into the CPU's caches at the expense of some cycles on the fast path. The implementation has been
+ * tightly optimized to avoid branching where possible and to use very quick integer operations.
+ *
+ * Generally speaking, reducing the size of a lookup table is always a good optimization, but since we need to spend
+ * extra CPU cycles trying to maintain parity with vanilla, there is the potential risk that this implementation ends
+ * up being slower than vanilla when the lookup table is able to be kept in cache memory.
+ *
+ * Unlike other "fast math" implementations, the values returned by this class are *bit-for-bit identical* with those
+ * from {@link MathHelper}. Validation is performed during runtime to ensure that the table is correct.
+ *
+ * @author coderbot16 Author of the original (and very clever) implementation in Rust:
+ * https://gitlab.com/coderbot16/i73/-/tree/master/i73-trig/src
+ * @author jellysquid3 Additional optimizations, port to Java
+ */
+public class CompactSineLUT {
+ private static final int[] SINE_TABLE_INT = new int[16384 + 1];
+ private static final float SINE_TABLE_MIDPOINT;
+
+ static {
+ final float[] SINE_TABLE = MathHelper.getSinTable();
+ // Copy the sine table, covering to raw int bits
+ for (int i = 0; i < SINE_TABLE_INT.length; i++) {
+ SINE_TABLE_INT[i] = Float.floatToRawIntBits(SINE_TABLE[i]);
+ }
+
+ SINE_TABLE_MIDPOINT = SINE_TABLE[SINE_TABLE.length / 2];
+
+ // Test that the lookup table is correct during runtime
+ for (int i = 0; i < SINE_TABLE.length; i++) {
+ float expected = SINE_TABLE[i];
+ float value = lookup(i);
+
+ if (expected != value) {
+ throw new IllegalArgumentException(String.format("LUT error at index %d (expected: %s, found: %s)", i, expected, value));
+ }
+ }
+ }
+
+ // [VanillaCopy] MathHelper#sin(float)
+ public static float sin(float f) {
+ return lookup((int) (f * 10430.38) & 0xFFFF);
+ }
+
+ // [VanillaCopy] MathHelper#cos(float)
+ public static float cos(float f) {
+ return lookup((int) (f * 10430.38 + 16384.0) & 0xFFFF);
+ }
+
+ private static float lookup(int index) {
+ // A special case... Is there some way to eliminate this?
+ if (index == 32768) {
+ return SINE_TABLE_MIDPOINT;
+ }
+
+ // Trigonometric identity: sin(-x) = -sin(x)
+ // Given a domain of 0 <= x <= 2*pi, just negate the value if x > pi.
+ // This allows the sin table size to be halved.
+ int neg = (index & 0x8000) << 16;
+
+ // All bits set if (pi/2 <= x), none set otherwise
+ // Extracts the 15th bit from 'half'
+ int mask = (index << 17) >> 31;
+
+ // Trigonometric identity: sin(x) = sin(pi/2 - x)
+ int pos = (0x8001 & mask) + (index ^ mask);
+
+ // Wrap the position in the table. Moving this down to immediately before the array access
+ // seems to help the Hotspot compiler optimize the bit math better.
+ pos &= 0x7fff;
+
+ // Fetch the corresponding value from the LUT and invert the sign bit as needed
+ // This directly manipulate the sign bit on the float bits to simplify logic
+ return Float.intBitsToFloat(SINE_TABLE_INT[pos] ^ neg);
+ }
+}

View File

@ -0,0 +1,407 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Gegy <gegy1000@gmail.com>
Date: Tue, 9 Feb 2021 13:23:12 -0500
Subject: [PATCH] tic-tacs: unblocking
Code originally licenced under LGPLv3 for the tic-tacs project: https://github.com/Gegy/tic-tacs
diff --git a/src/main/java/net/gegy1000/tictacs/NonBlockingWorldAccess.java b/src/main/java/net/gegy1000/tictacs/NonBlockingWorldAccess.java
new file mode 100644
index 0000000000000000000000000000000000000000..0d99f3b4930045632d88fa4acb3b8159ee9cf9f3
--- /dev/null
+++ b/src/main/java/net/gegy1000/tictacs/NonBlockingWorldAccess.java
@@ -0,0 +1,29 @@
+package net.gegy1000.tictacs;
+
+import net.minecraft.world.level.block.state.IBlockData;
+import net.minecraft.world.level.block.Blocks;
+import net.minecraft.world.level.material.Fluid;
+import net.minecraft.world.level.material.FluidTypes;
+import net.minecraft.core.BlockPosition;
+import net.minecraft.world.level.IWorldReader;
+import net.minecraft.world.level.material.FluidTypes;
+
+public interface NonBlockingWorldAccess extends IWorldReader {
+
+ public static final IBlockData DEFAULT_BLOCK_STATE = Blocks.AIR.getBlockData();
+ public static final Fluid DEFAULT_FLUID_STATE = FluidTypes.EMPTY.getFluidData();
+
+ default IBlockData getBlockStateIfLoaded(BlockPosition pos) {
+ if (this.isLoaded(pos)) {
+ return this.getType(pos);
+ }
+ return DEFAULT_BLOCK_STATE;
+ }
+
+ default Fluid getFluidStateIfLoaded(BlockPosition pos) {
+ if (this.isLoaded(pos)) {
+ return this.getFluid(pos);
+ }
+ return DEFAULT_FLUID_STATE;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/net/minecraft/server/level/EntityPlayer.java b/src/main/java/net/minecraft/server/level/EntityPlayer.java
index a33cbd6504fd0d5c5e50aa63009d70533c01f686..e4f8bb15201e89d0832e3bcdfcbc12667f51165b 100644
--- a/src/main/java/net/minecraft/server/level/EntityPlayer.java
+++ b/src/main/java/net/minecraft/server/level/EntityPlayer.java
@@ -657,6 +657,8 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
}
public void playerTick() {
+ if (!this.world.isLoaded(this.getChunkCoordinates())) return; // Yatopia - tic-tac unblocking
+
try {
if (valid && !this.isSpectator() || this.world.isLoaded(this.getChunkCoordinates())) { // Paper - don't tick dead players that are not in the world currently (pending respawn)
super.tick();
diff --git a/src/main/java/net/minecraft/server/level/WorldServer.java b/src/main/java/net/minecraft/server/level/WorldServer.java
index 7cedb4aaf4a002945866a0ca56eb9b0e7ae28de6..e054e98e413ed02b76e63b29c52bd70a559ad15d 100644
--- a/src/main/java/net/minecraft/server/level/WorldServer.java
+++ b/src/main/java/net/minecraft/server/level/WorldServer.java
@@ -176,8 +176,9 @@ import org.bukkit.event.weather.LightningStrikeEvent;
import org.bukkit.event.world.TimeSkipEvent;
// CraftBukkit end
import it.unimi.dsi.fastutil.ints.IntArrayList; // Tuinity
+import net.gegy1000.tictacs.NonBlockingWorldAccess; // Yatopia
-public class WorldServer extends World implements GeneratorAccessSeed {
+public class WorldServer extends World implements GeneratorAccessSeed, NonBlockingWorldAccess { // Yatopia
public static final BlockPosition a = new BlockPosition(100, 50, 0);
private static final Logger LOGGER = LogManager.getLogger();
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index 4492f2579da79bd58def922894f40422fbeaf54c..cd1f94e5c1c923ee9d8dd451406ac2bee360e9c3 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -142,9 +142,12 @@ import org.bukkit.event.entity.EntityPoseChangeEvent;
import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.plugin.PluginManager;
// CraftBukkit end
+import net.gegy1000.tictacs.NonBlockingWorldAccess; // Yatopia
public abstract class Entity implements INamableTileEntity, ICommandListener, net.minecraft.server.KeyedObject { // Paper
+ public boolean updateNeeded; // Yatopia
+ private boolean chunkPosUpdateRequested; // Yatopia
// CraftBukkit start
private static final int CURRENT_LEVEL = 2;
boolean preserveMotion = true; // Paper - keep initial motion on first setPositionRotation
@@ -772,6 +775,12 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, ne
}
// Tuinity end - detailed watchdog information
public void move(EnumMoveType enummovetype, Vec3D vec3d) {
+ // Yatopia start - tic-tacs unblocking
+ BlockPosition pos = this.getChunkCoordinates();
+ if (!this.world.isLoaded(pos)) {
+ return;
+ }
+ // Yatopia end
// Tuinity start - detailed watchdog information
com.tuinity.tuinity.util.TickThread.ensureTickThread("Cannot move an entity off-main");
synchronized (this.posLock) {
@@ -822,7 +831,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, ne
this.v = vec3d.y != vec3d1.y;
this.onGround = this.v && vec3d.y < 0.0D;
BlockPosition blockposition = this.ap();
- IBlockData iblockdata = this.world.getType(blockposition);
+ IBlockData iblockdata = this.world.getBlockStateIfLoaded(blockposition); // Yatopia
this.a(vec3d1.y, this.onGround, iblockdata, blockposition);
Vec3D vec3d2 = this.getMot();
@@ -936,9 +945,9 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, ne
int k = MathHelper.floor(this.loc.z);
BlockPosition blockposition = new BlockPosition(i, j, k);
- if (this.world.getType(blockposition).isAir()) {
+ if (this.world.getBlockStateIfLoaded(blockposition).isAir()) { // Yatopia
BlockPosition blockposition1 = blockposition.down();
- IBlockData iblockdata = this.world.getType(blockposition1);
+ IBlockData iblockdata = this.world.getBlockStateIfLoaded(blockposition1); // Yatopia
Block block = iblockdata.getBlock();
if (block.a((Tag) TagsBlock.FENCES) || block.a((Tag) TagsBlock.WALLS) || block instanceof BlockFenceGate) {
@@ -950,17 +959,21 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, ne
}
protected float getBlockJumpFactor() {
- float f = this.world.getType(this.getChunkCoordinates()).getBlock().getJumpFactor();
- float f1 = this.world.getType(this.as()).getBlock().getJumpFactor();
+ // Yatopia start - tic-tacs unblocking
+ float f = this.world.getBlockStateIfLoaded(this.getChunkCoordinates()).getBlock().getJumpFactor();
+ float f1 = this.world.getBlockStateIfLoaded(this.as()).getBlock().getJumpFactor();
+ // Yatopia end
return (double) f == 1.0D ? f1 : f;
}
protected float getBlockSpeedFactor() {
- Block block = this.world.getType(this.getChunkCoordinates()).getBlock();
+ // Yatopia start - tic-tacs unblocking
+ Block block = this.world.getBlockStateIfLoaded(this.getChunkCoordinates()).getBlock();
float f = block.getSpeedFactor();
- return block != Blocks.WATER && block != Blocks.BUBBLE_COLUMN ? ((double) f == 1.0D ? this.world.getType(this.as()).getBlock().getSpeedFactor() : f) : f;
+ return block != Blocks.WATER && block != Blocks.BUBBLE_COLUMN ? ((double) f == 1.0D ? this.world.getBlockStateIfLoaded(this.as()).getBlock().getSpeedFactor() : f) : f;
+ // Yatopia end
}
protected BlockPosition as() {
@@ -1305,7 +1318,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, ne
for (int i = blockposition.getX(); i <= blockposition1.getX(); ++i) {
// Tuinity end - reorder iteration to more cache aware
blockposition_mutableblockposition.d(i, j, k);
- IBlockData iblockdata = this.world.getType(blockposition_mutableblockposition);
+ IBlockData iblockdata = this.world.getBlockStateIfLoaded(blockposition_mutableblockposition);
// Tuinity start - move fire checking in here - reuse getType from this method
if (checkFire) {
@@ -1341,7 +1354,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, ne
protected void b(BlockPosition blockposition, IBlockData iblockdata) {
if (!iblockdata.getMaterial().isLiquid()) {
- IBlockData iblockdata1 = this.world.getType(blockposition.up());
+ IBlockData iblockdata1 = this.world.getBlockStateIfLoaded(blockposition.up()); // Yatopia
SoundEffectType soundeffecttype = iblockdata1.a(Blocks.SNOW) ? iblockdata1.getStepSound() : iblockdata.getStepSound();
this.playSound(soundeffecttype.getStepSound(), soundeffecttype.getVolume() * 0.15F, soundeffecttype.getPitch());
@@ -1432,7 +1445,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, ne
public final boolean isInBubbleColumn() { return k(); } // Paper - OBFHELPER
private boolean k() {
- return this.world.getType(this.getChunkCoordinates()).a(Blocks.BUBBLE_COLUMN);
+ return this.world.getBlockStateIfLoaded(this.getChunkCoordinates()).a(Blocks.BUBBLE_COLUMN); // Yatopia
}
public boolean isInWaterOrRain() {
@@ -1503,7 +1516,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, ne
}
BlockPosition blockposition = new BlockPosition(this.locX(), d0, this.locZ());
- Fluid fluid = this.world.getFluid(blockposition);
+ Fluid fluid = this.world.getFluidStateIfLoaded(blockposition); // Yatopia
Iterator iterator = TagsFluid.b().iterator();
Tag tag;
@@ -1561,7 +1574,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, ne
}
protected IBlockData aN() {
- return this.world.getType(this.ap());
+ return this.world.getBlockStateIfLoaded(this.ap()); // Yatopia
}
public boolean aO() {
@@ -1573,7 +1586,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, ne
int j = MathHelper.floor(this.locY() - 0.20000000298023224D);
int k = MathHelper.floor(this.locZ());
BlockPosition blockposition = new BlockPosition(i, j, k);
- IBlockData iblockdata = this.world.getType(blockposition);
+ IBlockData iblockdata = this.world.getBlockStateIfLoaded(blockposition); // Yatopia
if (iblockdata.h() != EnumRenderType.INVISIBLE) {
Vec3D vec3d = this.getMot();
@@ -2827,7 +2840,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, ne
EnumDirection enumdirection1 = aenumdirection[j];
blockposition_mutableblockposition.a((BaseBlockPosition) blockposition, enumdirection1);
- if (!this.world.getType(blockposition_mutableblockposition).r(this.world, blockposition_mutableblockposition)) {
+ if (!this.world.getBlockStateIfLoaded(blockposition_mutableblockposition).r(this.world, blockposition_mutableblockposition)) { // Yatopia
double d4 = vec3d.a(enumdirection1.n());
double d5 = enumdirection1.e() == EnumDirection.EnumAxisDirection.POSITIVE ? 1.0D - d4 : d4;
@@ -3043,14 +3056,14 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, ne
return (ShapeDetectorShape) this.findOrCreatePortal(worldserver, blockposition, flag2, event.getSearchRadius(), event.getCanCreatePortal(), event.getCreationRadius()).map((blockutil_rectangle) -> {
// CraftBukkit end
- IBlockData iblockdata = this.world.getType(this.ac);
+ IBlockData iblockdata = this.world.getBlockStateIfLoaded(this.ac); // Yatopia
EnumDirection.EnumAxis enumdirection_enumaxis;
Vec3D vec3d;
if (iblockdata.b(BlockProperties.E)) {
enumdirection_enumaxis = (EnumDirection.EnumAxis) iblockdata.get(BlockProperties.E);
BlockUtil.Rectangle blockutil_rectangle1 = BlockUtil.a(this.ac, enumdirection_enumaxis, 21, EnumDirection.EnumAxis.Y, 21, (blockposition1) -> {
- return this.world.getType(blockposition1) == iblockdata;
+ return this.world.getBlockStateIfLoaded(blockposition1) == iblockdata; // Yatopia
});
vec3d = this.a(enumdirection_enumaxis, blockutil_rectangle1);
@@ -3417,6 +3430,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, ne
}
public boolean cl() {
+ if (!this.updateNeeded) this.chunkPosUpdateRequested = true; // Yatopia
boolean flag = this.au;
this.au = false;
@@ -3620,7 +3634,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, ne
for (int i2 = k; i2 < l; ++i2) {
for (int j2 = i1; j2 < j1; ++j2) {
blockposition_mutableblockposition.d(l1, i2, j2);
- Fluid fluid = this.world.getFluid(blockposition_mutableblockposition);
+ Fluid fluid = this.world.getFluidStateIfLoaded(blockposition_mutableblockposition); // Yatopia
if (fluid.a(tag)) {
double d2 = (double) ((float) i2 + fluid.getHeight(this.world, blockposition_mutableblockposition));
diff --git a/src/main/java/net/minecraft/world/entity/EntityLiving.java b/src/main/java/net/minecraft/world/entity/EntityLiving.java
index fb62d5bfe188a7ae82a038454cbf0db10de23dda..2f5960a85b3599f369ad334f3b3a0bae8fad8ecf 100644
--- a/src/main/java/net/minecraft/world/entity/EntityLiving.java
+++ b/src/main/java/net/minecraft/world/entity/EntityLiving.java
@@ -140,6 +140,7 @@ import org.bukkit.event.entity.EntityTeleportEvent;
import org.bukkit.event.player.PlayerItemConsumeEvent;
// CraftBukkit end
+import net.gegy1000.tictacs.NonBlockingWorldAccess; // Yatopia
public abstract class EntityLiving extends Entity {
@@ -393,7 +394,7 @@ public abstract class EntityLiving extends Entity {
boolean flag1 = flag && ((EntityHuman) this).abilities.isInvulnerable;
if (this.isAlive()) {
- if (this.a((Tag) TagsFluid.WATER) && !this.world.getType(new BlockPosition(this.locX(), this.getHeadY(), this.locZ())).a(Blocks.BUBBLE_COLUMN)) {
+ if (this.a((Tag) TagsFluid.WATER) && !this.world.getBlockStateIfLoaded(new BlockPosition(this.locX(), this.getHeadY(), this.locZ())).a(Blocks.BUBBLE_COLUMN)) { // Yatopia
if (!this.canBreatheUnderwater() && !MobEffectUtil.c(this) && !flag1) { // Paper - use OBFHELPER so it can be overridden
this.setAirTicks(this.l(this.getAirTicks()));
if (this.getAirTicks() == -this.world.purpurConfig.drowningDamageInterval) { // Purpur
@@ -486,7 +487,7 @@ public abstract class EntityLiving extends Entity {
}
protected boolean cP() {
- return this.world.getType(this.as()).a((Tag) TagsBlock.SOUL_SPEED_BLOCKS);
+ return this.world.getBlockStateIfLoaded(this.as()).a((Tag) TagsBlock.SOUL_SPEED_BLOCKS); // Yatopia
}
@Override
@@ -534,6 +535,8 @@ public abstract class EntityLiving extends Entity {
}
protected void c(BlockPosition blockposition) {
+ if (!this.world.isLoaded(blockposition)) return; // Yatopia
+
int i = EnchantmentManager.a(Enchantments.FROST_WALKER, this);
if (i > 0) {
@@ -1580,7 +1583,7 @@ public abstract class EntityLiving extends Entity {
BlockPosition blockposition = this.getChunkCoordinates();
IBlockData iblockdata = Blocks.WITHER_ROSE.getBlockData();
- if (this.world.getType(blockposition).isAir() && iblockdata.canPlace(this.world, blockposition)) {
+ if (this.world.getBlockStateIfLoaded(blockposition).isAir() && iblockdata.canPlace(this.world, blockposition)) { // Yatopia
this.world.setTypeAndData(blockposition, iblockdata, 3);
flag = true;
}
@@ -1772,12 +1775,12 @@ public abstract class EntityLiving extends Entity {
}
public IBlockData ds() {
- return this.world.getType(this.getChunkCoordinates());
+ return this.world.getBlockStateIfLoaded(this.getChunkCoordinates()); // Yatopia
}
private boolean c(BlockPosition blockposition, IBlockData iblockdata) {
if ((Boolean) iblockdata.get(BlockTrapdoor.OPEN)) {
- IBlockData iblockdata1 = this.world.getType(blockposition.down());
+ IBlockData iblockdata1 = this.world.getBlockStateIfLoaded(blockposition.down()); // Yatopia
if (iblockdata1.a(Blocks.LADDER) && iblockdata1.get(BlockLadder.FACING) == iblockdata.get(BlockTrapdoor.FACING)) {
return true;
@@ -1824,7 +1827,7 @@ public abstract class EntityLiving extends Entity {
int i = MathHelper.floor(this.locX());
int j = MathHelper.floor(this.locY() - 0.20000000298023224D);
int k = MathHelper.floor(this.locZ());
- IBlockData iblockdata = this.world.getType(new BlockPosition(i, j, k));
+ IBlockData iblockdata = this.world.getBlockStateIfLoaded(new BlockPosition(i, j, k)); // Yatopia
if (!iblockdata.isAir()) {
SoundEffectType soundeffecttype = iblockdata.getStepSound();
@@ -2315,7 +2318,7 @@ public abstract class EntityLiving extends Entity {
private void a(Entity entity) {
Vec3D vec3d;
- if (!entity.dead && !this.world.getType(entity.getChunkCoordinates()).getBlock().a((Tag) TagsBlock.PORTALS)) {
+ if (!entity.dead && !this.world.getBlockStateIfLoaded(entity.getChunkCoordinates()).getBlock().a((Tag) TagsBlock.PORTALS)) { // Yatopia
vec3d = entity.b(this);
} else {
vec3d = new Vec3D(entity.locX(), entity.locY() + (double) entity.getHeight(), entity.locZ());
@@ -2369,7 +2372,7 @@ public abstract class EntityLiving extends Entity {
this.fallDistance = 0.0F;
}
- Fluid fluid = this.world.getFluid(this.getChunkCoordinates());
+ Fluid fluid = this.world.getFluidStateIfLoaded(this.getChunkCoordinates()); // Yatopia
double d1;
float f;
@@ -2485,7 +2488,7 @@ public abstract class EntityLiving extends Entity {
}
} else {
BlockPosition blockposition = this.as();
- float f5 = this.world.getType(blockposition).getBlock().getFrictionFactor();
+ float f5 = this.world.getBlockStateIfLoaded(blockposition).getBlock().getFrictionFactor(); // Yatopia
f = this.onGround ? f5 * 0.91F : 0.91F;
Vec3D vec3d6 = this.a(vec3d, f5);
@@ -3546,7 +3549,7 @@ public abstract class EntityLiving extends Entity {
while (!flag2 && blockposition.getY() > 0) {
BlockPosition blockposition1 = blockposition.down();
- IBlockData iblockdata = world.getType(blockposition1);
+ IBlockData iblockdata = this.world.getBlockStateIfLoaded(blockposition1); // Yatopia
if (iblockdata.getMaterial().isSolid()) {
flag2 = true;
@@ -3641,7 +3644,7 @@ public abstract class EntityLiving extends Entity {
this.stopRiding();
}
- IBlockData iblockdata = this.world.getType(blockposition);
+ IBlockData iblockdata = this.world.getBlockStateIfLoaded(blockposition); // Yatopia
if (iblockdata.getBlock() instanceof BlockBed) {
this.world.setTypeAndData(blockposition, (IBlockData) iblockdata.set(BlockBed.OCCUPIED, true), 3);
@@ -3660,7 +3663,7 @@ public abstract class EntityLiving extends Entity {
private boolean x() {
return (Boolean) this.getBedPosition().map((blockposition) -> {
- return this.world.getType(blockposition).getBlock() instanceof BlockBed;
+ return this.world.getBlockStateIfLoaded(blockposition).getBlock() instanceof BlockBed; // Yatopia
}).orElse(false);
}
@@ -3670,7 +3673,7 @@ public abstract class EntityLiving extends Entity {
this.world.getClass();
optional.filter(world::isLoaded).ifPresent((blockposition) -> {
- IBlockData iblockdata = this.world.getType(blockposition);
+ IBlockData iblockdata = this.world.getBlockStateIfLoaded(blockposition); // Yatopia
if (iblockdata.getBlock() instanceof BlockBed) {
this.world.setTypeAndData(blockposition, (IBlockData) iblockdata.set(BlockBed.OCCUPIED, false), 3);
diff --git a/src/main/java/net/minecraft/world/level/World.java b/src/main/java/net/minecraft/world/level/World.java
index aed97af643b8ec9b6fd5a5f06ff4f364daf39742..f5badbe0dee5c40cf83a5d2993d27ed70ddd2c85 100644
--- a/src/main/java/net/minecraft/world/level/World.java
+++ b/src/main/java/net/minecraft/world/level/World.java
@@ -96,7 +96,9 @@ import org.bukkit.craftbukkit.block.data.CraftBlockData;
import org.bukkit.event.block.BlockPhysicsEvent;
// CraftBukkit end
-public abstract class World implements GeneratorAccess, AutoCloseable {
+import net.gegy1000.tictacs.NonBlockingWorldAccess; // Yatopia
+
+public abstract class World implements GeneratorAccess, AutoCloseable, NonBlockingWorldAccess { // Yatopia
protected static final Logger LOGGER = LogManager.getLogger();
public static final Codec<ResourceKey<World>> f = MinecraftKey.a.xmap(ResourceKey.b(IRegistry.L), ResourceKey::a);
diff --git a/src/main/java/net/minecraft/world/level/material/FluidType.java b/src/main/java/net/minecraft/world/level/material/FluidType.java
index 6a60f53407db840150b84f4d2a709cc2e92362a4..bf3300607f9142486dc790a600d4c2ffa998d376 100644
--- a/src/main/java/net/minecraft/world/level/material/FluidType.java
+++ b/src/main/java/net/minecraft/world/level/material/FluidType.java
@@ -38,6 +38,7 @@ public abstract class FluidType {
this.a = fluid;
}
+ public final Fluid getFluidData() { return this.h(); } // Yatopia - OBFHELPER
public final Fluid h() {
return this.a;
}

View File

@ -0,0 +1,196 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: 2No2Name <50278648+2No2Name@users.noreply.github.com>
Date: Mon, 15 Feb 2021 14:58:55 -0500
Subject: [PATCH] lithium: optimize `BlockPos.iterateOutwards` by caching
offsets
Code taken from: https://github.com/CaffeineMC/lithium-fabric/pull/123 by 2No2Name licenced under the LGPLv3 License
diff --git a/src/main/java/me/jellysquid/mods/lithium/common/cached_blockpos_iteration/IterateOutwardsCache.java b/src/main/java/me/jellysquid/mods/lithium/common/cached_blockpos_iteration/IterateOutwardsCache.java
new file mode 100644
index 0000000000000000000000000000000000000000..50e9df6056f713b2f1eaf0cb4a23875e0c6c2e2c
--- /dev/null
+++ b/src/main/java/me/jellysquid/mods/lithium/common/cached_blockpos_iteration/IterateOutwardsCache.java
@@ -0,0 +1,72 @@
+package me.jellysquid.mods.lithium.common.cached_blockpos_iteration;
+
+import it.unimi.dsi.fastutil.longs.LongArrayList;
+import it.unimi.dsi.fastutil.longs.LongList;
+import net.minecraft.core.BlockPosition;
+
+import java.util.Iterator;
+import java.util.Random;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * @author 2No2Name, original implemenation by SuperCoder7979 and Gegy1000
+ */
+public class IterateOutwardsCache {
+ //POS_ZERO must not be replaced with BlockPos.ORIGIN, otherwise iterateOutwards at BlockPos.ORIGIN will not use the cache
+ public static final BlockPosition POS_ZERO = new BlockPosition(0,0,0);
+
+
+ private final ConcurrentHashMap<Long, LongArrayList> table;
+ private final int capacity;
+ private final Random random;
+
+ public IterateOutwardsCache(int capacity) {
+ this.capacity = capacity;
+ this.table = new ConcurrentHashMap<>(31);
+ this.random = new Random();
+ }
+
+ private void fillPositionsWithIterateOutwards(LongList entry, int xRange, int yRange, int zRange) {
+ // Add all positions to the cached list
+ for (BlockPosition pos : BlockPosition.iterateOutwards(POS_ZERO, xRange, yRange, zRange)) {
+ entry.add(pos.asLong());
+ }
+ }
+
+ public LongList getOrCompute(int xRange, int yRange, int zRange) {
+ long key = BlockPosition.asLong(xRange, yRange, zRange);
+
+ LongArrayList entry = this.table.get(key);
+ if (entry != null) {
+ return entry;
+ }
+
+ // Cache miss: compute and store
+ entry = new LongArrayList(128);
+
+ this.fillPositionsWithIterateOutwards(entry, xRange, yRange, zRange);
+
+ //decrease the array size, as of now it won't be modified anymore anyways
+ entry.trim();
+
+ //this might overwrite an entry as the same entry could have been computed and added during this thread's computation
+ //we do not use computeIfAbsent, as it can delay other threads for too long
+ Object previousEntry = this.table.put(key, entry);
+
+
+ if (previousEntry == null && this.table.size() > this.capacity) {
+ //prevent a memory leak by randomly removing about 1/8th of the elements when the exceed the desired capacity is exceeded
+ final Iterator<Long> iterator = this.table.keySet().iterator();
+ //prevent an unlikely infinite loop caused by another thread filling the table concurrently using counting
+ for (int i = -this.capacity; iterator.hasNext() && i < 5; i++) {
+ Long key2 = iterator.next();
+ //random is not threadsafe, but it doesn't matter here, because we don't need quality random numbers
+ if (this.random.nextInt(8) == 0 && key2 != key) {
+ iterator.remove();
+ }
+ }
+ }
+
+ return entry;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/me/jellysquid/mods/lithium/common/cached_blockpos_iteration/LongList2BlockPosMutableIterable.java b/src/main/java/me/jellysquid/mods/lithium/common/cached_blockpos_iteration/LongList2BlockPosMutableIterable.java
new file mode 100644
index 0000000000000000000000000000000000000000..e2e4f7968a399b4641df07b2931fff6dbc85ddb3
--- /dev/null
+++ b/src/main/java/me/jellysquid/mods/lithium/common/cached_blockpos_iteration/LongList2BlockPosMutableIterable.java
@@ -0,0 +1,47 @@
+package me.jellysquid.mods.lithium.common.cached_blockpos_iteration;
+
+import it.unimi.dsi.fastutil.longs.LongIterator;
+import it.unimi.dsi.fastutil.longs.LongList;
+import net.minecraft.core.BlockPosition;
+
+import java.util.Iterator;
+
+/**
+ * @author 2No2Name
+ */
+public class LongList2BlockPosMutableIterable implements Iterable<BlockPosition> {
+
+ private final LongList positions;
+ private final int xOffset, yOffset, zOffset;
+
+ public LongList2BlockPosMutableIterable(BlockPosition offset, LongList posList) {
+ this.xOffset = offset.getX();
+ this.yOffset = offset.getY();
+ this.zOffset = offset.getZ();
+ this.positions = posList;
+ }
+
+ @Override
+ public Iterator<BlockPosition> iterator() {
+ return new Iterator<BlockPosition>() {
+
+ private final LongIterator it = LongList2BlockPosMutableIterable.this.positions.iterator();
+ private final BlockPosition.MutableBlockPosition pos = new BlockPosition.MutableBlockPosition();
+
+ @Override
+ public boolean hasNext() {
+ return it.hasNext();
+ }
+
+ @Override
+ public BlockPosition next() {
+ long nextPos = this.it.nextLong();
+ return this.pos.setValues(
+ LongList2BlockPosMutableIterable.this.xOffset + BlockPosition.unpackLongX(nextPos),
+ LongList2BlockPosMutableIterable.this.yOffset + BlockPosition.unpackLongY(nextPos),
+ LongList2BlockPosMutableIterable.this.zOffset + BlockPosition.unpackLongZ(nextPos));
+ }
+ };
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/net/minecraft/core/BlockPosition.java b/src/main/java/net/minecraft/core/BlockPosition.java
index 9c508cc41575175d442cd51d75706830351a24f2..df6df2ae3e30ada07c90a26b9615d939508d3246 100644
--- a/src/main/java/net/minecraft/core/BlockPosition.java
+++ b/src/main/java/net/minecraft/core/BlockPosition.java
@@ -19,10 +19,16 @@ import net.minecraft.world.phys.Vec3D;
import org.apache.commons.lang3.Validate;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
+import me.jellysquid.mods.lithium.common.cached_blockpos_iteration.IterateOutwardsCache; // Yatopia
+import me.jellysquid.mods.lithium.common.cached_blockpos_iteration.LongList2BlockPosMutableIterable; // Yatopia
+import it.unimi.dsi.fastutil.longs.LongList; // Yatopia
@Immutable
public class BlockPosition extends BaseBlockPosition {
+ private static final IterateOutwardsCache ITERATE_OUTWARDS_CACHE = new IterateOutwardsCache(50); // Yatopia
+ private static final LongList HOGLIN_PIGLIN_CACHE = ITERATE_OUTWARDS_CACHE.getOrCompute(8, 4, 8); // Yatopia
+
public static final Codec<BlockPosition> a = Codec.INT_STREAM.comapFlatMap((intstream) -> {
return SystemUtils.a(intstream, 3).map((aint) -> {
return new BlockPosition(aint[0], aint[1], aint[2]);
@@ -78,14 +84,17 @@ public class BlockPosition extends BaseBlockPosition {
return a((int) (i >> 38) + j, (int) ((i << 52) >> 52) + k, (int) ((i << 26) >> 38) + l); // Paper - simplify/inline
}
+ public static int unpackLongX(long i) { return BlockPosition.b(i); } // Yatopia - OBFHELPER
public static int b(long i) {
return (int) (i >> 38); // Paper - simplify/inline
}
+ public static int unpackLongY(long i) { return BlockPosition.c(i); } // Yatopia - OBFHELPER
public static int c(long i) {
return (int) ((i << 52) >> 52); // Paper - simplify/inline
}
+ public static int unpackLongZ(long i) { return BlockPosition.d(i); } // Yatopia - OBFHELPER
public static int d(long i) {
return (int) ((i << 26) >> 38); // Paper - simplify/inline
}
@@ -266,7 +275,15 @@ public class BlockPosition extends BaseBlockPosition {
};
}
+ public static Iterable<BlockPosition> iterateOutwards(BlockPosition blockposition, int p_i, int p_j, int p_k) { return BlockPosition.a(blockposition, p_i, p_j, p_k); } // Yatopia - OBFHELPER
public static Iterable<BlockPosition> a(BlockPosition blockposition, int p_i, int p_j, int p_k) { // Paper - decompile issues - variable name conflicts to inner class field refs
+ // Yatopia start - lithium: optimize `BlockPos.iterateOutwards` by caching offsets
+ if (blockposition != me.jellysquid.mods.lithium.common.cached_blockpos_iteration.IterateOutwardsCache.POS_ZERO) {
+ final LongList positions = p_i == 8 && p_j == 4 && p_k == 8 ? HOGLIN_PIGLIN_CACHE : ITERATE_OUTWARDS_CACHE.getOrCompute(p_i, p_j, p_j);
+ return new LongList2BlockPosMutableIterable(blockposition, positions);
+ }
+ // Yatopia end
+
int l_decompiled = p_i + p_j + p_k; // Paper - decompile issues
int i1 = blockposition.getX();
int j1 = blockposition.getY();

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,232 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: JellySquid <jellysquid+atwork@protonmail.com>
Date: Sun, 24 Jan 2021 16:57:03 +0100
Subject: [PATCH] lithium block
Co-authored-by: Hugo Planque <hookwood01@gmail.com>
diff --git a/src/main/java/me/jellysquid/mods/lithium/common/util/tuples/FinalObject.java b/src/main/java/me/jellysquid/mods/lithium/common/util/tuples/FinalObject.java
new file mode 100644
index 0000000000000000000000000000000000000000..f78927e71258e859154cca8ba78d17130b0d82c1
--- /dev/null
+++ b/src/main/java/me/jellysquid/mods/lithium/common/util/tuples/FinalObject.java
@@ -0,0 +1,20 @@
+package me.jellysquid.mods.lithium.common.util.tuples;
+
+/**
+ * The purpose of this class is safe publication of the wrapped value. (JLS 17.5)
+ */
+public class FinalObject<T> {
+ private final T value;
+
+ public FinalObject(T value) {
+ this.value = value;
+ }
+
+ public FinalObject<T> of(T value) {
+ return new FinalObject<>(value);
+ }
+
+ public T getValue() {
+ return value;
+ }
+}
diff --git a/src/main/java/net/minecraft/core/EnumDirection.java b/src/main/java/net/minecraft/core/EnumDirection.java
index b8fe75b8c37ef1968519e69e078444b1a3c5c359..a825b17e454138e181926df3f2faa6d9d7af4055 100644
--- a/src/main/java/net/minecraft/core/EnumDirection.java
+++ b/src/main/java/net/minecraft/core/EnumDirection.java
@@ -100,6 +100,7 @@ public enum EnumDirection implements INamable {
return new EnumDirection[]{enumdirection, enumdirection1, enumdirection2, enumdirection2.opposite(), enumdirection1.opposite(), enumdirection.opposite()};
}
+ public int get3DDataValue(){ return c(); } // Yatopia - OBFHELPER
public int c() {
return this.g;
}
diff --git a/src/main/java/net/minecraft/world/level/block/piston/TileEntityPiston.java b/src/main/java/net/minecraft/world/level/block/piston/TileEntityPiston.java
index 58c7a52612fe0f5c1e4ddacc0bf93cd81f1286b8..af2a8fdcaf5962334dcc20717f3a1ad14aebcbcb 100644
--- a/src/main/java/net/minecraft/world/level/block/piston/TileEntityPiston.java
+++ b/src/main/java/net/minecraft/world/level/block/piston/TileEntityPiston.java
@@ -29,9 +29,9 @@ import net.minecraft.world.phys.shapes.VoxelShapes;
public class TileEntityPiston extends TileEntity implements ITickable {
private IBlockData a;
- private EnumDirection b;
- private boolean c;
- private boolean g;
+ private EnumDirection b; public EnumDirection getFacing() { return b; } // Yatopia - OBFHELPER
+ private boolean c; public boolean isExtending() { return c; } // Yatopia - OBFHELPER
+ private boolean g; public boolean isSource() { return g; } // Yatopia - OBFHELPER
private static final ThreadLocal<EnumDirection> h = ThreadLocal.withInitial(() -> {
return null;
});
@@ -40,6 +40,74 @@ public class TileEntityPiston extends TileEntity implements ITickable {
private long k;
private int l;
+ // Yatopia start - Port Lithium
+ private static final VoxelShape[] PISTON_BASE_WITH_MOVING_HEAD_SHAPES = precomputePistonBaseWithMovingHeadShapes();
+ /**
+ * We cache the offset and simplified VoxelShapes that are otherwise constructed on every call of getCollisionShape.
+ * For each offset direction and distance (6 directions, 2 distances each, and no direction with 0 distance) we
+ * store the offset and simplified VoxelShapes in the original VoxelShape when they are accessed the first time.
+ * We use safe publication, because both the Render and Server thread are using the cache.
+ *
+ * @param blockShape the original shape, must not be modified after passing it as an argument to this method
+ * @param offset the offset distance
+ * @param direction the offset direction
+ * @return blockShape offset and simplified
+ */
+ private static VoxelShape getOffsetAndSimplified(VoxelShape blockShape, float offset, EnumDirection direction) {
+ VoxelShape offsetSimplifiedShape = blockShape.getOffsetSimplifiedShape(offset, direction);
+ if (offsetSimplifiedShape == null) {
+ //create the offset shape and store it for later use
+ offsetSimplifiedShape = blockShape.offset(direction.getAdjacentX() * offset, direction.getAdjacentY() * offset, direction.getAdjacentZ() * offset).simplify();
+ blockShape.setShape(offset, direction, offsetSimplifiedShape);
+ }
+ return offsetSimplifiedShape;
+ }
+
+ /**
+ * Precompute all 18 possible configurations for the merged piston base and head shape.
+ *
+ * @return The array of the merged VoxelShapes, indexed by {@link TileEntityPiston#getIndexForMergedShape(float, EnumDirection)}
+ */
+ private static VoxelShape[] precomputePistonBaseWithMovingHeadShapes() {
+ float[] offsets = {0f, 0.5f, 1f};
+ EnumDirection[] directions = EnumDirection.values();
+
+ VoxelShape[] mergedShapes = new VoxelShape[offsets.length * directions.length];
+
+ for (EnumDirection facing : directions) {
+ VoxelShape baseShape = Blocks.PISTON.getBlockData().set(BlockPiston.EXTENDED, true)
+ .set(BlockPiston.FACING, facing).getCollisionShape(null, null);
+ for (float offset : offsets) {
+ //this cache is only required for the merged piston head + base shape.
+ //this shape is only used when !this.extending
+ //here: isShort = this.extending != 1.0F - this.progress < 0.25F can be simplified to:
+ //isShort = f < 0.25F , because f = getAmountExtended(this.progress) can be simplified to f == 1.0F - this.progress
+ //therefore isShort is dependent on the offset:
+ boolean isShort = offset < 0.25f;
+
+ VoxelShape headShape = (Blocks.PISTON_HEAD.getBlockData().set(BlockPistonExtension.FACING, facing))
+ .set(BlockPistonExtension.SHORT, isShort).getCollisionShape(null, null);
+
+ VoxelShape offsetHead = headShape.offset(facing.getAdjacentX() * offset,
+ facing.getAdjacentY() * offset,
+ facing.getAdjacentZ() * offset);
+ mergedShapes[getIndexForMergedShape(offset, facing)] = VoxelShapes.union(baseShape, offsetHead);
+ }
+
+ }
+
+ return mergedShapes;
+ }
+
+ private static int getIndexForMergedShape(float offset, EnumDirection direction) {
+ if (offset != 0f && offset != 0.5f && offset != 1f) {
+ return -1;
+ }
+ //shape of offset 0 is still dependent on the direction, due to piston head and base being directional blocks
+ return (int) (2 * offset) + (3 * direction.get3DDataValue());
+ }
+ // Yatopia End
+
public TileEntityPiston() {
super(TileEntityTypes.PISTON);
}
@@ -350,13 +418,21 @@ public class TileEntityPiston extends TileEntity implements ITickable {
} else {
iblockdata = this.a;
}
+ float f = this.e(this.i); // Yatopia Start - Port Lithium
+ if (this.isExtending() || !this.isSource()) {
+ //here voxelShape2.isEmpty() is guaranteed, vanilla code would call union() which calls simplify()
+ VoxelShape blockShape = iblockdata.getCollisionShape(iblockaccess, blockposition);
+
+ //we cache the simplified shapes, as the simplify() method costs a lot of CPU time and allocates several objects
+ VoxelShape offsetAndSimplified = getOffsetAndSimplified(blockShape, Math.abs(f), f < 0f ? this.getFacing().opposite() : this.getFacing());
+ return offsetAndSimplified;
+ } else {
+ //retracting piston heads have to act like their base as well, as the base block is replaced with the moving block
+ //f >= 0f is guaranteed (assuming no other mod interferes)
+ int index = getIndexForMergedShape(f, this.getFacing());
+ return PISTON_BASE_WITH_MOVING_HEAD_SHAPES[index];
+ } // Yatopia End
- float f = this.e(this.i);
- double d0 = (double) ((float) this.b.getAdjacentX() * f);
- double d1 = (double) ((float) this.b.getAdjacentY() * f);
- double d2 = (double) ((float) this.b.getAdjacentZ() * f);
-
- return VoxelShapes.a(voxelshape, iblockdata.getCollisionShape(iblockaccess, blockposition).a(d0, d1, d2));
}
}
diff --git a/src/main/java/net/minecraft/world/phys/shapes/VoxelShape.java b/src/main/java/net/minecraft/world/phys/shapes/VoxelShape.java
index 9567630593da7c77a0173b93c9a57ceb7887a59b..fbc5fab9946b6f9233f3014f0e69f2576b2138d7 100644
--- a/src/main/java/net/minecraft/world/phys/shapes/VoxelShape.java
+++ b/src/main/java/net/minecraft/world/phys/shapes/VoxelShape.java
@@ -13,9 +13,50 @@ import net.minecraft.util.MathHelper;
import net.minecraft.world.phys.AxisAlignedBB;
import net.minecraft.world.phys.MovingObjectPositionBlock;
import net.minecraft.world.phys.Vec3D;
+import me.jellysquid.mods.lithium.common.util.tuples.FinalObject; // Yatopia
public abstract class VoxelShape {
+ // Yatopia - Port Lithium
+ private FinalObject<VoxelShape>[] offsetAndSimplified;
+
+ public void setShape(float offset, EnumDirection direction, VoxelShape offsetShape) {
+ if (offsetShape == null) {
+ throw new IllegalArgumentException("offsetShape must not be null!");
+ }
+ int index = getIndexForOffsetSimplifiedShapes(offset, direction);
+ FinalObject<VoxelShape>[] offsetAndSimplified = this.offsetAndSimplified;
+ if (offsetAndSimplified == null) {
+ //noinspection unchecked
+ this.offsetAndSimplified = (offsetAndSimplified = new FinalObject[1 + (2 * 6)]);
+ }
+ //using FinalObject as it stores the value in a final field, which guarantees safe publication
+ offsetAndSimplified[index] = new FinalObject<>(offsetShape);
+ }
+
+ public VoxelShape getOffsetSimplifiedShape(float offset, EnumDirection direction) {
+ FinalObject<VoxelShape>[] offsetAndSimplified = this.offsetAndSimplified;
+ if (offsetAndSimplified == null) {
+ return null;
+ }
+ int index = getIndexForOffsetSimplifiedShapes(offset, direction);
+ //usage of FinalObject guarantees that we are seeing a fully initialized VoxelShape here, even when it was created on a different thread
+ FinalObject<VoxelShape> wrappedShape = offsetAndSimplified[index];
+ //noinspection FinalObjectAssignedToNull,FinalObjectGetWithoutIsPresent
+ return wrappedShape == null ? null : wrappedShape.getValue();
+ }
+
+ private static int getIndexForOffsetSimplifiedShapes(float offset, EnumDirection direction) {
+ if (offset != 0f && offset != 0.5f && offset != 1f) {
+ throw new IllegalArgumentException("offset must be one of {0f, 0.5f, 1f}");
+ }
+ if (offset == 0f) {
+ return 0; //can treat offsetting by 0 in all directions the same
+ }
+ return (int) (2 * offset) + 2 * direction.get3DDataValue();
+ }
+ // Yatopia End
+
protected final VoxelShapeDiscrete a; public final VoxelShapeDiscrete getShape() { return this.a; } // Tuinity - OBFHELPER
@Nullable
private VoxelShape[] b;
diff --git a/src/main/java/net/minecraft/world/phys/shapes/VoxelShapes.java b/src/main/java/net/minecraft/world/phys/shapes/VoxelShapes.java
index 98e787e6383a39de1708428137fd7f9e057ff153..049aa5f51e7517744b25f8c2c4b5e7a7de24a73e 100644
--- a/src/main/java/net/minecraft/world/phys/shapes/VoxelShapes.java
+++ b/src/main/java/net/minecraft/world/phys/shapes/VoxelShapes.java
@@ -187,6 +187,7 @@ public final class VoxelShapes {
return (long) i * (long) (j / IntMath.gcd(i, j));
}
+ public static VoxelShape union(VoxelShape voxelshape, VoxelShape voxelshape1) { return a(voxelshape, voxelshape1); } // Yatopia - OBFHELPER
public static VoxelShape a(VoxelShape voxelshape, VoxelShape voxelshape1) {
return a(voxelshape, voxelshape1, OperatorBoolean.OR);
}

View File

@ -0,0 +1,60 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: JellySquid <jellysquid+atwork@protonmail.com>
Date: Sun, 24 Jan 2021 22:55:55 +0100
Subject: [PATCH] lithium entity
Co-authored-by: Hugo Planque <hookwood01@gmail.com>
diff --git a/src/main/java/net/minecraft/world/entity/EntityLiving.java b/src/main/java/net/minecraft/world/entity/EntityLiving.java
index bbe9eea55b18e1198916df29cbd922092b485eed..6a24932b17bb8d2e48334e61bfd5290c1c1e2be6 100644
--- a/src/main/java/net/minecraft/world/entity/EntityLiving.java
+++ b/src/main/java/net/minecraft/world/entity/EntityLiving.java
@@ -286,6 +286,10 @@ public abstract class EntityLiving extends Entity {
public NearbyEntityListenerMulti getListener() {
return this.tracker;
}
+
+ private IBlockData lastStateAtFeet = null;
+
+ private long lastPos = Long.MIN_VALUE;
// Yatopia end
protected void initAttributes() {} // Purpur
@@ -363,6 +367,10 @@ public abstract class EntityLiving extends Entity {
@Override
public void entityBaseTick() {
+ // Yatopia start - port lithium
+ this.lastStateAtFeet = null;
+ this.lastPos = Long.MIN_VALUE;
+ // Yatopia end
this.ar = this.as;
if (this.justCreated) {
this.getBedPosition().ifPresent(this::a);
@@ -1784,6 +1792,26 @@ public abstract class EntityLiving extends Entity {
public IBlockData ds() {
return this.world.getBlockStateIfLoaded(this.getChunkCoordinates()); // Yatopia
+ /*
+ // Yatopia start - port lithium
+ int x = MathHelper.floor(this.locX());
+ int y = MathHelper.floor(this.locY());
+ int z = MathHelper.floor(this.locZ());
+
+ long pos = getChunkCoordinates().asLong();
+
+ if (this.lastPos == pos) {
+ return this.lastStateAtFeet;
+ }
+
+ IBlockData state = this.world.getType(getChunkCoordinates());
+
+ this.lastPos = pos;
+ this.lastStateAtFeet = state;
+
+ return state;
+ // Yatopia end
+ */
}
private boolean c(BlockPosition blockposition, IBlockData iblockdata) {

View File

@ -0,0 +1,40 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: JellySquid <jellysquid+atwork@protonmail.com>
Date: Sun, 24 Jan 2021 23:42:56 +0100
Subject: [PATCH] lithium gen
Co-authored-by: Hugo Planque <hookwood01@gmail.com>
diff --git a/src/main/java/net/minecraft/world/level/newbiome/area/AreaLazy.java b/src/main/java/net/minecraft/world/level/newbiome/area/AreaLazy.java
index 69a021b84cd3f6e2a397a03cfbb562a94f72aace..9a897ad2b53e281cf165106d03737d2ec517eb29 100644
--- a/src/main/java/net/minecraft/world/level/newbiome/area/AreaLazy.java
+++ b/src/main/java/net/minecraft/world/level/newbiome/area/AreaLazy.java
@@ -16,6 +16,7 @@ public final class AreaLazy implements Area {
this.a = areatransformer8;
}
+ public int sample(int i, int j){ return a(i, j); } // Yatopia - OBFHELPER
@Override
public int a(int i, int j) {
long k = ChunkCoordIntPair.pair(i, j);
diff --git a/src/main/java/net/minecraft/world/level/newbiome/layer/GenLayer.java b/src/main/java/net/minecraft/world/level/newbiome/layer/GenLayer.java
index 8b61bce3d7587832ddb2c0e29e76f9c68ddf5d8b..acf74fccde2fc1fc3bd065f7d1bd2f5ba7f475e4 100644
--- a/src/main/java/net/minecraft/world/level/newbiome/layer/GenLayer.java
+++ b/src/main/java/net/minecraft/world/level/newbiome/layer/GenLayer.java
@@ -15,13 +15,14 @@ public class GenLayer {
private static final Logger LOGGER = LogManager.getLogger();
private final AreaLazy b;
-
+ private final ThreadLocal<AreaLazy> tlSampler; // Yatopia - Port lithium
public GenLayer(AreaFactory<AreaLazy> areafactory) {
this.b = (AreaLazy) areafactory.make();
+ this.tlSampler = ThreadLocal.withInitial(areafactory::make); // Yatopia - Port lithium
}
public BiomeBase a(IRegistry<BiomeBase> iregistry, int i, int j) {
- int k = this.b.a(i, j);
+ int k = this.tlSampler.get().sample(i, j); // Yatopia - Port lithium
ResourceKey<BiomeBase> resourcekey = BiomeRegistry.a(k);
if (resourcekey == null) {

View File

@ -0,0 +1,358 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: JellySquid <jellysquid+atwork@protonmail.com>
Date: Wed, 27 Jan 2021 21:05:05 +0100
Subject: [PATCH] lithium shape
Co-authored-by: Hugo Planque <hookwood01@gmail.com>
diff --git a/src/main/java/me/jellysquid/mods/lithium/common/block/LithiumEntityShapeContext.java b/src/main/java/me/jellysquid/mods/lithium/common/block/LithiumEntityShapeContext.java
new file mode 100644
index 0000000000000000000000000000000000000000..85d55d144a38a16d0f148a29cd11985d7febe880
--- /dev/null
+++ b/src/main/java/me/jellysquid/mods/lithium/common/block/LithiumEntityShapeContext.java
@@ -0,0 +1,55 @@
+package me.jellysquid.mods.lithium.common.block;
+
+import net.minecraft.core.BlockPosition;
+import net.minecraft.world.entity.Entity;
+import net.minecraft.world.entity.EntityLiving;
+import net.minecraft.core.EnumDirection;
+import net.minecraft.world.level.material.Fluid;
+import net.minecraft.world.level.material.FluidTypeFlowing;
+import net.minecraft.world.item.Item;
+import net.minecraft.world.item.Items;
+import net.minecraft.world.phys.shapes.VoxelShape;
+import net.minecraft.world.phys.shapes.VoxelShapeCollision;
+
+/**
+ * A replacement for EntityShapeContext that does not calculate the heldItem on construction. As most instances never
+ * use this field, a lazy evaluation is faster on average. The initialization of the heldItem field takes about 1% of
+ * the server thread CPU time in a fresh world with lots of animals (singleplayer 1.16.5, renderdistance 24).
+ *
+ * @author 2No2Name
+ */
+public class LithiumEntityShapeContext implements VoxelShapeCollision {
+ private final Entity entity;
+ private final boolean descending;
+ private final double minY;
+ private Item heldItem;
+
+ public LithiumEntityShapeContext(Entity entity) {
+ this.entity = entity;
+ this.descending = entity.isDescending();
+ this.minY = entity.locY();
+ }
+
+ @Override
+ public boolean a(Item item) {
+ if (this.heldItem == null) {
+ this.heldItem = entity instanceof EntityLiving ? ((EntityLiving)entity).getItemInMainHand().getItem() : Items.AIR;
+ }
+ return this.heldItem == item;
+ }
+
+ @Override
+ public boolean a(Fluid aboveState, FluidTypeFlowing fluid) {
+ return this.entity instanceof EntityLiving && ((EntityLiving) this.entity).a(fluid) && !aboveState.getType().a(fluid);
+ }
+
+ @Override
+ public boolean b() {
+ return this.descending;
+ }
+
+ @Override
+ public boolean a(VoxelShape shape, BlockPosition pos, boolean defaultValue) {
+ return this.minY > (double)pos.getY() + shape.getMax(EnumDirection.EnumAxis.Y) - 9.999999747378752E-6D;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/me/jellysquid/mods/lithium/common/shapes/pairs/LithiumDoublePairList.java b/src/main/java/me/jellysquid/mods/lithium/common/shapes/pairs/LithiumDoublePairList.java
new file mode 100644
index 0000000000000000000000000000000000000000..bfa06e714050260779fc8727b4b2cabb6f811398
--- /dev/null
+++ b/src/main/java/me/jellysquid/mods/lithium/common/shapes/pairs/LithiumDoublePairList.java
@@ -0,0 +1,117 @@
+package me.jellysquid.mods.lithium.common.shapes.pairs;
+
+import it.unimi.dsi.fastutil.doubles.DoubleArrayList;
+import it.unimi.dsi.fastutil.doubles.DoubleList;
+import net.minecraft.world.phys.shapes.VoxelShapeMerger;
+
+/**
+ * Optimized variant of {@link net.minecraft.util.shape.SimplePairList}. This implementation works directly against
+ * flat arrays and tries to organize code in a manner that hits the JIT's happy path. In my testing, this is about
+ * ~50% faster than the vanilla implementation.
+ */
+public final class LithiumDoublePairList implements VoxelShapeMerger {
+ private final double[] merged;
+ private final int[] indicesFirst;
+ private final int[] indicesSecond;
+
+ private final DoubleArrayList pairs;
+
+ public LithiumDoublePairList(DoubleList aPoints, DoubleList bPoints, boolean flag1, boolean flag2) {
+ int size = aPoints.size() + bPoints.size();
+
+ this.merged = new double[size];
+ this.indicesFirst = new int[size];
+ this.indicesSecond = new int[size];
+
+ this.pairs = DoubleArrayList.wrap(this.merged);
+
+ this.merge(getArray(aPoints), getArray(bPoints), aPoints.size(), bPoints.size(), flag1, flag2);
+ }
+
+ private void merge(double[] aPoints, double[] bPoints, int aSize, int bSize, boolean flag1, boolean flag2) {
+ int aIdx = 0;
+ int bIdx = 0;
+
+ double prev = 0.0D;
+
+ int a1 = 0, a2 = 0;
+
+ while (true) {
+ boolean aWithinBounds = aIdx < aSize;
+ boolean bWithinBounds = bIdx < bSize;
+
+ if (!aWithinBounds && !bWithinBounds) {
+ break;
+ }
+
+ boolean flip = aWithinBounds && (!bWithinBounds || aPoints[aIdx] < bPoints[bIdx] + 1.0E-7D);
+
+ double value;
+
+ if (flip) {
+ value = aPoints[aIdx++];
+ } else {
+ value = bPoints[bIdx++];
+ }
+
+ if ((aIdx == 0 || !aWithinBounds) && !flip && !flag2) {
+ continue;
+ }
+
+ if ((bIdx == 0 || !bWithinBounds) && flip && !flag1) {
+ continue;
+ }
+
+ if (a2 == 0 || prev < value - 1.0E-7D) {
+ this.indicesFirst[a1] = aIdx - 1;
+ this.indicesSecond[a1] = bIdx - 1;
+ this.merged[a2] = value;
+
+ a1++;
+ a2++;
+ prev = value;
+ } else if (a2 > 0) {
+ this.indicesFirst[a1 - 1] = aIdx - 1;
+ this.indicesSecond[a1 - 1] = bIdx - 1;
+ }
+ }
+
+ if (a2 == 0) {
+ this.merged[a2++] = Math.min(aPoints[aSize - 1], bPoints[bSize - 1]);
+ }
+
+ this.pairs.size(a2);
+ }
+
+ @Override
+ public boolean a(VoxelShapeMerger.a predicate) {
+ int l = this.pairs.size() - 1;
+
+ for (int i = 0; i < l; i++) {
+ if (!predicate.merge(this.indicesFirst[i], this.indicesSecond[i], i)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ @Override
+ public DoubleList a() {
+ return this.pairs;
+ }
+
+ private static double[] getArray(DoubleList list) {
+ if (list instanceof DoubleArrayList) {
+ return ((DoubleArrayList) list).elements();
+ }
+
+ double[] points = new double[list.size()];
+
+ for (int i = 0; i < points.length; i++) {
+ points[i] = list.getDouble(i);
+ }
+
+ return points;
+ }
+}
diff --git a/src/main/java/me/jellysquid/mods/lithium/common/util/collections/Object2BooleanCacheTable.java b/src/main/java/me/jellysquid/mods/lithium/common/util/collections/Object2BooleanCacheTable.java
new file mode 100644
index 0000000000000000000000000000000000000000..e210e0fa39b74805429832c3d232fadb33975414
--- /dev/null
+++ b/src/main/java/me/jellysquid/mods/lithium/common/util/collections/Object2BooleanCacheTable.java
@@ -0,0 +1,61 @@
+package me.jellysquid.mods.lithium.common.util.collections;
+
+import it.unimi.dsi.fastutil.HashCommon;
+import net.minecraft.util.MathHelper;
+
+import java.util.function.Predicate;
+
+/**
+ * A lossy hashtable implementation that stores a mapping between an object and a boolean.
+ * <p>
+ * Any hash collisions will result in an overwrite: this is safe because the correct value can always be recomputed,
+ * given that the given operator is deterministic.
+ * <p>
+ * This implementation is safe to use from multiple threads
+ */
+public final class Object2BooleanCacheTable<T> {
+ private final int capacity;
+ private final int mask;
+
+ private final Node<T>[] nodes;
+
+ private final Predicate<T> operator;
+
+ @SuppressWarnings("unchecked")
+ public Object2BooleanCacheTable(int capacity, Predicate<T> operator) {
+ this.capacity = MathHelper.smallestEncompassingPowerOfTwo(capacity);
+ this.mask = this.capacity - 1;
+
+ this.nodes = (Node<T>[]) new Node[this.capacity];
+
+ this.operator = operator;
+ }
+
+ private static <T> int hash(T key) {
+ return HashCommon.mix(key.hashCode());
+ }
+
+ public boolean get(T key) {
+ int idx = hash(key) & this.mask;
+
+ Node<T> node = this.nodes[idx];
+ if (node != null && key.equals(node.key)) {
+ return node.value;
+ }
+
+ boolean test = this.operator.test(key);
+ this.nodes[idx] = new Node<>(key, test);
+
+ return test;
+ }
+
+ static class Node<T> {
+ final T key;
+ final boolean value;
+
+ Node(T key, boolean value) {
+ this.key = key;
+ this.value = value;
+ }
+ }
+}
diff --git a/src/main/java/net/minecraft/util/MathHelper.java b/src/main/java/net/minecraft/util/MathHelper.java
index b95115aca72ba0cf6451096ddbd8b50a8f3bb5c6..0afb8c643cb3e5938e12183c6132797d6ed645bb 100644
--- a/src/main/java/net/minecraft/util/MathHelper.java
+++ b/src/main/java/net/minecraft/util/MathHelper.java
@@ -198,6 +198,7 @@ public class MathHelper {
return c(f, f + f3, f2);
}
+ public static int smallestEncompassingPowerOfTwo(int i){ return c(i); } // Yatopia - OBFHELPER
public static int c(int i) {
int j = i - 1;
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index 7befe4263a2d046922438e1a9853f2d8290ee230..ab5fb00885d22126639e7459ef71c56be4b5eb9e 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -2647,6 +2647,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, ne
return this.isSneaking();
}
+ public boolean isDescending() { return by(); } // Yatopia - OBFHELPER
public boolean by() {
return this.isSneaking();
}
diff --git a/src/main/java/net/minecraft/world/level/block/Block.java b/src/main/java/net/minecraft/world/level/block/Block.java
index 3319c419a9eaf91224396c8b19eb057abd8094e6..9dee9ff25ba12f4de6d9080176c371627215b029 100644
--- a/src/main/java/net/minecraft/world/level/block/Block.java
+++ b/src/main/java/net/minecraft/world/level/block/Block.java
@@ -56,6 +56,7 @@ import net.minecraft.world.phys.shapes.VoxelShapes;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import me.jellysquid.mods.lithium.common.ai.pathing.PathNodeDefaults;
+import me.jellysquid.mods.lithium.common.util.collections.Object2BooleanCacheTable;
public class Block extends BlockBase implements IMaterial {
@@ -229,8 +230,14 @@ public class Block extends BlockBase implements IMaterial {
return a(voxelshape1);
}
+ // Yatopia start - Port lithium
+ private static final Object2BooleanCacheTable<VoxelShape> FULL_CUBE_CACHE = new Object2BooleanCacheTable<>(
+ 512,
+ shape -> !VoxelShapes.applyOperation(VoxelShapes.fullCube(), shape, OperatorBoolean.NOT_SAME)
+ );
+
public static boolean a(VoxelShape voxelshape) {
- return (Boolean) Block.a.getUnchecked(voxelshape);
+ return FULL_CUBE_CACHE.get(voxelshape); // Yatopia end
}
public boolean b(IBlockData iblockdata, IBlockAccess iblockaccess, BlockPosition blockposition) {
diff --git a/src/main/java/net/minecraft/world/phys/shapes/VoxelShape.java b/src/main/java/net/minecraft/world/phys/shapes/VoxelShape.java
index fbc5fab9946b6f9233f3014f0e69f2576b2138d7..012892063405616c8ae35b6e06020008dfd147df 100644
--- a/src/main/java/net/minecraft/world/phys/shapes/VoxelShape.java
+++ b/src/main/java/net/minecraft/world/phys/shapes/VoxelShape.java
@@ -71,6 +71,7 @@ public abstract class VoxelShape {
return i >= this.a.c(enumdirection_enumaxis) ? Double.POSITIVE_INFINITY : this.a(enumdirection_enumaxis, i);
}
+ public double getMax(EnumDirection.EnumAxis enumdirection_enumaxis) { return c(enumdirection_enumaxis); } // Yatopia - OBFHELPER
public double c(EnumDirection.EnumAxis enumdirection_enumaxis) {
int i = this.a.b(enumdirection_enumaxis);
diff --git a/src/main/java/net/minecraft/world/phys/shapes/VoxelShapeMerger.java b/src/main/java/net/minecraft/world/phys/shapes/VoxelShapeMerger.java
index d2a46ce0c5c980d34dc2f4b716a174a81a68f1d0..0c594866cb291abb2e90b149d52445a628331879 100644
--- a/src/main/java/net/minecraft/world/phys/shapes/VoxelShapeMerger.java
+++ b/src/main/java/net/minecraft/world/phys/shapes/VoxelShapeMerger.java
@@ -2,7 +2,7 @@ package net.minecraft.world.phys.shapes;
import it.unimi.dsi.fastutil.doubles.DoubleList;
-interface VoxelShapeMerger {
+public interface VoxelShapeMerger { // Yatopia - make Public
DoubleList a();
diff --git a/src/main/java/net/minecraft/world/phys/shapes/VoxelShapes.java b/src/main/java/net/minecraft/world/phys/shapes/VoxelShapes.java
index 049aa5f51e7517744b25f8c2c4b5e7a7de24a73e..173197e9dc6acb31aa41ce645224fd9a2733f27c 100644
--- a/src/main/java/net/minecraft/world/phys/shapes/VoxelShapes.java
+++ b/src/main/java/net/minecraft/world/phys/shapes/VoxelShapes.java
@@ -5,6 +5,8 @@ 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 me.jellysquid.mods.lithium.common.shapes.pairs.LithiumDoublePairList; // Yatopia
+
import java.util.Arrays;
import java.util.Iterator;
import java.util.Objects;
@@ -476,7 +478,7 @@ public final class VoxelShapes {
// doublelist is usually a DoubleArrayList with Infinite head/tails that falls to the final else clause
// This is actually the most common path, so jump to it straight away
if (doublelist.getDouble(0) == Double.NEGATIVE_INFINITY && doublelist.getDouble(doublelist.size() - 1) == Double.POSITIVE_INFINITY) {
- return new VoxelShapeMergerList(doublelist, doublelist1, flag, flag1);
+ return new LithiumDoublePairList(doublelist, doublelist1, flag, flag1); // Yatopia - Port lithium
}
// Split out rest to hopefully inline the above
return lessCommonMerge(i, doublelist, doublelist1, flag, flag1);

File diff suppressed because it is too large Load Diff