mirror of
https://github.com/PaperMC/Paper.git
synced 2024-12-13 04:36:53 +01:00
8c5b837e05
Firstly, the old methods all routed to the CompletableFuture method. However, the CF method could not guarantee that if the caller was off-main that the future would be "completed" on-main. Since the callback methods used the CF one, this meant that the callback methods did not guarantee that the callbacks were to be called on the main thread. Now, all methods route to getChunkAtAsync(x, z, gen, urgent, cb) so that the methods with the callback are guaranteed to invoke the callback on the main thread. The CF behavior remains unchanged; it may still appear to complete on main if invoked off-main. Secondly, remove the scheduleOnMain invocation in the async chunk completion. This unnecessarily delays the callback by 1 tick. Thirdly, add getChunksAtAsync(minX, minZ, maxX, maxZ, ...) which will load chunks within an area. This method is provided as a helper as keeping all chunks loaded within an area can be complicated to implement for plugins (due to the lacking ticket API), and is already implemented internally anyways. Fourthly, remove the ticket addition that occured with getChunkAt and getChunkAtAsync. The ticket addition may delay the unloading of the chunk unnecessarily. It also fixes a very rare timing bug where the future/callback would be completed after the chunk unloads.
95 lines
7.0 KiB
Diff
95 lines
7.0 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
|
|
Date: Sat, 30 Dec 2023 15:00:06 -0500
|
|
Subject: [PATCH] Properly handle experience dropping on block break
|
|
|
|
This causes spawnAfterBreak to spawn xp by default, removing the need to manually add xp wherever this method is used.
|
|
For classes that use custom xp amounts, they can drop the resources with disabling
|
|
|
|
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
|
|
index 18c011c1943867dbc4abee338b03b9be499876dd..01fbefdbed48ab85481c811cca532c91860626f7 100644
|
|
--- a/src/main/java/net/minecraft/world/level/Level.java
|
|
+++ b/src/main/java/net/minecraft/world/level/Level.java
|
|
@@ -615,7 +615,8 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
|
if (drop) {
|
|
BlockEntity tileentity = iblockdata.hasBlockEntity() ? this.getBlockEntity(pos) : null;
|
|
|
|
- Block.dropResources(iblockdata, this, pos, tileentity, breakingEntity, ItemStack.EMPTY);
|
|
+ Block.dropResources(iblockdata, this, pos, tileentity, breakingEntity, ItemStack.EMPTY, false); // Paper - Properly handle xp dropping
|
|
+ iblockdata.getBlock().popExperience((ServerLevel) this, pos, xp, breakingEntity); // Paper - Properly handle xp dropping; custom amount
|
|
}
|
|
|
|
boolean flag1 = this.setBlock(pos, fluid.createLegacyBlock(), 3, maxUpdateDepth);
|
|
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 4ff32e3fb1a1979827ef063cda196a43995440fe..dc242451f397ae6a30b830ef1f211f1a066423a4 100644
|
|
--- a/src/main/java/net/minecraft/world/level/block/Block.java
|
|
+++ b/src/main/java/net/minecraft/world/level/block/Block.java
|
|
@@ -302,23 +302,31 @@ public class Block extends BlockBehaviour implements ItemLike {
|
|
for (ItemStack drop : Block.getDrops(state, serverLevel, pos, blockEntity)) {
|
|
items.add(org.bukkit.craftbukkit.inventory.CraftItemStack.asBukkitCopy(drop));
|
|
}
|
|
+ Block block = state.getBlock(); // Paper - Properly handle xp dropping
|
|
io.papermc.paper.event.block.BlockBreakBlockEvent event = new io.papermc.paper.event.block.BlockBreakBlockEvent(org.bukkit.craftbukkit.block.CraftBlock.at(levelAccessor, pos), org.bukkit.craftbukkit.block.CraftBlock.at(levelAccessor, source), items);
|
|
+ event.setExpToDrop(block.getExpDrop(state, serverLevel, pos, net.minecraft.world.item.ItemStack.EMPTY, true)); // Paper - Properly handle xp dropping
|
|
event.callEvent();
|
|
for (org.bukkit.inventory.ItemStack drop : event.getDrops()) {
|
|
popResource(serverLevel, pos, org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(drop));
|
|
}
|
|
- state.spawnAfterBreak(serverLevel, pos, ItemStack.EMPTY, true);
|
|
+ state.spawnAfterBreak(serverLevel, pos, ItemStack.EMPTY, false); // Paper - Properly handle xp dropping
|
|
+ block.popExperience(serverLevel, pos, event.getExpToDrop()); // Paper - Properly handle xp dropping
|
|
}
|
|
return true;
|
|
}
|
|
// Paper end - Add BlockBreakBlockEvent
|
|
|
|
public static void dropResources(BlockState state, Level world, BlockPos pos, @Nullable BlockEntity blockEntity, @Nullable Entity entity, ItemStack tool) {
|
|
+ // Paper start - Properly handle xp dropping
|
|
+ dropResources(state, world, pos, blockEntity, entity, tool, true);
|
|
+ }
|
|
+ public static void dropResources(BlockState state, Level world, BlockPos pos, @Nullable BlockEntity blockEntity, @Nullable Entity entity, ItemStack tool, boolean dropExperience) {
|
|
+ // Paper end - Properly handle xp dropping
|
|
if (world instanceof ServerLevel) {
|
|
Block.getDrops(state, (ServerLevel) world, pos, blockEntity, entity, tool).forEach((itemstack1) -> {
|
|
Block.popResource(world, pos, itemstack1);
|
|
});
|
|
- state.spawnAfterBreak((ServerLevel) world, pos, tool, true);
|
|
+ state.spawnAfterBreak((ServerLevel) world, pos, tool, dropExperience); // Paper - Properly handle xp dropping
|
|
}
|
|
|
|
}
|
|
@@ -406,7 +414,7 @@ public class Block extends BlockBehaviour implements ItemLike {
|
|
player.awardStat(Stats.BLOCK_MINED.get(this));
|
|
player.causeFoodExhaustion(0.005F, org.bukkit.event.entity.EntityExhaustionEvent.ExhaustionReason.BLOCK_MINED); // CraftBukkit - EntityExhaustionEvent
|
|
if (includeDrops) { // Paper - fix drops not preventing stats/food exhaustion
|
|
- Block.dropResources(state, world, pos, blockEntity, player, tool);
|
|
+ Block.dropResources(state, world, pos, blockEntity, player, tool, dropExp); // Paper - Properly handle xp dropping
|
|
} // Paper - fix drops not preventing stats/food exhaustion
|
|
}
|
|
|
|
diff --git a/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java b/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java
|
|
index 0665ca48fe2f8ab1ce1c0306b11be19b06445f74..1b988b92e80faa1ac224caf9f9e955ac43a4c45a 100644
|
|
--- a/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java
|
|
+++ b/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java
|
|
@@ -1180,6 +1180,7 @@ public abstract class BlockBehaviour implements FeatureElement {
|
|
|
|
public void spawnAfterBreak(ServerLevel world, BlockPos pos, ItemStack tool, boolean dropExperience) {
|
|
this.getBlock().spawnAfterBreak(this.asState(), world, pos, tool, dropExperience);
|
|
+ if (dropExperience) {getBlock().popExperience(world, pos, this.getBlock().getExpDrop(asState(), world, pos, tool, true));} // Paper - Properly handle xp dropping
|
|
}
|
|
|
|
public List<ItemStack> getDrops(LootParams.Builder builder) {
|
|
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
|
|
index 6dceb6082538df6f6147254e861d1cec8af7ec50..5cb69d0b822e11a99a96aef4f59986d083b079f4 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
|
|
@@ -509,7 +509,7 @@ public class CraftBlock implements Block {
|
|
|
|
// Modelled off EntityHuman#hasBlock
|
|
if (block != Blocks.AIR && (item == null || !iblockdata.requiresCorrectToolForDrops() || nmsItem.isCorrectToolForDrops(iblockdata))) {
|
|
- net.minecraft.world.level.block.Block.dropResources(iblockdata, this.world.getMinecraftWorld(), this.position, this.world.getBlockEntity(this.position), null, nmsItem);
|
|
+ net.minecraft.world.level.block.Block.dropResources(iblockdata, this.world.getMinecraftWorld(), this.position, this.world.getBlockEntity(this.position), null, nmsItem, false); // Paper - Properly handle xp dropping
|
|
// Paper start - improve Block#breanNaturally
|
|
if (triggerEffect) {
|
|
if (iblockdata.getBlock() instanceof net.minecraft.world.level.block.BaseFireBlock) {
|