mirror of
https://github.com/PaperMC/Paper.git
synced 2024-06-26 14:54:50 +02:00
Upstream has released updates that appear to apply and compile correctly. This update has not been tested by PaperMC and as with ANY update, please do your own testing Bukkit Changes: 6680169e [#660/Enum] Merge remote-tracking branch 'origin/pr/660' into experimental 8b97f215 Add missing AbstractTestingBase extension 9f21f42b [#660/Enum] Merge remote-tracking branch 'origin/pr/660' into experimental fb59a4a0 Create experimental version a7c1393b Merge branch 'master' into enums-to-registers 1af01165 Merge branch 'master' into enums-to-registers 4ee82e4e Implement feedback af8ffd60 Merge branch 'master' into enums-to-registers 6a8ea63f Updated to 1.20 22ae9ebc Merge branch 'master' into enums-to-registers b1d669be Some clean up 685d812e Merge branch 'master' into enums-to-registers 00d778c7 Convert MusicInstrument bba2eb5f Convert GameEvent ffbf67a1 Convert PotionType eacaa45d Convert Particle d08d21d1 Convert PatternType c6b51f7c Convert Cat type af6c2987 Make missing Frog variant abstract a67a5f5c Add missing Annotation 6ab21c50 Change how converting from / to BlockType and ItemType work e3e84e69 Add Objects.requireNonNull so that there are not marked as nullable fceddab5 Add missing deprecation e91906f5 Don't convert legacy in register instead, only in required method 2200b334 Use static constructors for ItemStack b5f483b0 Deprecated Material a995df2a Fix typo getItemTyp 9cedb664 import ItemType 27e282b2 getSteerItemType -> getSteerItem d8d0e43b Better Piglin method names 3a2ab399 BLOCK_TYPE -> BLOCK, ITEM_TYPE -> ITEM a0eb63ac Interface it is 4bb0b646 Split Material into BlockType and ItemType b6bfcff5 Merge branch 'master' into enums-to-registers 1f86c847 Updated to Mockito 5.3.1 280ee1f7 Fix merge, updated to 1.19.4 9e0c7ad5 Merge branch 'master' into enums-to-registers fdbed698 Updated to 1.19.3 85c3e2d3 Merge branch 'master' into enums-to-registers b2c390af Fix merge 4e405647 Merge branch 'master' into enums-to-registers d01b4c90 Fix copy/paste ba2c8cb1 Update to 1.19 7e4f2db2 Merge branch 'master' of https://hub.spigotmc.org/stash/scm/~derfrzocker/bukkit into enums-to-registers a1a974f0 Fix merge 7d3a91d3 Merge branch 'master' of https://hub.spigotmc.org/stash/scm/~derfrzocker/bukkit into enums-to-registers 499e22d9 Merge branch 'master' of https://hub.spigotmc.org/stash/scm/~derfrzocker/bukkit into enums-to-registers a0cf419f Merge branch 'master' of https://hub.spigotmc.org/stash/scm/~derfrzocker/bukkit into enums-to-registers d5bd36a2 Fix / Implement merge changes fe643952 Merge branch 'master' of https://hub.spigotmc.org/stash/scm/~derfrzocker/bukkit into enums-to-registers cf1d2005 Merge branch 'master' of https://hub.spigotmc.org/stash/scm/~derfrzocker/bukkit into enums-to-registers f18dce93 Make Statistic abstract bbe3f791 Fix 1.18 merge Handle comment out test cases 0988647e Merge branch 'master' of https://hub.spigotmc.org/stash/scm/~derfrzocker/bukkit into enums-to-registers 6e4f2c50 Populated BlockType and ItemType 7a58144d Convert Material enum, midpoint push, it compiles and runs 4771132c Merge branch 'master' of https://hub.spigotmc.org/stash/scm/~derfrzocker/bukkit into enums-to-registers e6b179ff Convert Material enum, midpoint push to merge BlockState changes f33b85a0 Change other enums / classes. 8b0d5418 Create seperat OldEnum class, which holds common enum methods. 45544426 Change Enums to classes to easier handle none standart minecraft values CraftBukkit Changes: 8969b32d0 [#931/Enum] Merge remote-tracking branch 'origin/pr/931' into experimental 222257a67 Add missing AbstractTestingBase extension 0480af399 [#931/Enum] Merge remote-tracking branch 'origin/pr/931' into experimental 1afa1ddc2 Create experimental version 00780ea51 Ignore FactoryItemMaterialTest test 676969d01 SPIGOT-7389: Handle setting null items in ChiseledBookshelf Inventory 84f10cc36 Fix merge 9e114e13e Merge branch 'master' into enums-to-registers 941787e24 Add missing Commodore for 1.20 updated 6dac9a12d Updated tests 737426398 Only allow reference holder aaaa5fa88 Merge branch 'master' into enums-to-registers 74957eb99 Merge branch 'master' into enums-to-registers a1ca4e870 Merge branch 'master' into enums-to-registers f293f4a61 Updated to 1.20 b434b3d15 Merge branch 'master' into enums-to-registers e99dcbda7 Some clean up fcead8aed Use correct primitive class e955d9c50 Fix some Commodore errors af5526ebb Allow Material to support older plugins b83afd643 Add rewrite for Google enum set methods 067323765 Add missing method replacement in dynamic invocation 63e17e631 Merge branch 'master' into enums-to-registers 26dfcacf8 Bad copy and past d50c9bd6a Convert MusicInstrument c0c5312db Convert GameEvent 39daffe2c Convert PotionType 9b974f832 Convert Particle f528fca63 Convert PatternType 525c65006 Convert Cat type 6832b8fbb More consistent to / from bukkit / minecraft methods d31e38e16 Make missing Frog variant abstract e4f0e7d8e This shouldn't be committed 6fee81baa Add Commodore for EnumSet 82a668683 Fix hasItemType / getItemType f70162d66 Change how converting from / to BlockType and ItemType work c3f7c7886 Don't convert legacy in register instead, only in required method 2039e05fa Use static constructors for ItemStack fe221578b More Commodore 2b70bd171 More Commodore 70f4a89f5 Fix some Commodore 06544ed4b Fix typo getItemTyp 6269d2e42 getSteerItemType -> getSteerItem a19ac46c0 Better Piglin method names eef5f52c6 BLOCK_TYPE -> BLOCK, ITEM_TYPE -> ITEM bbaff1348 Interface it is c39e1316c Finish Commodore action for Material split dd8552105 Work on Commodore 1d4ef8bf2 Split Material into BlockType and ItemType 6c5a98220 Merge branch 'master' into enums-to-registers 869658a96 Handle Material calls in lambda expression 523ac4ac0 Add reroute for Class#getEnumConstants 0a4463279 Use extra method for getting registry 602d9b404 Updated to Mockito 5.3.1 8ff87b77d Fix merge, updated to 1.19.4 9d739d313 Merge branch 'master' into enums-to-registers eb6f702ff Reduce usage of BuiltInRegistries b6f667cac Some more asm compatibility changes, add config option 87c931d38 Handle enum maps a2c6699db Updated to 1.19.3 f7c27584f Merge branch 'master' into enums-to-registers 2f95b9951 Fix merge 184b05740 Merge branch 'master' into enums-to-registers 12bd8de26 Updated to 1.19 9c57831b7 Merge branch 'master' of https://hub.spigotmc.org/stash/scm/~derfrzocker/craftbukkit into enums-to-registers 4ed8eb402 Fix merge a9faac8e4 Merge branch 'master' of https://hub.spigotmc.org/stash/scm/~derfrzocker/craftbukkit into enums-to-registers 0d2988603 Merge branch 'master' of https://hub.spigotmc.org/stash/scm/~derfrzocker/craftbukkit into enums-to-registers 3f8f9557d Fix merge, updated to 1.18.2 1560490c6 Merge branch 'master' of https://hub.spigotmc.org/stash/scm/~derfrzocker/craftbukkit into enums-to-registers a0e4eb12c Merge branch 'master' of https://hub.spigotmc.org/stash/scm/~derfrzocker/craftbukkit into enums-to-registers 8b59f682d Move getType method to CraftEntity class b849c0147 Add missing patches 4644ba79f Fix / Implement merge changes cf9ee732e Merge branch 'master' of https://hub.spigotmc.org/stash/scm/~derfrzocker/craftbukkit into enums-to-registers 0c9125b67 Use Tag where possible cc05153d9 Cache interactable call ab5cc36de Use getHandle 83ebf4114 Merge branch 'master' of https://hub.spigotmc.org/stash/scm/~derfrzocker/craftbukkit into enums-to-registers bc20aea0c Make Statistic abstract 3faa7e135 Add Tests for Material BlockType and ItemType e10f74365 Fix 1.18 merge Handle comment out test cases f72f70ec4 Merge branch 'master' of https://hub.spigotmc.org/stash/scm/~derfrzocker/craftbukkit into enums-to-registers dbf4f5b7e Populated BlockType and ItemType 015afc1bc Convert Material enum, midpoint push, it compiles and runs cc0112866 Merge branch 'master' of https://hub.spigotmc.org/stash/scm/~derfrzocker/craftbukkit into enums-to-registers e26742c59 Convert Material enum, midpoint push to merge BlockState changes 796ad9295 Fix bug in legacy naming converting. 199c8278c Change other enums / classes. fd513652a Seperated custom biome value handling. Fix compareTo call. 60c71ce07 Change Enums to classes to easier handle none standart minecraft values Spigot Changes: addcf45f [Enum] Rebuild patches
455 lines
21 KiB
Diff
455 lines
21 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
|
|
Date: Sun, 20 Jun 2021 16:19:26 -0700
|
|
Subject: [PATCH] Optimise random block ticking
|
|
|
|
Massive performance improvement for random block ticking.
|
|
The performance increase comes from the fact that the vast
|
|
majority of attempted block ticks (~95% in my testing) fail
|
|
because the randomly selected block is not tickable.
|
|
|
|
Now only tickable blocks are targeted, however this means that
|
|
the maximum number of block ticks occurs per chunk. However,
|
|
not all chunks are going to be targeted. The percent chance
|
|
of a chunk being targeted is based on how many tickable blocks
|
|
are in the chunk.
|
|
This means that while block ticks are spread out less, the
|
|
total number of blocks ticked per world tick remains the same.
|
|
Therefore, the chance of a random tickable block being ticked
|
|
remains the same.
|
|
|
|
diff --git a/src/main/java/io/papermc/paper/util/math/ThreadUnsafeRandom.java b/src/main/java/io/papermc/paper/util/math/ThreadUnsafeRandom.java
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..7d93652c1abbb6aee6eb7c26cf35d4d032ef7b69
|
|
--- /dev/null
|
|
+++ b/src/main/java/io/papermc/paper/util/math/ThreadUnsafeRandom.java
|
|
@@ -0,0 +1,65 @@
|
|
+package io.papermc.paper.util.math;
|
|
+
|
|
+import net.minecraft.util.RandomSource;
|
|
+import net.minecraft.world.level.levelgen.LegacyRandomSource;
|
|
+import net.minecraft.world.level.levelgen.PositionalRandomFactory;
|
|
+import org.checkerframework.checker.nullness.qual.NonNull;
|
|
+import org.checkerframework.framework.qual.DefaultQualifier;
|
|
+
|
|
+@DefaultQualifier(NonNull.class)
|
|
+public final class ThreadUnsafeRandom extends LegacyRandomSource {
|
|
+
|
|
+ // See javadoc and internal comments for java.util.Random where these values come from, how they are used, and the author for them.
|
|
+ private static final long multiplier = 0x5DEECE66DL;
|
|
+ private static final long addend = 0xBL;
|
|
+ private static final long mask = (1L << 48) - 1;
|
|
+
|
|
+ private static long initialScramble(long seed) {
|
|
+ return (seed ^ multiplier) & mask;
|
|
+ }
|
|
+
|
|
+ private long seed;
|
|
+
|
|
+ public ThreadUnsafeRandom(long seed) {
|
|
+ super(seed);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public RandomSource fork() {
|
|
+ return new ThreadUnsafeRandom(this.nextLong());
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public PositionalRandomFactory forkPositional() {
|
|
+ throw new UnsupportedOperationException();
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void setSeed(long seed) {
|
|
+ // note: called by Random constructor
|
|
+ this.seed = initialScramble(seed);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public int next(int bits) {
|
|
+ // avoid the expensive CAS logic used by superclass
|
|
+ return (int) (((this.seed = this.seed * multiplier + addend) & mask) >>> (48 - bits));
|
|
+ }
|
|
+
|
|
+ // Taken from
|
|
+ // https://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction/
|
|
+ // https://github.com/lemire/Code-used-on-Daniel-Lemire-s-blog/blob/master/2016/06/25/fastrange.c
|
|
+ // Original license is public domain
|
|
+ public static int fastRandomBounded(final long randomInteger, final long limit) {
|
|
+ // randomInteger must be [0, pow(2, 32))
|
|
+ // limit must be [0, pow(2, 32))
|
|
+ return (int)((randomInteger * limit) >>> 32);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public int nextInt(int bound) {
|
|
+ // yes this breaks random's spec
|
|
+ // however there's nothing that uses this class that relies on it
|
|
+ return fastRandomBounded(this.next(32) & 0xFFFFFFFFL, bound);
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
|
index 4db57d685e926aea21644473c2a9790bfca47e3f..be8d7aa376474c6806fe95a64c9ef9c17199ba73 100644
|
|
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
|
|
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
|
@@ -845,6 +845,10 @@ public class ServerLevel extends Level implements WorldGenLevel {
|
|
entityplayer.stopSleepInBed(false, false);
|
|
});
|
|
}
|
|
+ // Paper start - optimise random block ticking
|
|
+ private final BlockPos.MutableBlockPos chunkTickMutablePosition = new BlockPos.MutableBlockPos();
|
|
+ private final io.papermc.paper.util.math.ThreadUnsafeRandom randomTickRandom = new io.papermc.paper.util.math.ThreadUnsafeRandom(this.random.nextLong());
|
|
+ // Paper end
|
|
|
|
public void tickChunk(LevelChunk chunk, int randomTickSpeed) {
|
|
ChunkPos chunkcoordintpair = chunk.getPos();
|
|
@@ -854,10 +858,10 @@ public class ServerLevel extends Level implements WorldGenLevel {
|
|
ProfilerFiller gameprofilerfiller = this.getProfiler();
|
|
|
|
gameprofilerfiller.push("thunder");
|
|
- BlockPos blockposition;
|
|
+ final BlockPos.MutableBlockPos blockposition = this.chunkTickMutablePosition; // Paper - use mutable to reduce allocation rate, final to force compile fail on change
|
|
|
|
if (!this.paperConfig().environment.disableThunder && flag && this.isThundering() && this.spigotConfig.thunderChance > 0 && this.random.nextInt(this.spigotConfig.thunderChance) == 0) { // Spigot // Paper - disable thunder
|
|
- blockposition = this.findLightningTargetAround(this.getBlockRandomPos(j, 0, k, 15));
|
|
+ blockposition.set(this.findLightningTargetAround(this.getBlockRandomPos(j, 0, k, 15))); // Paper
|
|
if (this.isRainingAt(blockposition)) {
|
|
DifficultyInstance difficultydamagescaler = this.getCurrentDifficultyAt(blockposition);
|
|
boolean flag1 = this.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING) && this.random.nextDouble() < (double) difficultydamagescaler.getEffectiveDifficulty() * this.paperConfig().entities.spawning.skeletonHorseThunderSpawnChance.or(0.01D) && !this.getBlockState(blockposition.below()).is(Blocks.LIGHTNING_ROD); // Paper
|
|
@@ -888,16 +892,25 @@ public class ServerLevel extends Level implements WorldGenLevel {
|
|
int i1;
|
|
|
|
if (!this.paperConfig().environment.disableIceAndSnow && this.random.nextInt(16) == 0) { // Paper - Disable ice and snow
|
|
- blockposition = this.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING, this.getBlockRandomPos(j, 0, k, 15));
|
|
- BlockPos blockposition1 = blockposition.below();
|
|
+ // Paper start - optimise chunk ticking
|
|
+ this.getRandomBlockPosition(j, 0, k, 15, blockposition);
|
|
+ int normalY = chunk.getHeight(Heightmap.Types.MOTION_BLOCKING, blockposition.getX() & 15, blockposition.getZ() & 15) + 1;
|
|
+ int downY = normalY - 1;
|
|
+ blockposition.setY(normalY);
|
|
+ // Paper end
|
|
Biome biomebase = (Biome) this.getBiome(blockposition).value();
|
|
|
|
- if (biomebase.shouldFreeze(this, blockposition1)) {
|
|
- org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(this, blockposition1, Blocks.ICE.defaultBlockState(), null); // CraftBukkit
|
|
+ // Paper start - optimise chunk ticking
|
|
+ blockposition.setY(downY);
|
|
+ if (biomebase.shouldFreeze(this, blockposition)) {
|
|
+ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(this, blockposition, Blocks.ICE.defaultBlockState(), null); // CraftBukkit
|
|
+ // Paper end
|
|
}
|
|
|
|
if (flag) {
|
|
l = this.getGameRules().getInt(GameRules.RULE_SNOW_ACCUMULATION_HEIGHT);
|
|
+
|
|
+ blockposition.setY(normalY); // Paper
|
|
if (l > 0 && biomebase.shouldSnow(this, blockposition)) {
|
|
BlockState iblockdata = this.getBlockState(blockposition);
|
|
|
|
@@ -913,51 +926,54 @@ public class ServerLevel extends Level implements WorldGenLevel {
|
|
org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(this, blockposition, Blocks.SNOW.defaultBlockState(), null); // CraftBukkit
|
|
}
|
|
}
|
|
+ blockposition.setY(downY); // Paper
|
|
|
|
- Biome.Precipitation biomebase_precipitation = biomebase.getPrecipitationAt(blockposition1);
|
|
+ Biome.Precipitation biomebase_precipitation = biomebase.getPrecipitationAt(blockposition); // Paper
|
|
|
|
if (biomebase_precipitation != Biome.Precipitation.NONE) {
|
|
- BlockState iblockdata2 = this.getBlockState(blockposition1);
|
|
+ BlockState iblockdata2 = this.getBlockState(blockposition); // Paper
|
|
|
|
- iblockdata2.getBlock().handlePrecipitation(iblockdata2, this, blockposition1, biomebase_precipitation);
|
|
+ iblockdata2.getBlock().handlePrecipitation(iblockdata2, this, blockposition, biomebase_precipitation); // Paper
|
|
}
|
|
}
|
|
}
|
|
|
|
- gameprofilerfiller.popPush("tickBlocks");
|
|
+ // Paper start - optimise random block ticking
|
|
+ gameprofilerfiller.popPush("randomTick");
|
|
timings.chunkTicksBlocks.startTiming(); // Paper
|
|
if (randomTickSpeed > 0) {
|
|
- LevelChunkSection[] achunksection = chunk.getSections();
|
|
-
|
|
- for (int j1 = 0; j1 < achunksection.length; ++j1) {
|
|
- LevelChunkSection chunksection = achunksection[j1];
|
|
-
|
|
- if (chunksection.isRandomlyTicking()) {
|
|
- l = chunk.getSectionYFromSectionIndex(j1);
|
|
- int k1 = SectionPos.sectionToBlockCoord(l);
|
|
-
|
|
- for (i1 = 0; i1 < randomTickSpeed; ++i1) {
|
|
- BlockPos blockposition2 = this.getBlockRandomPos(j, k1, k, 15);
|
|
-
|
|
- gameprofilerfiller.push("randomTick");
|
|
- BlockState iblockdata3 = chunksection.getBlockState(blockposition2.getX() - j, blockposition2.getY() - k1, blockposition2.getZ() - k);
|
|
+ LevelChunkSection[] sections = chunk.getSections();
|
|
+ int minSection = io.papermc.paper.util.WorldUtil.getMinSection(this);
|
|
+ for (int sectionIndex = 0; sectionIndex < sections.length; ++sectionIndex) {
|
|
+ LevelChunkSection section = sections[sectionIndex];
|
|
+ if (section == null || section.tickingList.size() == 0) {
|
|
+ continue;
|
|
+ }
|
|
|
|
- if (iblockdata3.isRandomlyTicking()) {
|
|
- iblockdata3.randomTick(this, blockposition2, this.random);
|
|
- }
|
|
+ int yPos = (sectionIndex + minSection) << 4;
|
|
+ for (int a = 0; a < randomTickSpeed; ++a) {
|
|
+ int tickingBlocks = section.tickingList.size();
|
|
+ int index = this.randomTickRandom.nextInt(16 * 16 * 16);
|
|
+ if (index >= tickingBlocks) {
|
|
+ continue;
|
|
+ }
|
|
|
|
- FluidState fluid = iblockdata3.getFluidState();
|
|
+ long raw = section.tickingList.getRaw(index);
|
|
+ int location = com.destroystokyo.paper.util.maplist.IBlockDataList.getLocationFromRaw(raw);
|
|
+ int randomX = location & 15;
|
|
+ int randomY = ((location >>> (4 + 4)) & 255) | yPos;
|
|
+ int randomZ = (location >>> 4) & 15;
|
|
|
|
- if (fluid.isRandomlyTicking()) {
|
|
- fluid.randomTick(this, blockposition2, this.random);
|
|
- }
|
|
+ BlockPos blockposition2 = blockposition.set(j + randomX, randomY, k + randomZ);
|
|
+ BlockState iblockdata = com.destroystokyo.paper.util.maplist.IBlockDataList.getBlockDataFromRaw(raw);
|
|
|
|
- gameprofilerfiller.pop();
|
|
- }
|
|
+ iblockdata.randomTick(this, blockposition2, this.randomTickRandom);
|
|
+ // We drop the fluid tick since LAVA is ALREADY TICKED by the above method (See LiquidBlock).
|
|
+ // TODO CHECK ON UPDATE (ping the Canadian)
|
|
}
|
|
}
|
|
}
|
|
-
|
|
+ // Paper end - optimise random block ticking
|
|
timings.chunkTicksBlocks.stopTiming(); // Paper
|
|
gameprofilerfiller.pop();
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/util/BitStorage.java b/src/main/java/net/minecraft/util/BitStorage.java
|
|
index 68648c5a5e3ff079f832092af0f2f801c42d1ede..8bafd5fd7499ba4a04bf706cfd1e156073716e21 100644
|
|
--- a/src/main/java/net/minecraft/util/BitStorage.java
|
|
+++ b/src/main/java/net/minecraft/util/BitStorage.java
|
|
@@ -20,4 +20,15 @@ public interface BitStorage {
|
|
void unpack(int[] out);
|
|
|
|
BitStorage copy();
|
|
+
|
|
+ // Paper start
|
|
+ void forEach(DataBitConsumer consumer);
|
|
+
|
|
+ @FunctionalInterface
|
|
+ interface DataBitConsumer {
|
|
+
|
|
+ void accept(int location, int data);
|
|
+
|
|
+ }
|
|
+ // Paper end
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/util/SimpleBitStorage.java b/src/main/java/net/minecraft/util/SimpleBitStorage.java
|
|
index 2b3fd62dca2d1475075b5dcde56cea85b749cb44..e4d0d7e8fc58b8f9f614d74a141e452166e0364c 100644
|
|
--- a/src/main/java/net/minecraft/util/SimpleBitStorage.java
|
|
+++ b/src/main/java/net/minecraft/util/SimpleBitStorage.java
|
|
@@ -124,6 +124,28 @@ public class SimpleBitStorage implements BitStorage {
|
|
return this.bits;
|
|
}
|
|
|
|
+ // Paper start
|
|
+ @Override
|
|
+ public final void forEach(DataBitConsumer consumer) {
|
|
+ int i = 0;
|
|
+ long[] along = this.data;
|
|
+ int j = along.length;
|
|
+
|
|
+ for (int k = 0; k < j; ++k) {
|
|
+ long l = along[k];
|
|
+
|
|
+ for (int i1 = 0; i1 < this.valuesPerLong; ++i1) {
|
|
+ consumer.accept(i, (int) (l & this.mask));
|
|
+ l >>= this.bits;
|
|
+ ++i;
|
|
+ if (i >= this.size) {
|
|
+ return;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ // Paper end
|
|
+
|
|
@Override
|
|
public void getAll(IntConsumer action) {
|
|
int i = 0;
|
|
diff --git a/src/main/java/net/minecraft/util/ZeroBitStorage.java b/src/main/java/net/minecraft/util/ZeroBitStorage.java
|
|
index f0f764f36fb92c64ab2dc8a0a50c3f48321c3c9a..311625277a26c9c187025a1036978229241b965f 100644
|
|
--- a/src/main/java/net/minecraft/util/ZeroBitStorage.java
|
|
+++ b/src/main/java/net/minecraft/util/ZeroBitStorage.java
|
|
@@ -46,6 +46,15 @@ public class ZeroBitStorage implements BitStorage {
|
|
return 0;
|
|
}
|
|
|
|
+ // Paper start
|
|
+ @Override
|
|
+ public void forEach(DataBitConsumer consumer) {
|
|
+ for(int i = 0; i < this.size; ++i) {
|
|
+ consumer.accept(i, 0);
|
|
+ }
|
|
+ }
|
|
+ // Paper end
|
|
+
|
|
@Override
|
|
public void getAll(IntConsumer action) {
|
|
for(int i = 0; i < this.size; ++i) {
|
|
diff --git a/src/main/java/net/minecraft/world/entity/animal/Turtle.java b/src/main/java/net/minecraft/world/entity/animal/Turtle.java
|
|
index 99fc97051c61ac8d08afdc0ea4845e96705e243b..c48bf4ca76f70d878378fc43c8270de5c3332824 100644
|
|
--- a/src/main/java/net/minecraft/world/entity/animal/Turtle.java
|
|
+++ b/src/main/java/net/minecraft/world/entity/animal/Turtle.java
|
|
@@ -84,7 +84,7 @@ public class Turtle extends Animal {
|
|
}
|
|
|
|
public void setHomePos(BlockPos pos) {
|
|
- this.entityData.set(Turtle.HOME_POS, pos);
|
|
+ this.entityData.set(Turtle.HOME_POS, pos.immutable()); // Paper - called with mutablepos...
|
|
}
|
|
|
|
public BlockPos getHomePos() {
|
|
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
|
|
index f04f216f052095710d7ef13743489991380d6a62..69886eb8bf9769aa8f2942ad68aeadbb4e86c223 100644
|
|
--- a/src/main/java/net/minecraft/world/level/Level.java
|
|
+++ b/src/main/java/net/minecraft/world/level/Level.java
|
|
@@ -1296,10 +1296,18 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
|
public abstract RecipeManager getRecipeManager();
|
|
|
|
public BlockPos getBlockRandomPos(int x, int y, int z, int l) {
|
|
+ // Paper start - allow use of mutable pos
|
|
+ BlockPos.MutableBlockPos ret = new BlockPos.MutableBlockPos();
|
|
+ this.getRandomBlockPosition(x, y, z, l, ret);
|
|
+ return ret.immutable();
|
|
+ }
|
|
+ public final BlockPos.MutableBlockPos getRandomBlockPosition(int x, int y, int z, int l, BlockPos.MutableBlockPos out) {
|
|
+ // Paper end
|
|
this.randValue = this.randValue * 3 + 1013904223;
|
|
int i1 = this.randValue >> 2;
|
|
|
|
- return new BlockPos(x + (i1 & 15), y + (i1 >> 16 & l), z + (i1 >> 8 & 15));
|
|
+ out.set(x + (i1 & 15), y + (i1 >> 16 & l), z + (i1 >> 8 & 15)); // Paper - change to setValues call
|
|
+ return out; // Paper
|
|
}
|
|
|
|
public boolean noSave() {
|
|
diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java
|
|
index b8fee4f8a0cfe32b9ef7f3f3cf818cbaec0d3fca..12edaf88cca54540c617239ac31b2263dfa0ecd7 100644
|
|
--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java
|
|
+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java
|
|
@@ -25,6 +25,7 @@ public class LevelChunkSection {
|
|
public final PalettedContainer<BlockState> states;
|
|
// CraftBukkit start - read/write
|
|
private PalettedContainer<Holder<Biome>> biomes;
|
|
+ public final com.destroystokyo.paper.util.maplist.IBlockDataList tickingList = new com.destroystokyo.paper.util.maplist.IBlockDataList(); // Paper
|
|
|
|
public LevelChunkSection(PalettedContainer<BlockState> datapaletteblock, PalettedContainer<Holder<Biome>> palettedcontainerro) {
|
|
// CraftBukkit end
|
|
@@ -77,6 +78,9 @@ public class LevelChunkSection {
|
|
--this.nonEmptyBlockCount;
|
|
if (iblockdata1.isRandomlyTicking()) {
|
|
--this.tickingBlockCount;
|
|
+ // Paper start
|
|
+ this.tickingList.remove(x, y, z);
|
|
+ // Paper end
|
|
}
|
|
}
|
|
|
|
@@ -88,6 +92,9 @@ public class LevelChunkSection {
|
|
++this.nonEmptyBlockCount;
|
|
if (state.isRandomlyTicking()) {
|
|
++this.tickingBlockCount;
|
|
+ // Paper start
|
|
+ this.tickingList.add(x, y, z, state);
|
|
+ // Paper end
|
|
}
|
|
}
|
|
|
|
@@ -115,40 +122,31 @@ public class LevelChunkSection {
|
|
}
|
|
|
|
public void recalcBlockCounts() {
|
|
- class a implements PalettedContainer.CountConsumer<BlockState> {
|
|
-
|
|
- public int nonEmptyBlockCount;
|
|
- public int tickingBlockCount;
|
|
- public int tickingFluidCount;
|
|
-
|
|
- a() {}
|
|
-
|
|
- public void accept(BlockState iblockdata, int i) {
|
|
- FluidState fluid = iblockdata.getFluidState();
|
|
-
|
|
- if (!iblockdata.isAir()) {
|
|
- this.nonEmptyBlockCount += i;
|
|
- if (iblockdata.isRandomlyTicking()) {
|
|
- this.tickingBlockCount += i;
|
|
- }
|
|
+ // Paper start - unfuck this
|
|
+ this.tickingList.clear();
|
|
+ this.nonEmptyBlockCount = 0;
|
|
+ this.tickingBlockCount = 0;
|
|
+ this.tickingFluidCount = 0;
|
|
+ this.states.forEachLocation((BlockState iblockdata, int i) -> {
|
|
+ FluidState fluid = iblockdata.getFluidState();
|
|
+
|
|
+ if (!iblockdata.isAir()) {
|
|
+ this.nonEmptyBlockCount = (short) (this.nonEmptyBlockCount + 1);
|
|
+ if (iblockdata.isRandomlyTicking()) {
|
|
+ this.tickingBlockCount = (short)(this.tickingBlockCount + 1);
|
|
+ this.tickingList.add(i, iblockdata);
|
|
}
|
|
+ }
|
|
|
|
- if (!fluid.isEmpty()) {
|
|
- this.nonEmptyBlockCount += i;
|
|
- if (fluid.isRandomlyTicking()) {
|
|
- this.tickingFluidCount += i;
|
|
- }
|
|
+ if (!fluid.isEmpty()) {
|
|
+ this.nonEmptyBlockCount = (short) (this.nonEmptyBlockCount + 1);
|
|
+ if (fluid.isRandomlyTicking()) {
|
|
+ this.tickingFluidCount = (short) (this.tickingFluidCount + 1);
|
|
}
|
|
-
|
|
}
|
|
- }
|
|
|
|
- a a0 = new a();
|
|
-
|
|
- this.states.count(a0);
|
|
- this.nonEmptyBlockCount = (short) a0.nonEmptyBlockCount;
|
|
- this.tickingBlockCount = (short) a0.tickingBlockCount;
|
|
- this.tickingFluidCount = (short) a0.tickingFluidCount;
|
|
+ });
|
|
+ // Paper end
|
|
}
|
|
|
|
public PalettedContainer<BlockState> getStates() {
|
|
diff --git a/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java b/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java
|
|
index de91ed0d5f7f472cb2f24a8f6e4ebbdeaa4faf52..7f5547dc31aa53b2863f4c09f598fa88e7fe2afd 100644
|
|
--- a/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java
|
|
+++ b/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java
|
|
@@ -385,6 +385,14 @@ public class PalettedContainer<T> implements PaletteResize<T>, PalettedContainer
|
|
}
|
|
}
|
|
|
|
+ // Paper start
|
|
+ public void forEachLocation(PalettedContainer.CountConsumer<T> consumer) {
|
|
+ this.data.storage.forEach((int location, int data) -> {
|
|
+ consumer.accept(this.data.palette.valueFor(data), location);
|
|
+ });
|
|
+ }
|
|
+ // Paper end
|
|
+
|
|
@FunctionalInterface
|
|
public interface CountConsumer<T> {
|
|
void accept(T object, int count);
|