From c20a5e8805f64097430cf0722011f20862a8df9c Mon Sep 17 00:00:00 2001 From: Gabriel Harris-Rouquette Date: Wed, 26 Sep 2018 11:08:30 -0700 Subject: [PATCH] Fix MC-136995 - Chunk loading and unloading issue with entities placed in exact positions. (#5160) Scatter gun patches to improve entity tracking and position tracking. Provided by Aikar through the Paper project, this commit of patches combines the following patches: https://github.com/PaperMC/Paper/blob/fd1bd5223a461b6d98280bb8f2d67280a30dd24a/Spigot-Server-Patches/0306-Mark-chunk-dirty-anytime-entities-change-to-guarante.patch https://github.com/PaperMC/Paper/blob/fd1bd5223a461b6d98280bb8f2d67280a30dd24a/Spigot-Server-Patches/0315-Always-process-chunk-registration-after-moving.patch https://github.com/PaperMC/Paper/blob/fd1bd5223a461b6d98280bb8f2d67280a30dd24a/Spigot-Server-Patches/0335-Ensure-chunks-are-always-loaded-on-hard-position-set.patch https://github.com/PaperMC/Paper/blob/fd1bd5223a461b6d98280bb8f2d67280a30dd24a/Spigot-Server-Patches/0378-Sync-Player-Position-to-Vehicles.patch --- .../net/minecraft/entity/Entity.java.patch | 93 +++++++-- .../entity/EntityLeashKnot.java.patch | 10 + .../entity/monster/EntityShulker.java.patch | 10 +- .../network/NetHandlerPlayServer.java.patch | 26 ++- .../net/minecraft/world/World.java.patch | 184 ++++++++++-------- .../minecraft/world/chunk/Chunk.java.patch | 50 +++-- 6 files changed, 251 insertions(+), 122 deletions(-) create mode 100644 patches/minecraft/net/minecraft/entity/EntityLeashKnot.java.patch diff --git a/patches/minecraft/net/minecraft/entity/Entity.java.patch b/patches/minecraft/net/minecraft/entity/Entity.java.patch index 91c2107134..443c8f845c 100644 --- a/patches/minecraft/net/minecraft/entity/Entity.java.patch +++ b/patches/minecraft/net/minecraft/entity/Entity.java.patch @@ -46,7 +46,23 @@ public int func_145782_y() { return this.field_145783_c; -@@ -1053,7 +1065,7 @@ +@@ -344,6 +356,7 @@ + this.field_70165_t = p_70107_1_; + this.field_70163_u = p_70107_3_; + this.field_70161_v = p_70107_5_; ++ if (this.isAddedToWorld) this.field_70170_p.func_72866_a(this, false); // Forge - Process chunk registration after moving. + float f = this.field_70130_N / 2.0F; + float f1 = this.field_70131_O; + this.func_174826_a(new AxisAlignedBB(p_70107_1_ - (double)f, p_70107_3_, p_70107_5_ - (double)f, p_70107_1_ + (double)f, p_70107_3_ + (double)f1, p_70107_5_ + (double)f)); +@@ -995,6 +1008,7 @@ + this.field_70165_t = (axisalignedbb.field_72340_a + axisalignedbb.field_72336_d) / 2.0D; + this.field_70163_u = axisalignedbb.field_72338_b; + this.field_70161_v = (axisalignedbb.field_72339_c + axisalignedbb.field_72334_f) / 2.0D; ++ if (this.isAddedToWorld) this.field_70170_p.func_72866_a(this, false); // Forge - Process chunk registration after moving. + } + + protected SoundEvent func_184184_Z() +@@ -1053,7 +1067,7 @@ protected void func_180429_a(BlockPos p_180429_1_, Block p_180429_2_) { @@ -55,7 +71,7 @@ if (this.field_70170_p.func_180495_p(p_180429_1_.func_177984_a()).func_177230_c() == Blocks.field_150431_aC) { -@@ -1259,6 +1271,7 @@ +@@ -1259,6 +1273,7 @@ BlockPos blockpos = new BlockPos(i, j, k); IBlockState iblockstate = this.field_70170_p.func_180495_p(blockpos); @@ -63,7 +79,7 @@ if (iblockstate.func_185901_i() != EnumBlockRenderType.INVISIBLE) { this.field_70170_p.func_175688_a(EnumParticleTypes.BLOCK_CRACK, this.field_70165_t + ((double)this.field_70146_Z.nextFloat() - 0.5D) * (double)this.field_70130_N, this.func_174813_aQ().field_72338_b + 0.1D, this.field_70161_v + ((double)this.field_70146_Z.nextFloat() - 0.5D) * (double)this.field_70130_N, -this.field_70159_w * 4.0D, 1.5D, -this.field_70179_y * 4.0D, Block.func_176210_f(iblockstate)); -@@ -1277,12 +1290,12 @@ +@@ -1277,12 +1292,12 @@ BlockPos blockpos = new BlockPos(this.field_70165_t, d0, this.field_70161_v); IBlockState iblockstate = this.field_70170_p.func_180495_p(blockpos); @@ -80,7 +96,15 @@ } else { -@@ -1707,6 +1720,7 @@ +@@ -1382,6 +1397,7 @@ + this.field_70126_B -= 360.0F; + } + ++ this.field_70170_p.func_72964_e((int) Math.floor(this.field_70165_t) >> 4, (int) Math.floor(this.field_70161_v) >> 4); // Forge - ensure target chunk is loaded. + this.func_70107_b(this.field_70165_t, this.field_70163_u, this.field_70161_v); + this.func_70101_b(p_70080_7_, p_70080_8_); + } +@@ -1707,6 +1723,7 @@ { p_189511_1_.func_74757_a("Glowing", this.field_184238_ar); } @@ -88,7 +112,7 @@ if (!this.field_184236_aF.isEmpty()) { -@@ -1720,6 +1734,9 @@ +@@ -1720,6 +1737,9 @@ p_189511_1_.func_74782_a("Tags", nbttaglist); } @@ -98,7 +122,7 @@ this.func_70014_b(p_189511_1_); if (this.func_184207_aI()) -@@ -1826,7 +1843,11 @@ +@@ -1826,7 +1846,11 @@ this.func_174810_b(p_70020_1_.func_74767_n("Silent")); this.func_189654_d(p_70020_1_.func_74767_n("NoGravity")); this.func_184195_f(p_70020_1_.func_74767_n("Glowing")); @@ -110,7 +134,7 @@ if (p_70020_1_.func_150297_b("Tags", 9)) { this.field_184236_aF.clear(); -@@ -1918,7 +1939,10 @@ +@@ -1918,7 +1942,10 @@ { EntityItem entityitem = new EntityItem(this.field_70170_p, this.field_70165_t, this.field_70163_u + (double)p_70099_2_, this.field_70161_v, p_70099_1_); entityitem.func_174869_p(); @@ -122,7 +146,7 @@ return entityitem; } } -@@ -1985,6 +2009,7 @@ +@@ -1985,6 +2012,7 @@ this.field_70159_w = 0.0D; this.field_70181_x = 0.0D; this.field_70179_y = 0.0D; @@ -130,7 +154,7 @@ this.func_70071_h_(); if (this.func_184218_aH()) -@@ -2032,6 +2057,7 @@ +@@ -2032,6 +2060,7 @@ } } @@ -138,7 +162,7 @@ if (p_184205_2_ || this.func_184228_n(p_184205_1_) && p_184205_1_.func_184219_q(this)) { if (this.func_184218_aH()) -@@ -2067,6 +2093,7 @@ +@@ -2067,6 +2096,7 @@ if (this.field_184239_as != null) { Entity entity = this.field_184239_as; @@ -146,7 +170,7 @@ this.field_184239_as = null; entity.func_184225_p(this); } -@@ -2509,8 +2536,16 @@ +@@ -2509,8 +2539,16 @@ @Nullable public Entity func_184204_a(int p_184204_1_) { @@ -163,7 +187,7 @@ this.field_70170_p.field_72984_F.func_76320_a("changeDimension"); MinecraftServer minecraftserver = this.func_184102_h(); int i = this.field_71093_bK; -@@ -2518,7 +2553,7 @@ +@@ -2518,7 +2556,7 @@ WorldServer worldserver1 = minecraftserver.func_71218_a(p_184204_1_); this.field_71093_bK = p_184204_1_; @@ -172,7 +196,7 @@ { worldserver1 = minecraftserver.func_71218_a(0); this.field_71093_bK = 0; -@@ -2529,22 +2564,23 @@ +@@ -2529,22 +2567,23 @@ this.field_70170_p.field_72984_F.func_76320_a("reposition"); BlockPos blockpos; @@ -201,7 +225,7 @@ { d0 = MathHelper.func_151237_a(d0 * 8.0D, worldserver1.func_175723_af().func_177726_b() + 16.0D, worldserver1.func_175723_af().func_177728_d() - 16.0D); d1 = MathHelper.func_151237_a(d1 * 8.0D, worldserver1.func_175723_af().func_177736_c() + 16.0D, worldserver1.func_175723_af().func_177733_e() - 16.0D); -@@ -2554,8 +2590,7 @@ +@@ -2554,8 +2593,7 @@ d1 = (double)MathHelper.func_76125_a((int)d1, -29999872, 29999872); float f = this.field_70177_z; this.func_70012_b(d0, this.field_70163_u, d1, 90.0F, 0.0F); @@ -211,7 +235,7 @@ blockpos = new BlockPos(this); } -@@ -2567,7 +2602,7 @@ +@@ -2567,7 +2605,7 @@ { entity.func_180432_n(this); @@ -220,7 +244,7 @@ { BlockPos blockpos1 = worldserver1.func_175672_r(worldserver1.func_175694_M()); entity.func_174828_a(blockpos1, entity.field_70177_z, entity.field_70125_A); -@@ -2604,7 +2639,7 @@ +@@ -2604,7 +2642,7 @@ public float func_180428_a(Explosion p_180428_1_, World p_180428_2_, BlockPos p_180428_3_, IBlockState p_180428_4_) { @@ -229,12 +253,47 @@ } public boolean func_174816_a(Explosion p_174816_1_, World p_174816_2_, BlockPos p_174816_3_, IBlockState p_174816_4_, float p_174816_5_) -@@ -2901,6 +2936,183 @@ +@@ -2901,6 +2939,218 @@ EnchantmentHelper.func_151385_b(p_174815_1_, p_174815_2_); } + /* ================================== Forge Start =====================================*/ + /** ++ * Internal use for keeping track of entities that are tracked by a world, to ++ * allow guarantees that entity position changes will force a chunk load, avoiding ++ * potential issues with entity desyncing and bad chunk data. ++ */ ++ private boolean isAddedToWorld; ++ ++ /** ++ * Gets whether this entity has been added to a world (for tracking). Specifically ++ * between the times when an entity is added to a world and the entity being removed ++ * from the world's tracked lists. See {@link World#onEntityAdded(Entity)} and ++ * {@link World#onEntityRemoved(Entity)}. ++ * ++ * @return True if this entity is being tracked by a world ++ */ ++ public final boolean isAddedToWorld() { return this.isAddedToWorld; } ++ ++ /** ++ * Called after the entity has been added to the world's ++ * ticking list. Can be overriden, but needs to call super ++ * to prevent MC-136995. ++ */ ++ public void onAddedToWorld() { ++ this.isAddedToWorld = true; ++ } ++ ++ /** ++ * Called after the entity has been removed to the world's ++ * ticking list. Can be overriden, but needs to call super ++ * to prevent MC-136995. ++ */ ++ public void onRemovedFromWorld() { ++ this.isAddedToWorld = false; ++ } ++ ++ /** + * Returns a NBTTagCompound that can be used to store custom data for this entity. + * It will be written, and read from disc, so it persists over world saves. + * @return A NBTTagCompound diff --git a/patches/minecraft/net/minecraft/entity/EntityLeashKnot.java.patch b/patches/minecraft/net/minecraft/entity/EntityLeashKnot.java.patch new file mode 100644 index 0000000000..d8c6b7e89b --- /dev/null +++ b/patches/minecraft/net/minecraft/entity/EntityLeashKnot.java.patch @@ -0,0 +1,10 @@ +--- ../src-base/minecraft/net/minecraft/entity/EntityLeashKnot.java ++++ ../src-work/minecraft/net/minecraft/entity/EntityLeashKnot.java +@@ -43,6 +43,7 @@ + this.field_70165_t = (double)this.field_174861_a.func_177958_n() + 0.5D; + this.field_70163_u = (double)this.field_174861_a.func_177956_o() + 0.5D; + this.field_70161_v = (double)this.field_174861_a.func_177952_p() + 0.5D; ++ if (this.isAddedToWorld()) this.field_70170_p.func_72866_a(this, false); // Forge - Process chunk registration after moving. + } + + public void func_174859_a(EnumFacing p_174859_1_) diff --git a/patches/minecraft/net/minecraft/entity/monster/EntityShulker.java.patch b/patches/minecraft/net/minecraft/entity/monster/EntityShulker.java.patch index c9e4dd32a3..d68a89540e 100644 --- a/patches/minecraft/net/minecraft/entity/monster/EntityShulker.java.patch +++ b/patches/minecraft/net/minecraft/entity/monster/EntityShulker.java.patch @@ -1,6 +1,14 @@ --- ../src-base/minecraft/net/minecraft/entity/monster/EntityShulker.java +++ ../src-work/minecraft/net/minecraft/entity/monster/EntityShulker.java -@@ -426,6 +426,13 @@ +@@ -311,6 +311,7 @@ + this.field_70165_t = (double)blockpos.func_177958_n() + 0.5D; + this.field_70163_u = (double)blockpos.func_177956_o(); + this.field_70161_v = (double)blockpos.func_177952_p() + 0.5D; ++ if (this.isAddedToWorld()) this.field_70170_p.func_72866_a(this, false); // Forge - Process chunk registration after moving. + this.field_70169_q = this.field_70165_t; + this.field_70167_r = this.field_70163_u; + this.field_70166_s = this.field_70161_v; +@@ -426,6 +427,13 @@ if (flag) { diff --git a/patches/minecraft/net/minecraft/network/NetHandlerPlayServer.java.patch b/patches/minecraft/net/minecraft/network/NetHandlerPlayServer.java.patch index 877ffe5f53..7e534a4fee 100644 --- a/patches/minecraft/net/minecraft/network/NetHandlerPlayServer.java.patch +++ b/patches/minecraft/net/minecraft/network/NetHandlerPlayServer.java.patch @@ -1,6 +1,20 @@ --- ../src-base/minecraft/net/minecraft/network/NetHandlerPlayServer.java +++ ../src-work/minecraft/net/minecraft/network/NetHandlerPlayServer.java -@@ -671,7 +671,10 @@ +@@ -377,11 +377,13 @@ + } + + entity.func_70080_a(d3, d4, d5, f, f1); ++ this.field_147369_b.func_70080_a(d3, d4, d5, f, f1); // Forge - Resync player position on vehicle moving + boolean flag2 = worldserver.func_184144_a(entity, entity.func_174813_aQ().func_186664_h(0.0625D)).isEmpty(); + + if (flag && (flag1 || !flag2)) + { + entity.func_70080_a(d0, d1, d2, f, f1); ++ this.field_147369_b.func_70080_a(d0, d1, d2, f, f1); // Forge - Resync player position on vehicle moving + this.field_147371_a.func_179290_a(new SPacketMoveVehicle(entity)); + return; + } +@@ -671,7 +673,10 @@ double d2 = this.field_147369_b.field_70161_v - ((double)blockpos.func_177952_p() + 0.5D); double d3 = d0 * d0 + d1 * d1 + d2 * d2; @@ -12,7 +26,7 @@ { return; } -@@ -729,7 +732,9 @@ +@@ -729,7 +734,9 @@ if (blockpos.func_177956_o() < this.field_147367_d.func_71207_Z() - 1 || enumfacing != EnumFacing.UP && blockpos.func_177956_o() < this.field_147367_d.func_71207_Z()) { @@ -23,7 +37,7 @@ { this.field_147369_b.field_71134_c.func_187251_a(this.field_147369_b, worldserver, itemstack, enumhand, blockpos, enumfacing, p_184337_1_.func_187026_d(), p_184337_1_.func_187025_e(), p_184337_1_.func_187020_f()); } -@@ -933,7 +938,9 @@ +@@ -933,7 +940,9 @@ } else { @@ -34,7 +48,7 @@ this.field_147367_d.func_184103_al().func_148544_a(itextcomponent, false); } -@@ -1066,6 +1073,7 @@ +@@ -1066,6 +1075,7 @@ else if (p_147340_1_.func_149565_c() == CPacketUseEntity.Action.INTERACT_AT) { EnumHand enumhand1 = p_147340_1_.func_186994_b(); @@ -42,7 +56,7 @@ entity.func_184199_a(this.field_147369_b, p_147340_1_.func_179712_b(), enumhand1); } else if (p_147340_1_.func_149565_c() == CPacketUseEntity.Action.ATTACK) -@@ -1106,7 +1114,7 @@ +@@ -1106,7 +1116,7 @@ return; } @@ -51,7 +65,7 @@ if (this.field_147367_d.func_71199_h()) { -@@ -1149,7 +1157,7 @@ +@@ -1149,7 +1159,7 @@ { ItemStack itemstack2 = this.field_147369_b.field_71070_bA.func_184996_a(p_147351_1_.func_149544_d(), p_147351_1_.func_149543_e(), p_147351_1_.func_186993_f(), this.field_147369_b); diff --git a/patches/minecraft/net/minecraft/world/World.java.patch b/patches/minecraft/net/minecraft/world/World.java.patch index 1757acc9e8..3475b06610 100644 --- a/patches/minecraft/net/minecraft/world/World.java.patch +++ b/patches/minecraft/net/minecraft/world/World.java.patch @@ -1,6 +1,14 @@ --- ../src-base/minecraft/net/minecraft/world/World.java +++ ../src-work/minecraft/net/minecraft/world/World.java -@@ -63,8 +63,15 @@ +@@ -11,6 +11,7 @@ + import java.util.Random; + import java.util.UUID; + import java.util.function.Supplier; ++ + import javax.annotation.Nullable; + import net.minecraft.advancements.AdvancementManager; + import net.minecraft.advancements.FunctionManager; +@@ -63,8 +64,15 @@ import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; @@ -17,7 +25,7 @@ private int field_181546_a = 63; protected boolean field_72999_e; public final List field_72996_f = Lists.newArrayList(); -@@ -108,6 +115,12 @@ +@@ -108,6 +116,12 @@ private final WorldBorder field_175728_M; int[] field_72994_J; @@ -30,7 +38,7 @@ protected World(ISaveHandler p_i45749_1_, WorldInfo p_i45749_2_, WorldProvider p_i45749_3_, Profiler p_i45749_4_, boolean p_i45749_5_) { this.field_73021_x = Lists.newArrayList(this.field_184152_t); -@@ -122,6 +135,7 @@ +@@ -122,6 +136,7 @@ this.field_73011_w = p_i45749_3_; this.field_72995_K = p_i45749_5_; this.field_175728_M = p_i45749_3_.func_177501_r(); @@ -38,7 +46,7 @@ } public World func_175643_b() -@@ -131,6 +145,11 @@ +@@ -131,6 +146,11 @@ public Biome func_180494_b(final BlockPos p_180494_1_) { @@ -50,7 +58,7 @@ if (this.func_175667_e(p_180494_1_)) { Chunk chunk = this.func_175726_f(p_180494_1_); -@@ -207,7 +226,7 @@ +@@ -207,7 +227,7 @@ public boolean func_175623_d(BlockPos p_175623_1_) { @@ -59,7 +67,7 @@ } public boolean func_175667_e(BlockPos p_175667_1_) -@@ -308,24 +327,51 @@ +@@ -308,24 +328,51 @@ else { Chunk chunk = this.func_175726_f(p_180501_1_); @@ -114,7 +122,7 @@ this.func_184138_a(p_180501_1_, iblockstate, p_180501_2_, p_180501_3_); } -@@ -342,8 +388,6 @@ +@@ -342,8 +389,6 @@ { this.func_190522_c(p_180501_1_, block); } @@ -123,7 +131,7 @@ } } } -@@ -358,7 +402,7 @@ +@@ -358,7 +403,7 @@ IBlockState iblockstate = this.func_180495_p(p_175655_1_); Block block = iblockstate.func_177230_c(); @@ -132,7 +140,7 @@ { return false; } -@@ -441,6 +485,9 @@ +@@ -441,6 +486,9 @@ public void func_175685_c(BlockPos p_175685_1_, Block p_175685_2_, boolean p_175685_3_) { @@ -142,7 +150,7 @@ this.func_190524_a(p_175685_1_.func_177976_e(), p_175685_2_, p_175685_1_); this.func_190524_a(p_175685_1_.func_177974_f(), p_175685_2_, p_175685_1_); this.func_190524_a(p_175685_1_.func_177977_b(), p_175685_2_, p_175685_1_); -@@ -456,6 +503,11 @@ +@@ -456,6 +504,11 @@ public void func_175695_a(BlockPos p_175695_1_, Block p_175695_2_, EnumFacing p_175695_3_) { @@ -154,7 +162,7 @@ if (p_175695_3_ != EnumFacing.WEST) { this.func_190524_a(p_175695_1_.func_177976_e(), p_175695_2_, p_175695_1_); -@@ -507,7 +559,7 @@ +@@ -507,7 +560,7 @@ { try { @@ -163,7 +171,7 @@ } catch (Throwable var2) { -@@ -527,11 +579,11 @@ +@@ -527,11 +580,11 @@ { IBlockState iblockstate = this.func_180495_p(p_190529_1_); @@ -177,7 +185,7 @@ } catch (Throwable throwable) { -@@ -543,7 +595,7 @@ +@@ -543,7 +596,7 @@ { try { @@ -186,7 +194,7 @@ } catch (Throwable var2) { -@@ -588,7 +640,7 @@ +@@ -588,7 +641,7 @@ { IBlockState iblockstate = this.func_180495_p(blockpos1); @@ -195,7 +203,7 @@ { return false; } -@@ -862,7 +914,7 @@ +@@ -862,7 +915,7 @@ public boolean func_72935_r() { @@ -204,7 +212,7 @@ } @Nullable -@@ -1065,6 +1117,13 @@ +@@ -1065,6 +1118,13 @@ public void func_184148_a(@Nullable EntityPlayer p_184148_1_, double p_184148_2_, double p_184148_4_, double p_184148_6_, SoundEvent p_184148_8_, SoundCategory p_184148_9_, float p_184148_10_, float p_184148_11_) { @@ -218,7 +226,7 @@ for (int i = 0; i < this.field_73021_x.size(); ++i) { ((IWorldEventListener)this.field_73021_x.get(i)).func_184375_a(p_184148_1_, p_184148_8_, p_184148_9_, p_184148_2_, p_184148_4_, p_184148_6_, p_184148_10_, p_184148_11_); -@@ -1118,6 +1177,9 @@ +@@ -1118,6 +1178,9 @@ public boolean func_72838_d(Entity p_72838_1_) { @@ -228,7 +236,7 @@ int i = MathHelper.func_76128_c(p_72838_1_.field_70165_t / 16.0D); int j = MathHelper.func_76128_c(p_72838_1_.field_70161_v / 16.0D); boolean flag = p_72838_1_.field_98038_p; -@@ -1140,6 +1202,8 @@ +@@ -1140,6 +1203,8 @@ this.func_72854_c(); } @@ -237,7 +245,23 @@ this.func_72964_e(i, j).func_76612_a(p_72838_1_); this.field_72996_f.add(p_72838_1_); this.func_72923_a(p_72838_1_); -@@ -1227,6 +1291,7 @@ +@@ -1153,6 +1218,7 @@ + { + ((IWorldEventListener)this.field_73021_x.get(i)).func_72703_a(p_72923_1_); + } ++ p_72923_1_.onAddedToWorld(); + } + + public void func_72847_b(Entity p_72847_1_) +@@ -1161,6 +1227,7 @@ + { + ((IWorldEventListener)this.field_73021_x.get(i)).func_72709_b(p_72847_1_); + } ++ p_72847_1_.onRemovedFromWorld(); + } + + public void func_72900_e(Entity p_72900_1_) +@@ -1227,6 +1294,7 @@ IBlockState iblockstate = Blocks.field_150348_b.func_176223_P(); BlockPos.PooledMutableBlockPos blockpos$pooledmutableblockpos = BlockPos.PooledMutableBlockPos.func_185346_s(); @@ -245,7 +269,7 @@ try { for (int k1 = i; k1 < j; ++k1) -@@ -1269,7 +1334,7 @@ +@@ -1269,7 +1337,7 @@ iblockstate1.func_185908_a(this, blockpos$pooledmutableblockpos, p_191504_2_, p_191504_4_, p_191504_1_, false); @@ -254,7 +278,7 @@ { boolean flag5 = true; return flag5; -@@ -1319,11 +1384,10 @@ +@@ -1319,11 +1387,10 @@ } } } @@ -267,7 +291,7 @@ public void func_72848_b(IWorldEventListener p_72848_1_) { this.field_73021_x.remove(p_72848_1_); -@@ -1361,19 +1425,38 @@ +@@ -1361,19 +1428,38 @@ public int func_72967_a(float p_72967_1_) { @@ -308,7 +332,7 @@ float f = this.func_72826_c(p_72971_1_); float f1 = 1.0F - (MathHelper.func_76134_b(f * ((float)Math.PI * 2F)) * 2.0F + 0.2F); f1 = MathHelper.func_76131_a(f1, 0.0F, 1.0F); -@@ -1386,6 +1469,12 @@ +@@ -1386,6 +1472,12 @@ @SideOnly(Side.CLIENT) public Vec3d func_72833_a(Entity p_72833_1_, float p_72833_2_) { @@ -321,7 +345,7 @@ float f = this.func_72826_c(p_72833_2_); float f1 = MathHelper.func_76134_b(f * ((float)Math.PI * 2F)) * 2.0F + 0.5F; f1 = MathHelper.func_76131_a(f1, 0.0F, 1.0F); -@@ -1393,9 +1482,7 @@ +@@ -1393,9 +1485,7 @@ int j = MathHelper.func_76128_c(p_72833_1_.field_70163_u); int k = MathHelper.func_76128_c(p_72833_1_.field_70161_v); BlockPos blockpos = new BlockPos(i, j, k); @@ -332,7 +356,7 @@ float f3 = (float)(l >> 16 & 255) / 255.0F; float f4 = (float)(l >> 8 & 255) / 255.0F; float f5 = (float)(l & 255) / 255.0F; -@@ -1444,20 +1531,25 @@ +@@ -1444,20 +1534,25 @@ public float func_72826_c(float p_72826_1_) { @@ -361,7 +385,7 @@ public float func_72929_e(float p_72929_1_) { float f = this.func_72826_c(p_72929_1_); -@@ -1467,6 +1559,12 @@ +@@ -1467,6 +1562,12 @@ @SideOnly(Side.CLIENT) public Vec3d func_72824_f(float p_72824_1_) { @@ -374,7 +398,7 @@ float f = this.func_72826_c(p_72824_1_); float f1 = MathHelper.func_76134_b(f * ((float)Math.PI * 2F)) * 2.0F + 0.5F; f1 = MathHelper.func_76131_a(f1, 0.0F, 1.0F); -@@ -1522,9 +1620,9 @@ +@@ -1522,9 +1623,9 @@ for (blockpos = new BlockPos(p_175672_1_.func_177958_n(), chunk.func_76625_h() + 16, p_175672_1_.func_177952_p()); blockpos.func_177956_o() >= 0; blockpos = blockpos1) { blockpos1 = blockpos.func_177977_b(); @@ -386,7 +410,7 @@ { break; } -@@ -1536,6 +1634,12 @@ +@@ -1536,6 +1637,12 @@ @SideOnly(Side.CLIENT) public float func_72880_h(float p_72880_1_) { @@ -399,7 +423,7 @@ float f = this.func_72826_c(p_72880_1_); float f1 = 1.0F - (MathHelper.func_76134_b(f * ((float)Math.PI * 2F)) * 2.0F + 0.25F); f1 = MathHelper.func_76131_a(f1, 0.0F, 1.0F); -@@ -1570,6 +1674,7 @@ +@@ -1570,6 +1677,7 @@ try { @@ -407,7 +431,7 @@ ++entity.field_70173_aa; entity.func_70071_h_(); } -@@ -1587,6 +1692,12 @@ +@@ -1587,6 +1695,12 @@ entity.func_85029_a(crashreportcategory); } @@ -420,7 +444,7 @@ throw new ReportedException(crashreport); } -@@ -1641,13 +1752,21 @@ +@@ -1641,13 +1755,21 @@ { try { @@ -442,7 +466,7 @@ throw new ReportedException(crashreport1); } } -@@ -1674,14 +1793,23 @@ +@@ -1674,14 +1796,23 @@ this.field_72984_F.func_76318_c("blockEntities"); @@ -469,7 +493,7 @@ Iterator iterator = this.field_175730_i.iterator(); while (iterator.hasNext()) -@@ -1692,7 +1820,7 @@ +@@ -1692,7 +1823,7 @@ { BlockPos blockpos = tileentity.func_174877_v(); @@ -478,7 +502,7 @@ { try { -@@ -1700,7 +1828,9 @@ +@@ -1700,7 +1831,9 @@ { return String.valueOf((Object)TileEntity.func_190559_a(tileentity.getClass())); }); @@ -488,7 +512,7 @@ this.field_72984_F.func_76319_b(); } catch (Throwable throwable) -@@ -1708,6 +1838,13 @@ +@@ -1708,6 +1841,13 @@ CrashReport crashreport2 = CrashReport.func_85055_a(throwable, "Ticking block entity"); CrashReportCategory crashreportcategory2 = crashreport2.func_85058_a("Block entity being ticked"); tileentity.func_145828_a(crashreportcategory2); @@ -502,7 +526,7 @@ throw new ReportedException(crashreport2); } } -@@ -1720,7 +1857,10 @@ +@@ -1720,7 +1860,10 @@ if (this.func_175667_e(tileentity.func_174877_v())) { @@ -514,7 +538,7 @@ } } } -@@ -1764,12 +1904,18 @@ +@@ -1764,12 +1907,18 @@ public boolean func_175700_a(TileEntity p_175700_1_) { @@ -533,7 +557,7 @@ if (this.field_72995_K) { -@@ -1785,6 +1931,11 @@ +@@ -1785,6 +1934,11 @@ { if (this.field_147481_N) { @@ -545,7 +569,7 @@ this.field_147484_a.addAll(p_147448_1_); } else -@@ -1807,9 +1958,13 @@ +@@ -1807,9 +1961,13 @@ { int j2 = MathHelper.func_76128_c(p_72866_1_.field_70165_t); int k2 = MathHelper.func_76128_c(p_72866_1_.field_70161_v); @@ -561,7 +585,7 @@ { return; } -@@ -1831,6 +1986,7 @@ +@@ -1831,6 +1989,7 @@ } else { @@ -569,7 +593,7 @@ p_72866_1_.func_70071_h_(); } } -@@ -1914,7 +2070,7 @@ +@@ -1914,7 +2073,7 @@ { Entity entity4 = list.get(j2); @@ -578,7 +602,7 @@ { return false; } -@@ -1972,6 +2128,12 @@ +@@ -1972,6 +2131,12 @@ { IBlockState iblockstate1 = this.func_180495_p(blockpos$pooledmutableblockpos.func_181079_c(l3, i4, j4)); @@ -591,7 +615,7 @@ if (iblockstate1.func_185904_a().func_76224_d()) { blockpos$pooledmutableblockpos.func_185344_t(); -@@ -2011,6 +2173,11 @@ +@@ -2011,6 +2176,11 @@ blockpos$pooledmutableblockpos.func_185344_t(); return true; } @@ -603,7 +627,7 @@ } } } -@@ -2050,6 +2217,16 @@ +@@ -2050,6 +2220,16 @@ IBlockState iblockstate1 = this.func_180495_p(blockpos$pooledmutableblockpos); Block block = iblockstate1.func_177230_c(); @@ -620,7 +644,7 @@ if (iblockstate1.func_185904_a() == p_72918_2_) { double d0 = (double)((float)(i4 + 1) - BlockLiquid.func_149801_b(((Integer)iblockstate1.func_177229_b(BlockLiquid.field_176367_b)).intValue())); -@@ -2095,7 +2272,14 @@ +@@ -2095,7 +2275,14 @@ { for (int j4 = j3; j4 < k3; ++j4) { @@ -636,7 +660,7 @@ { blockpos$pooledmutableblockpos.func_185344_t(); return true; -@@ -2116,6 +2300,7 @@ +@@ -2116,6 +2303,7 @@ public Explosion func_72885_a(@Nullable Entity p_72885_1_, double p_72885_2_, double p_72885_4_, double p_72885_6_, float p_72885_8_, boolean p_72885_9_, boolean p_72885_10_) { Explosion explosion = new Explosion(this, p_72885_1_, p_72885_2_, p_72885_4_, p_72885_6_, p_72885_8_, p_72885_9_, p_72885_10_); @@ -644,7 +668,7 @@ explosion.func_77278_a(); explosion.func_77279_a(true); return explosion; -@@ -2238,6 +2423,7 @@ +@@ -2238,6 +2426,7 @@ public void func_175690_a(BlockPos p_175690_1_, @Nullable TileEntity p_175690_2_) { @@ -652,7 +676,7 @@ if (!this.func_189509_E(p_175690_1_)) { if (p_175690_2_ != null && !p_175690_2_.func_145837_r()) -@@ -2245,6 +2431,8 @@ +@@ -2245,6 +2434,8 @@ if (this.field_147481_N) { p_175690_2_.func_174878_a(p_175690_1_); @@ -661,7 +685,7 @@ Iterator iterator1 = this.field_147484_a.iterator(); while (iterator1.hasNext()) -@@ -2262,7 +2450,8 @@ +@@ -2262,7 +2453,8 @@ } else { @@ -671,7 +695,7 @@ this.func_175700_a(p_175690_2_); } } -@@ -2277,6 +2466,8 @@ +@@ -2277,6 +2469,8 @@ { tileentity2.func_145843_s(); this.field_147484_a.remove(tileentity2); @@ -680,7 +704,7 @@ } else { -@@ -2289,6 +2480,7 @@ +@@ -2289,6 +2483,7 @@ this.func_175726_f(p_175713_1_).func_177425_e(p_175713_1_); } @@ -688,7 +712,7 @@ } public void func_147457_a(TileEntity p_147457_1_) -@@ -2315,7 +2507,7 @@ +@@ -2315,7 +2510,7 @@ if (chunk1 != null && !chunk1.func_76621_g()) { IBlockState iblockstate1 = this.func_180495_p(p_175677_1_); @@ -697,7 +721,7 @@ } else { -@@ -2338,6 +2530,7 @@ +@@ -2338,6 +2533,7 @@ { this.field_72985_G = p_72891_1_; this.field_72992_H = p_72891_2_; @@ -705,7 +729,7 @@ } public void func_72835_b() -@@ -2347,6 +2540,11 @@ +@@ -2347,6 +2543,11 @@ protected void func_72947_a() { @@ -717,7 +741,7 @@ if (this.field_72986_A.func_76059_o()) { this.field_73004_o = 1.0F; -@@ -2360,6 +2558,11 @@ +@@ -2360,6 +2561,11 @@ protected void func_72979_l() { @@ -729,7 +753,7 @@ if (this.field_73011_w.func_191066_m()) { if (!this.field_72995_K) -@@ -2484,6 +2687,11 @@ +@@ -2484,6 +2690,11 @@ public boolean func_175670_e(BlockPos p_175670_1_, boolean p_175670_2_) { @@ -741,7 +765,7 @@ Biome biome = this.func_180494_b(p_175670_1_); float f = biome.func_180626_a(p_175670_1_); -@@ -2525,6 +2733,11 @@ +@@ -2525,6 +2736,11 @@ public boolean func_175708_f(BlockPos p_175708_1_, boolean p_175708_2_) { @@ -753,7 +777,7 @@ Biome biome = this.func_180494_b(p_175708_1_); float f = biome.func_180626_a(p_175708_1_); -@@ -2542,7 +2755,7 @@ +@@ -2542,7 +2758,7 @@ { IBlockState iblockstate1 = this.func_180495_p(p_175708_1_); @@ -762,7 +786,7 @@ { return true; } -@@ -2574,10 +2787,10 @@ +@@ -2574,10 +2790,10 @@ else { IBlockState iblockstate1 = this.func_180495_p(p_175638_1_); @@ -776,7 +800,7 @@ { k2 = 1; } -@@ -2589,7 +2802,7 @@ +@@ -2589,7 +2805,7 @@ if (k2 >= 15) { @@ -785,7 +809,7 @@ } else if (j2 >= 14) { -@@ -2630,12 +2843,13 @@ +@@ -2630,12 +2846,13 @@ public boolean func_180500_c(EnumSkyBlock p_180500_1_, BlockPos p_180500_2_) { @@ -800,7 +824,7 @@ int j2 = 0; int k2 = 0; this.field_72984_F.func_76320_a("getBrightness"); -@@ -2673,7 +2887,7 @@ +@@ -2673,7 +2890,7 @@ int l5 = MathHelper.func_76130_a(k4 - k3); int i6 = MathHelper.func_76130_a(l4 - l3); @@ -809,7 +833,7 @@ { BlockPos.PooledMutableBlockPos blockpos$pooledmutableblockpos = BlockPos.PooledMutableBlockPos.func_185346_s(); -@@ -2683,7 +2897,8 @@ +@@ -2683,7 +2900,8 @@ int k6 = k4 + enumfacing.func_96559_d(); int l6 = l4 + enumfacing.func_82599_e(); blockpos$pooledmutableblockpos.func_181079_c(j6, k6, l6); @@ -819,7 +843,7 @@ j5 = this.func_175642_b(p_180500_1_, blockpos$pooledmutableblockpos); if (j5 == i5 - i7 && k2 < this.field_72994_J.length) -@@ -2725,7 +2940,7 @@ +@@ -2725,7 +2943,7 @@ int j9 = Math.abs(i8 - l3); boolean flag = k2 < this.field_72994_J.length - 6; @@ -828,7 +852,7 @@ { if (this.func_175642_b(p_180500_1_, blockpos2.func_177976_e()) < k8) { -@@ -2791,10 +3006,10 @@ +@@ -2791,10 +3009,10 @@ public List func_175674_a(@Nullable Entity p_175674_1_, AxisAlignedBB p_175674_2_, @Nullable Predicate p_175674_3_) { List list = Lists.newArrayList(); @@ -843,7 +867,7 @@ for (int j3 = j2; j3 <= k2; ++j3) { -@@ -2847,10 +3062,10 @@ +@@ -2847,10 +3065,10 @@ public List func_175647_a(Class p_175647_1_, AxisAlignedBB p_175647_2_, @Nullable Predicate p_175647_3_) { @@ -858,7 +882,7 @@ List list = Lists.newArrayList(); for (int j3 = j2; j3 < k2; ++j3) -@@ -2930,11 +3145,13 @@ +@@ -2930,11 +3148,13 @@ public void func_175650_b(Collection p_175650_1_) { @@ -875,7 +899,7 @@ } } -@@ -2958,7 +3175,7 @@ +@@ -2958,7 +3178,7 @@ } else { @@ -884,7 +908,7 @@ } } -@@ -3042,7 +3259,7 @@ +@@ -3042,7 +3262,7 @@ public int func_175651_c(BlockPos p_175651_1_, EnumFacing p_175651_2_) { IBlockState iblockstate1 = this.func_180495_p(p_175651_1_); @@ -893,7 +917,7 @@ } public boolean func_175640_z(BlockPos p_175640_1_) -@@ -3208,6 +3425,8 @@ +@@ -3208,6 +3428,8 @@ d2 *= ((Double)MoreObjects.firstNonNull(p_184150_11_.apply(entityplayer1), Double.valueOf(1.0D))).doubleValue(); } @@ -902,7 +926,7 @@ if ((p_184150_9_ < 0.0D || Math.abs(entityplayer1.field_70163_u - p_184150_3_) < p_184150_9_ * p_184150_9_) && (p_184150_7_ < 0.0D || d1 < d2 * d2) && (d0 == -1.0D || d1 < d0)) { d0 = d1; -@@ -3269,7 +3488,7 @@ +@@ -3269,7 +3491,7 @@ public long func_72905_C() { @@ -911,7 +935,7 @@ } public long func_82737_E() -@@ -3279,17 +3498,17 @@ +@@ -3279,17 +3501,17 @@ public long func_72820_D() { @@ -932,7 +956,7 @@ if (!this.func_175723_af().func_177746_a(blockpos1)) { -@@ -3301,7 +3520,7 @@ +@@ -3301,7 +3523,7 @@ public void func_175652_B(BlockPos p_175652_1_) { @@ -941,7 +965,7 @@ } @SideOnly(Side.CLIENT) -@@ -3321,12 +3540,18 @@ +@@ -3321,12 +3543,18 @@ if (!this.field_72996_f.contains(p_72897_1_)) { @@ -960,7 +984,7 @@ return true; } -@@ -3428,8 +3653,7 @@ +@@ -3428,8 +3656,7 @@ public boolean func_180502_D(BlockPos p_180502_1_) { @@ -970,7 +994,7 @@ } @Nullable -@@ -3490,12 +3714,12 @@ +@@ -3490,12 +3717,12 @@ public int func_72800_K() { @@ -985,7 +1009,7 @@ } public Random func_72843_D(int p_72843_1_, int p_72843_2_, int p_72843_3_) -@@ -3539,7 +3763,7 @@ +@@ -3539,7 +3766,7 @@ @SideOnly(Side.CLIENT) public double func_72919_O() { @@ -994,7 +1018,7 @@ } public void func_175715_c(int p_175715_1_, BlockPos p_175715_2_, int p_175715_3_) -@@ -3573,7 +3797,7 @@ +@@ -3573,7 +3800,7 @@ public void func_175666_e(BlockPos p_175666_1_, Block p_175666_2_) { @@ -1003,7 +1027,7 @@ { BlockPos blockpos1 = p_175666_1_.func_177972_a(enumfacing); -@@ -3581,18 +3805,15 @@ +@@ -3581,18 +3808,15 @@ { IBlockState iblockstate1 = this.func_180495_p(blockpos1); @@ -1026,7 +1050,7 @@ } } } -@@ -3658,6 +3879,124 @@ +@@ -3658,6 +3882,124 @@ return j2 >= -128 && j2 <= 128 && k2 >= -128 && k2 <= 128; } diff --git a/patches/minecraft/net/minecraft/world/chunk/Chunk.java.patch b/patches/minecraft/net/minecraft/world/chunk/Chunk.java.patch index eb15c03a97..75344ada1b 100644 --- a/patches/minecraft/net/minecraft/world/chunk/Chunk.java.patch +++ b/patches/minecraft/net/minecraft/world/chunk/Chunk.java.patch @@ -115,7 +115,7 @@ this.field_76637_e.func_175690_a(p_177436_1_, tileentity1); } -@@ -738,6 +736,7 @@ +@@ -738,11 +736,13 @@ k = this.field_76645_j.length - 1; } @@ -123,7 +123,21 @@ p_76612_1_.field_70175_ag = true; p_76612_1_.field_70176_ah = this.field_76635_g; p_76612_1_.field_70162_ai = k; -@@ -778,7 +777,7 @@ + p_76612_1_.field_70164_aj = this.field_76647_h; + this.field_76645_j[k].add(p_76612_1_); ++ this.func_76630_e(); // Forge - ensure chunks are marked to save after an entity add + } + + public void func_76622_b(Entity p_76622_1_) +@@ -763,6 +763,7 @@ + } + + this.field_76645_j[p_76608_2_].remove(p_76608_1_); ++ this.func_76630_e(); // Forge - ensure chunks are marked to save after entity removals + } + + public boolean func_177444_d(BlockPos p_177444_1_) +@@ -778,7 +779,7 @@ { IBlockState iblockstate = this.func_177435_g(p_177422_1_); Block block = iblockstate.func_177230_c(); @@ -132,7 +146,7 @@ } @Nullable -@@ -786,6 +785,12 @@ +@@ -786,6 +787,12 @@ { TileEntity tileentity = this.field_150816_i.get(p_177424_1_); @@ -145,7 +159,7 @@ if (tileentity == null) { if (p_177424_2_ == Chunk.EnumCreateEntityType.IMMEDIATE) -@@ -795,14 +800,9 @@ +@@ -795,14 +802,9 @@ } else if (p_177424_2_ == Chunk.EnumCreateEntityType.QUEUED) { @@ -161,7 +175,7 @@ return tileentity; } -@@ -819,10 +819,11 @@ +@@ -819,10 +821,11 @@ public void func_177426_a(BlockPos p_177426_1_, TileEntity p_177426_2_) { @@ -174,7 +188,7 @@ { if (this.field_150816_i.containsKey(p_177426_1_)) { -@@ -854,12 +855,14 @@ +@@ -854,12 +857,14 @@ for (ClassInheritanceMultiMap classinheritancemultimap : this.field_76645_j) { @@ -190,7 +204,7 @@ this.field_76636_d = false; for (TileEntity tileentity : this.field_150816_i.values()) -@@ -871,6 +874,7 @@ +@@ -871,6 +876,7 @@ { this.field_76637_e.func_175681_c(classinheritancemultimap); } @@ -198,7 +212,7 @@ } public void func_76630_e() -@@ -880,8 +884,8 @@ +@@ -880,8 +886,8 @@ public void func_177414_a(@Nullable Entity p_177414_1_, AxisAlignedBB p_177414_2_, List p_177414_3_, Predicate p_177414_4_) { @@ -209,7 +223,7 @@ i = MathHelper.func_76125_a(i, 0, this.field_76645_j.length - 1); j = MathHelper.func_76125_a(j, 0, this.field_76645_j.length - 1); -@@ -918,8 +922,8 @@ +@@ -918,8 +924,8 @@ public void func_177430_a(Class p_177430_1_, AxisAlignedBB p_177430_2_, List p_177430_3_, Predicate p_177430_4_) { @@ -220,7 +234,7 @@ i = MathHelper.func_76125_a(i, 0, this.field_76645_j.length - 1); j = MathHelper.func_76125_a(j, 0, this.field_76645_j.length - 1); -@@ -997,6 +1001,9 @@ +@@ -997,6 +1003,9 @@ protected void func_186034_a(IChunkGenerator p_186034_1_) { @@ -230,7 +244,7 @@ if (this.func_177419_t()) { if (p_186034_1_.func_185933_a(this, this.field_76635_g, this.field_76647_h)) -@@ -1008,8 +1015,10 @@ +@@ -1008,8 +1017,10 @@ { this.func_150809_p(); p_186034_1_.func_185931_b(this.field_76635_g, this.field_76647_h); @@ -241,7 +255,7 @@ } public BlockPos func_177440_h(BlockPos p_177440_1_) -@@ -1064,7 +1073,7 @@ +@@ -1064,7 +1075,7 @@ { BlockPos blockpos = this.field_177447_w.poll(); @@ -250,7 +264,7 @@ { TileEntity tileentity = this.func_177422_i(blockpos); this.field_76637_e.func_175690_a(blockpos, tileentity); -@@ -1128,6 +1137,13 @@ +@@ -1128,6 +1139,13 @@ @SideOnly(Side.CLIENT) public void func_186033_a(PacketBuffer p_186033_1_, int p_186033_2_, boolean p_186033_3_) { @@ -264,7 +278,7 @@ boolean flag = this.field_76637_e.field_73011_w.func_191066_m(); for (int i = 0; i < this.field_76652_q.length; ++i) -@@ -1176,10 +1192,16 @@ +@@ -1176,10 +1194,16 @@ this.field_76646_k = true; this.func_76590_a(); @@ -281,7 +295,7 @@ } public Biome func_177411_a(BlockPos p_177411_1_, BiomeProvider p_177411_2_) -@@ -1244,13 +1266,13 @@ +@@ -1244,13 +1268,13 @@ BlockPos blockpos1 = blockpos.func_177982_a(k, (j << 4) + i1, l); boolean flag = i1 == 0 || i1 == 15 || k == 0 || k == 15 || l == 0 || l == 15; @@ -297,7 +311,7 @@ { this.field_76637_e.func_175664_x(blockpos2); } -@@ -1381,7 +1403,7 @@ +@@ -1381,7 +1405,7 @@ { blockpos$mutableblockpos.func_181079_c(blockpos$mutableblockpos.func_177958_n(), l, blockpos$mutableblockpos.func_177952_p()); @@ -306,7 +320,7 @@ { this.field_76637_e.func_175664_x(blockpos$mutableblockpos); } -@@ -1420,6 +1442,7 @@ +@@ -1420,6 +1444,7 @@ else { System.arraycopy(p_177420_1_, 0, this.field_76634_f, 0, this.field_76634_f.length); @@ -314,7 +328,7 @@ } } -@@ -1489,4 +1512,55 @@ +@@ -1489,4 +1514,55 @@ QUEUED, CHECK; }