LootTable API and replenishable lootables
Provides an API to control the loot table for an object. Also provides a feature that any Lootable Inventory (Chests in Structures) can automatically replenish after a given time. This feature is good for long term worlds so that newer players do not suffer with "Every chest has been looted" == AT == public org.bukkit.craftbukkit.block.CraftBlockEntityState getTileEntity()Lnet/minecraft/world/level/block/entity/BlockEntity; public org.bukkit.craftbukkit.block.CraftLootable setLootTable(Lorg/bukkit/loot/LootTable;J)V public org.bukkit.craftbukkit.entity.CraftMinecartContainer setLootTable(Lorg/bukkit/loot/LootTable;J)V
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
--- a/net/minecraft/world/level/block/ShulkerBoxBlock.java
|
||||
+++ b/net/minecraft/world/level/block/ShulkerBoxBlock.java
|
||||
@@ -137,7 +137,7 @@
|
||||
itemEntity.setDefaultPickUpDelay();
|
||||
world.addFreshEntity(itemEntity);
|
||||
} else {
|
||||
- shulkerBoxBlockEntity.unpackLootTable(player);
|
||||
+ shulkerBoxBlockEntity.unpackLootTable(player, true); // Paper - force clear loot table so replenish data isn't persisted in the stack
|
||||
}
|
||||
}
|
||||
|
||||
@@ -147,7 +147,15 @@
|
||||
@Override
|
||||
protected List<ItemStack> getDrops(BlockState state, LootParams.Builder builder) {
|
||||
BlockEntity blockEntity = builder.getOptionalParameter(LootContextParams.BLOCK_ENTITY);
|
||||
+ Runnable reAdd = null; // Paper
|
||||
if (blockEntity instanceof ShulkerBoxBlockEntity shulkerBoxBlockEntity) {
|
||||
+ // Paper start - clear loot table if it was already used
|
||||
+ if (shulkerBoxBlockEntity.lootableData().getLastFill() != -1 || !builder.getLevel().paperConfig().lootables.retainUnlootedShulkerBoxLootTableOnNonPlayerBreak) {
|
||||
+ net.minecraft.resources.ResourceKey<net.minecraft.world.level.storage.loot.LootTable> lootTableResourceKey = shulkerBoxBlockEntity.getLootTable();
|
||||
+ reAdd = () -> shulkerBoxBlockEntity.setLootTable(lootTableResourceKey);
|
||||
+ shulkerBoxBlockEntity.setLootTable(null);
|
||||
+ }
|
||||
+ // Paper end
|
||||
builder = builder.withDynamicDrop(CONTENTS, lootConsumer -> {
|
||||
for (int i = 0; i < shulkerBoxBlockEntity.getContainerSize(); i++) {
|
||||
lootConsumer.accept(shulkerBoxBlockEntity.getItem(i));
|
||||
@@ -155,7 +163,13 @@
|
||||
});
|
||||
}
|
||||
|
||||
+ // Paper start - re-set loot table if it was cleared
|
||||
+ try {
|
||||
return super.getDrops(state, builder);
|
||||
+ } finally {
|
||||
+ if (reAdd != null) reAdd.run();
|
||||
+ }
|
||||
+ // Paper end - re-set loot table if it was cleared
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -0,0 +1,16 @@
|
||||
--- a/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java
|
||||
+++ b/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java
|
||||
@@ -115,4 +115,13 @@
|
||||
nbt.remove("LootTable");
|
||||
nbt.remove("LootTableSeed");
|
||||
}
|
||||
+
|
||||
+ // Paper start - LootTable API
|
||||
+ final com.destroystokyo.paper.loottable.PaperLootableInventoryData lootableData = new com.destroystokyo.paper.loottable.PaperLootableInventoryData(); // Paper
|
||||
+
|
||||
+ @Override
|
||||
+ public com.destroystokyo.paper.loottable.PaperLootableInventoryData lootableData() {
|
||||
+ return this.lootableData;
|
||||
+ }
|
||||
+ // Paper end - LootTable API
|
||||
}
|
||||
Reference in New Issue
Block a user