mirror of
https://github.com/PaperMC/Paper.git
synced 2024-11-27 04:55:47 +01:00
ab347c4c96
Upstream has released updates that appears 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: 42d5a714 SPIGOT-5899: Hoglins API similar to Piglins 2c1ee10e SPIGOT-5887: ClickType doesn't include off hand swaps 5ff7c7ce SPIGOT-5886: Missing BlockData CraftBukkit Changes:7560f5f5
SPIGOT-5905: Fix hex colours not being allowed in MOTDd47c47ee
SPIGOT-5889: Villager using composter should call EntityChangeBlockEvent2fe6b4a3
SPIGOT-5899: Hoglins API similar to Piglinse09dbeca
SPIGOT-5887: ClickType doesn't include off hand swaps23aac2a5
SPIGOT-5903: EntityDismountEvent cannot be triggered asynchronously92cbf656
SPIGOT-5884: Tab completions lost on reloadData / minecraft:reloadfb4e54ad
SPIGOT-5902: PlayerRespawnEvent places player at spawn before event is calledaa8f3d5a
SPIGOT-5901: Structures are generated in all worlds based on the setting for the main worlda0c35937
SPIGOT-5895: PlayerChangedWorldEvent#getFrom is incorrect89c0a5c3
SPIGOT-5886: Missing BlockData Spigot Changes: 0287a20d SPIGOT-5903: EntityDismountEvent cannot be triggered asynchronously
408 lines
20 KiB
Diff
408 lines
20 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
|
|
Date: Mon, 27 Jan 2020 21:28:00 -0800
|
|
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/com/destroystokyo/paper/util/math/ThreadUnsafeRandom.java b/src/main/java/com/destroystokyo/paper/util/math/ThreadUnsafeRandom.java
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..3edc8e52e06a62ce9f8cc734fd7458b37cfaad91
|
|
--- /dev/null
|
|
+++ b/src/main/java/com/destroystokyo/paper/util/math/ThreadUnsafeRandom.java
|
|
@@ -0,0 +1,46 @@
|
|
+package com.destroystokyo.paper.util.math;
|
|
+
|
|
+import java.util.Random;
|
|
+
|
|
+public final class ThreadUnsafeRandom extends Random {
|
|
+
|
|
+ // 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;
|
|
+
|
|
+ @Override
|
|
+ public void setSeed(long seed) {
|
|
+ // note: called by Random constructor
|
|
+ this.seed = initialScramble(seed);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ protected 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/BlockPosition.java b/src/main/java/net/minecraft/server/BlockPosition.java
|
|
index b50d86b39d2296e1dfb9aaaeb8f8f6f62a4e7430..2d3e73ef92c7b88d49f8eb27233cb823b425ea4a 100644
|
|
--- a/src/main/java/net/minecraft/server/BlockPosition.java
|
|
+++ b/src/main/java/net/minecraft/server/BlockPosition.java
|
|
@@ -402,6 +402,7 @@ public class BlockPosition extends BaseBlockPosition {
|
|
return this.d(MathHelper.floor(d0), MathHelper.floor(d1), MathHelper.floor(d2));
|
|
}
|
|
|
|
+ public final BlockPosition.MutableBlockPosition setValues(final BaseBlockPosition baseblockposition) { return this.g(baseblockposition); } // Paper - OBFHELPER
|
|
public BlockPosition.MutableBlockPosition g(BaseBlockPosition baseblockposition) {
|
|
return this.d(baseblockposition.getX(), baseblockposition.getY(), baseblockposition.getZ());
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
|
|
index b2713942d8cf5bedd91ac63df18a336743c72da5..a76b1d2fd81aaedb37190bcb8510020d5df2513e 100644
|
|
--- a/src/main/java/net/minecraft/server/Chunk.java
|
|
+++ b/src/main/java/net/minecraft/server/Chunk.java
|
|
@@ -593,8 +593,8 @@ public class Chunk implements IChunkAccess {
|
|
this.entities.remove(entity); // Paper
|
|
}
|
|
|
|
- @Override
|
|
- public int getHighestBlock(HeightMap.Type heightmap_type, int i, int j) {
|
|
+ public final int getHighestBlockY(HeightMap.Type heightmap_type, int i, int j) { return this.getHighestBlock(heightmap_type, i, j) + 1; } // Paper - sort of an obfhelper, but without -1
|
|
+ @Override public int getHighestBlock(HeightMap.Type heightmap_type, int i, int j) { // Paper
|
|
return ((HeightMap) this.heightMap.get(heightmap_type)).a(i & 15, j & 15) - 1;
|
|
}
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/ChunkSection.java b/src/main/java/net/minecraft/server/ChunkSection.java
|
|
index b168ad8021a5387e05023cd03ec1a69c8a86a233..cf444fa1cc96e881a1f9ed0c78d45935fe1c90ab 100644
|
|
--- a/src/main/java/net/minecraft/server/ChunkSection.java
|
|
+++ b/src/main/java/net/minecraft/server/ChunkSection.java
|
|
@@ -7,12 +7,14 @@ import javax.annotation.Nullable;
|
|
public class ChunkSection {
|
|
|
|
public static final DataPalette<IBlockData> GLOBAL_PALETTE = new DataPaletteGlobal<>(Block.REGISTRY_ID, Blocks.AIR.getBlockData());
|
|
- private final int yPos;
|
|
+ final int yPos; // Paper - private -> package-private
|
|
short nonEmptyBlockCount; // Paper - package-private
|
|
- private short tickingBlockCount;
|
|
+ short tickingBlockCount; // Paper - private -> package-private
|
|
private short e;
|
|
final DataPaletteBlock<IBlockData> blockIds;
|
|
|
|
+ final com.destroystokyo.paper.util.maplist.IBlockDataList tickingList = new com.destroystokyo.paper.util.maplist.IBlockDataList(); // Paper
|
|
+
|
|
// Paper start - Anti-Xray - Add parameters
|
|
@Deprecated public ChunkSection(int i) { this(i, null, null, true); } // Notice for updates: Please make sure this constructor isn't used anywhere
|
|
public ChunkSection(int i, IChunkAccess chunk, World world, boolean initializeBlocks) {
|
|
@@ -67,6 +69,9 @@ public class ChunkSection {
|
|
--this.nonEmptyBlockCount;
|
|
if (iblockdata1.isTicking()) {
|
|
--this.tickingBlockCount;
|
|
+ // Paper start
|
|
+ this.tickingList.remove(i, j, k);
|
|
+ // Paper end
|
|
}
|
|
}
|
|
|
|
@@ -78,6 +83,9 @@ public class ChunkSection {
|
|
++this.nonEmptyBlockCount;
|
|
if (iblockdata.isTicking()) {
|
|
++this.tickingBlockCount;
|
|
+ // Paper start
|
|
+ this.tickingList.add(i, j, k, iblockdata);
|
|
+ // Paper end
|
|
}
|
|
}
|
|
|
|
@@ -113,23 +121,29 @@ public class ChunkSection {
|
|
}
|
|
|
|
public void recalcBlockCounts() {
|
|
+ // Paper start
|
|
+ this.tickingList.clear();
|
|
+ // Paper end
|
|
this.nonEmptyBlockCount = 0;
|
|
this.tickingBlockCount = 0;
|
|
this.e = 0;
|
|
- this.blockIds.a((iblockdata, i) -> {
|
|
+ this.blockIds.forEachLocation((iblockdata, location) -> { // Paper
|
|
Fluid fluid = iblockdata.getFluid();
|
|
|
|
if (!iblockdata.isAir()) {
|
|
- this.nonEmptyBlockCount = (short) (this.nonEmptyBlockCount + i);
|
|
+ this.nonEmptyBlockCount = (short) (this.nonEmptyBlockCount + 1);
|
|
if (iblockdata.isTicking()) {
|
|
- this.tickingBlockCount = (short) (this.tickingBlockCount + i);
|
|
+ this.tickingBlockCount = (short) (this.tickingBlockCount + 1);
|
|
+ // Paper start
|
|
+ this.tickingList.add(location, iblockdata);
|
|
+ // Paper end
|
|
}
|
|
}
|
|
|
|
if (!fluid.isEmpty()) {
|
|
- this.nonEmptyBlockCount = (short) (this.nonEmptyBlockCount + i);
|
|
+ this.nonEmptyBlockCount = (short) (this.nonEmptyBlockCount + 1);
|
|
if (fluid.f()) {
|
|
- this.e = (short) (this.e + i);
|
|
+ this.e = (short) (this.e + 1);
|
|
}
|
|
}
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/DataBits.java b/src/main/java/net/minecraft/server/DataBits.java
|
|
index 48cca2b9a1dbb071615625842123c0c47e281b29..235c9ec37c00ce8838b3e7c02284e402f9d30e38 100644
|
|
--- a/src/main/java/net/minecraft/server/DataBits.java
|
|
+++ b/src/main/java/net/minecraft/server/DataBits.java
|
|
@@ -111,4 +111,32 @@ public class DataBits {
|
|
}
|
|
|
|
}
|
|
+
|
|
+ // Paper start
|
|
+ public final void forEach(DataBitConsumer consumer) {
|
|
+ int i = 0;
|
|
+ long[] along = this.b;
|
|
+ int j = along.length;
|
|
+
|
|
+ for (int k = 0; k < j; ++k) {
|
|
+ long l = along[k];
|
|
+
|
|
+ for (int i1 = 0; i1 < this.f; ++i1) {
|
|
+ consumer.accept(i, (int) (l & this.d));
|
|
+ l >>= this.c;
|
|
+ ++i;
|
|
+ if (i >= this.e) {
|
|
+ return;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ @FunctionalInterface
|
|
+ static interface DataBitConsumer {
|
|
+
|
|
+ void accept(int location, int data);
|
|
+
|
|
+ }
|
|
+ // Paper end
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/server/DataPaletteBlock.java b/src/main/java/net/minecraft/server/DataPaletteBlock.java
|
|
index 900b551f6f76862443b09c1e76ad596eda5655f4..1cb45f97b644347d16b66b46113b1e4455004fd3 100644
|
|
--- a/src/main/java/net/minecraft/server/DataPaletteBlock.java
|
|
+++ b/src/main/java/net/minecraft/server/DataPaletteBlock.java
|
|
@@ -277,6 +277,14 @@ public class DataPaletteBlock<T> implements DataPaletteExpandable<T> {
|
|
});
|
|
}
|
|
|
|
+ // Paper start
|
|
+ public void forEachLocation(DataPaletteBlock.a<T> datapaletteblock_a) {
|
|
+ this.getDataBits().forEach((int location, int data) -> {
|
|
+ datapaletteblock_a.accept(this.getDataPalette().getObject(data), location);
|
|
+ });
|
|
+ }
|
|
+ // Paper end
|
|
+
|
|
@FunctionalInterface
|
|
public interface a<T> {
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/EntityTurtle.java b/src/main/java/net/minecraft/server/EntityTurtle.java
|
|
index 00827c335e9413e986d7f07d0adbcef0d106a553..c66a8011dde4932e03ea91194ea92a7263e48428 100644
|
|
--- a/src/main/java/net/minecraft/server/EntityTurtle.java
|
|
+++ b/src/main/java/net/minecraft/server/EntityTurtle.java
|
|
@@ -29,7 +29,7 @@ public class EntityTurtle extends EntityAnimal {
|
|
|
|
public final void setHome(BlockPosition pos) { setHomePos(pos); } // Paper - OBFHELPER
|
|
public void setHomePos(BlockPosition blockposition) {
|
|
- this.datawatcher.set(EntityTurtle.bw, blockposition);
|
|
+ this.datawatcher.set(EntityTurtle.bw, blockposition.immutableCopy()); // Paper - called with mutablepos...
|
|
}
|
|
// TODO Paper: Obf helpers here can prolly be removed? check that no newer patches use them
|
|
public final BlockPosition getHome() { return this.getHomePos(); } // Paper - OBFHELPER
|
|
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
|
|
index 73e0bf2d0851d2e10cd5b45a4bb90eba104bdc3d..93df6a29035bb3cc96409b145a2e1433d38bbe99 100644
|
|
--- a/src/main/java/net/minecraft/server/World.java
|
|
+++ b/src/main/java/net/minecraft/server/World.java
|
|
@@ -1466,10 +1466,18 @@ public abstract class World implements GeneratorAccess, AutoCloseable {
|
|
public abstract TagRegistry p();
|
|
|
|
public BlockPosition a(int i, int j, int k, int l) {
|
|
+ // Paper start - allow use of mutable pos
|
|
+ BlockPosition.MutableBlockPosition ret = new BlockPosition.MutableBlockPosition();
|
|
+ this.getRandomBlockPosition(i, j, k, l, ret);
|
|
+ return ret.immutableCopy();
|
|
+ }
|
|
+ public final BlockPosition.MutableBlockPosition getRandomBlockPosition(int i, int j, int k, int l, BlockPosition.MutableBlockPosition out) {
|
|
+ // Paper end
|
|
this.n = this.n * 3 + 1013904223;
|
|
int i1 = this.n >> 2;
|
|
|
|
- return new BlockPosition(i + (i1 & 15), j + (i1 >> 16 & l), k + (i1 >> 8 & 15));
|
|
+ out.setValues(i + (i1 & 15), j + (i1 >> 16 & l), k + (i1 >> 8 & 15)); // Paper - change to setValues call
|
|
+ return out; // Paper
|
|
}
|
|
|
|
public boolean isSavingDisabled() {
|
|
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
|
|
index 8458ac3cf864774520afcb9ddc7cd60fc8f9d4e6..d52a75ac37db59e4df23131aecc3e7fc6bedf3a9 100644
|
|
--- a/src/main/java/net/minecraft/server/WorldServer.java
|
|
+++ b/src/main/java/net/minecraft/server/WorldServer.java
|
|
@@ -557,7 +557,12 @@ public class WorldServer extends World implements GeneratorAccessSeed {
|
|
});
|
|
}
|
|
|
|
- public void a(Chunk chunk, int i) {
|
|
+ // Paper start - optimise random block ticking
|
|
+ private final BlockPosition.MutableBlockPosition chunkTickMutablePosition = new BlockPosition.MutableBlockPosition();
|
|
+ private final com.destroystokyo.paper.util.math.ThreadUnsafeRandom randomTickRandom = new com.destroystokyo.paper.util.math.ThreadUnsafeRandom();
|
|
+ // Paper end
|
|
+
|
|
+ public void a(Chunk chunk, int i) { final int randomTickSpeed = i; // Paper
|
|
ChunkCoordIntPair chunkcoordintpair = chunk.getPos();
|
|
boolean flag = this.isRaining();
|
|
int j = chunkcoordintpair.d();
|
|
@@ -565,10 +570,10 @@ public class WorldServer extends World implements GeneratorAccessSeed {
|
|
GameProfilerFiller gameprofilerfiller = this.getMethodProfiler();
|
|
|
|
gameprofilerfiller.enter("thunder");
|
|
- BlockPosition blockposition;
|
|
+ final BlockPosition.MutableBlockPosition blockposition = this.chunkTickMutablePosition; // Paper - use mutable to reduce allocation rate, final to force compile fail on change
|
|
|
|
if (!this.paperConfig.disableThunder && flag && this.T() && this.random.nextInt(100000) == 0) { // Paper - Disable thunder
|
|
- blockposition = this.a(this.a(j, 0, k, 15));
|
|
+ blockposition.setValues(this.a(this.a(j, 0, k, 15))); // Paper
|
|
if (this.isRainingAt(blockposition)) {
|
|
DifficultyDamageScaler difficultydamagescaler = this.getDamageScaler(blockposition);
|
|
boolean flag1 = this.getGameRules().getBoolean(GameRules.DO_MOB_SPAWNING) && this.random.nextDouble() < (double) difficultydamagescaler.b() * paperConfig.skeleHorseSpawnChance; // Paper
|
|
@@ -591,59 +596,77 @@ public class WorldServer extends World implements GeneratorAccessSeed {
|
|
}
|
|
|
|
gameprofilerfiller.exitEnter("iceandsnow");
|
|
- if (!this.paperConfig.disableIceAndSnow && this.random.nextInt(16) == 0) { // Paper - Disable ice and snow
|
|
- blockposition = this.getHighestBlockYAt(HeightMap.Type.MOTION_BLOCKING, this.a(j, 0, k, 15));
|
|
- BlockPosition blockposition1 = blockposition.down();
|
|
+ if (!this.paperConfig.disableIceAndSnow && this.randomTickRandom.nextInt(16) == 0) { // Paper - Disable ice and snow // Paper - optimise random ticking
|
|
+ // Paper start - optimise chunk ticking
|
|
+ this.getRandomBlockPosition(j, 0, k, 15, blockposition);
|
|
+ int normalY = chunk.getHighestBlockY(HeightMap.Type.MOTION_BLOCKING, blockposition.getX() & 15, blockposition.getZ() & 15);
|
|
+ int downY = normalY - 1;
|
|
+ blockposition.setY(normalY);
|
|
+ // Paper end
|
|
BiomeBase biomebase = this.getBiome(blockposition);
|
|
|
|
- if (biomebase.a((IWorldReader) this, blockposition1)) {
|
|
- org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(this, blockposition1, Blocks.ICE.getBlockData(), null); // CraftBukkit
|
|
+ // Paper start - optimise chunk ticking
|
|
+ blockposition.setY(downY);
|
|
+ if (biomebase.a((IWorldReader) this, blockposition)) {
|
|
+ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(this, blockposition, Blocks.ICE.getBlockData(), null); // CraftBukkit
|
|
+ // Paper end
|
|
}
|
|
|
|
+ blockposition.setY(normalY); // Paper
|
|
if (flag && biomebase.b(this, blockposition)) {
|
|
org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(this, blockposition, Blocks.SNOW.getBlockData(), null); // CraftBukkit
|
|
}
|
|
|
|
- if (flag && this.getBiome(blockposition1).d() == BiomeBase.Precipitation.RAIN) {
|
|
- this.getType(blockposition1).getBlock().c((World) this, blockposition1);
|
|
+ // Paper start - optimise chunk ticking
|
|
+ blockposition.setY(downY);
|
|
+ if (flag && this.getBiome(blockposition).d() == BiomeBase.Precipitation.RAIN) {
|
|
+ chunk.getType(blockposition).getBlock().c((World) this, blockposition);
|
|
+ // Paper end
|
|
}
|
|
}
|
|
|
|
- gameprofilerfiller.exitEnter("tickBlocks");
|
|
- timings.chunkTicksBlocks.startTiming(); // Paper
|
|
+ // Paper start - optimise random block ticking
|
|
+ gameprofilerfiller.exit();
|
|
if (i > 0) {
|
|
- ChunkSection[] achunksection = chunk.getSections();
|
|
- int l = achunksection.length;
|
|
+ gameprofilerfiller.enter("randomTick");
|
|
+ timings.chunkTicksBlocks.startTiming(); // Paper
|
|
|
|
- for (int i1 = 0; i1 < l; ++i1) {
|
|
- ChunkSection chunksection = achunksection[i1];
|
|
+ ChunkSection[] sections = chunk.getSections();
|
|
|
|
- if (chunksection != Chunk.a && chunksection.d()) {
|
|
- int j1 = chunksection.getYPosition();
|
|
+ for (int sectionIndex = 0; sectionIndex < 16; ++sectionIndex) {
|
|
+ ChunkSection section = sections[sectionIndex];
|
|
+ if (section == null || section.tickingList.size() == 0) {
|
|
+ continue;
|
|
+ }
|
|
|
|
- for (int k1 = 0; k1 < i; ++k1) {
|
|
- BlockPosition blockposition2 = this.a(j, j1, k, 15);
|
|
+ int yPos = sectionIndex << 4;
|
|
|
|
- gameprofilerfiller.enter("randomTick");
|
|
- IBlockData iblockdata = chunksection.getType(blockposition2.getX() - j, blockposition2.getY() - j1, blockposition2.getZ() - k);
|
|
+ for (int a = 0; a < randomTickSpeed; ++a) {
|
|
+ int tickingBlocks = section.tickingList.size();
|
|
+ int index = this.randomTickRandom.nextInt(16 * 16 * 16);
|
|
+ if (index >= tickingBlocks) {
|
|
+ continue;
|
|
+ }
|
|
|
|
- if (iblockdata.isTicking()) {
|
|
- iblockdata.b(this, blockposition2, this.random);
|
|
- }
|
|
+ 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;
|
|
|
|
- Fluid fluid = iblockdata.getFluid();
|
|
+ BlockPosition blockposition2 = blockposition.setValues(j + randomX, randomY, k + randomZ);
|
|
+ IBlockData iblockdata = com.destroystokyo.paper.util.maplist.IBlockDataList.getBlockDataFromRaw(raw);
|
|
|
|
- if (fluid.f()) {
|
|
- fluid.b(this, blockposition2, this.random);
|
|
- }
|
|
+ iblockdata.b(this, blockposition2, this.randomTickRandom);
|
|
|
|
- gameprofilerfiller.exit();
|
|
- }
|
|
+ // We drop the fluid tick since LAVA is ALREADY TICKED by the above method.
|
|
+ // TODO CHECK ON UPDATE
|
|
}
|
|
}
|
|
+ gameprofilerfiller.exit();
|
|
+ timings.chunkTicksBlocks.stopTiming(); // Paper
|
|
+ // Paper end
|
|
}
|
|
- timings.chunkTicksBlocks.stopTiming(); // Paper
|
|
- gameprofilerfiller.exit();
|
|
}
|
|
|
|
protected BlockPosition a(BlockPosition blockposition) {
|