mirror of
https://github.com/PaperMC/Paper.git
synced 2025-01-02 17:32:03 +01:00
07c767b6f4
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
92 lines
4.6 KiB
Diff
92 lines
4.6 KiB
Diff
--- a/net/minecraft/world/RandomizableContainer.java
|
|
+++ b/net/minecraft/world/RandomizableContainer.java
|
|
@@ -28,7 +28,7 @@
|
|
|
|
void setLootTable(@Nullable ResourceKey<LootTable> lootTable);
|
|
|
|
- default void setLootTable(ResourceKey<LootTable> lootTableId, long lootTableSeed) {
|
|
+ default void setLootTable(@Nullable ResourceKey<LootTable> lootTableId, long lootTableSeed) { // Paper - add nullable
|
|
this.setLootTable(lootTableId);
|
|
this.setLootTableSeed(lootTableSeed);
|
|
}
|
|
@@ -51,13 +51,14 @@
|
|
default boolean tryLoadLootTable(CompoundTag nbt) {
|
|
if (nbt.contains("LootTable", 8)) {
|
|
this.setLootTable(ResourceKey.create(Registries.LOOT_TABLE, ResourceLocation.parse(nbt.getString("LootTable"))));
|
|
+ if (this.lootableData() != null && this.getLootTable() != null) this.lootableData().loadNbt(nbt); // Paper - LootTable API
|
|
if (nbt.contains("LootTableSeed", 4)) {
|
|
this.setLootTableSeed(nbt.getLong("LootTableSeed"));
|
|
} else {
|
|
this.setLootTableSeed(0L);
|
|
}
|
|
|
|
- return true;
|
|
+ return this.lootableData() == null; // Paper - only track the loot table if there is chance for replenish
|
|
} else {
|
|
return false;
|
|
}
|
|
@@ -69,26 +70,44 @@
|
|
return false;
|
|
} else {
|
|
nbt.putString("LootTable", resourceKey.location().toString());
|
|
+ if (this.lootableData() != null) this.lootableData().saveNbt(nbt); // Paper - LootTable API
|
|
long l = this.getLootTableSeed();
|
|
if (l != 0L) {
|
|
nbt.putLong("LootTableSeed", l);
|
|
}
|
|
|
|
- return true;
|
|
+ return this.lootableData() == null; // Paper - only track the loot table if there is chance for replenish
|
|
}
|
|
}
|
|
|
|
default void unpackLootTable(@Nullable Player player) {
|
|
+ // Paper start - LootTable API
|
|
+ this.unpackLootTable(player, false);
|
|
+ }
|
|
+ default void unpackLootTable(@Nullable final Player player, final boolean forceClearLootTable) {
|
|
+ // Paper end - LootTable API
|
|
Level level = this.getLevel();
|
|
BlockPos blockPos = this.getBlockPos();
|
|
ResourceKey<LootTable> resourceKey = this.getLootTable();
|
|
- if (resourceKey != null && level != null && level.getServer() != null) {
|
|
+ // Paper start - LootTable API
|
|
+ lootReplenish: if (resourceKey != null && level != null && level.getServer() != null) {
|
|
+ if (this.lootableData() != null && !this.lootableData().shouldReplenish(this, com.destroystokyo.paper.loottable.PaperLootableInventoryData.CONTAINER, player)) {
|
|
+ if (forceClearLootTable) {
|
|
+ this.setLootTable(null);
|
|
+ }
|
|
+ break lootReplenish;
|
|
+ }
|
|
+ // Paper end - LootTable API
|
|
LootTable lootTable = level.getServer().reloadableRegistries().getLootTable(resourceKey);
|
|
if (player instanceof ServerPlayer) {
|
|
CriteriaTriggers.GENERATE_LOOT.trigger((ServerPlayer)player, resourceKey);
|
|
}
|
|
|
|
- this.setLootTable(null);
|
|
+ // Paper start - LootTable API
|
|
+ if (forceClearLootTable || this.lootableData() == null || this.lootableData().shouldClearLootTable(this, com.destroystokyo.paper.loottable.PaperLootableInventoryData.CONTAINER, player)) {
|
|
+ this.setLootTable(null);
|
|
+ }
|
|
+ // Paper end - LootTable API
|
|
LootParams.Builder builder = new LootParams.Builder((ServerLevel)level).withParameter(LootContextParams.ORIGIN, Vec3.atCenterOf(blockPos));
|
|
if (player != null) {
|
|
builder.withLuck(player.getLuck()).withParameter(LootContextParams.THIS_ENTITY, player);
|
|
@@ -97,4 +116,16 @@
|
|
lootTable.fill(this, builder.create(LootContextParamSets.CHEST), this.getLootTableSeed());
|
|
}
|
|
}
|
|
+
|
|
+ // Paper start - LootTable API
|
|
+ @Nullable @org.jetbrains.annotations.Contract(pure = true)
|
|
+ default com.destroystokyo.paper.loottable.PaperLootableInventoryData lootableData() {
|
|
+ return null; // some containers don't really have a "replenish" ability like decorated pots
|
|
+ }
|
|
+
|
|
+ default com.destroystokyo.paper.loottable.PaperLootableInventory getLootableInventory() {
|
|
+ final org.bukkit.block.Block block = org.bukkit.craftbukkit.block.CraftBlock.at(java.util.Objects.requireNonNull(this.getLevel(), "Cannot manage loot tables on block entities not in world"), this.getBlockPos());
|
|
+ return (com.destroystokyo.paper.loottable.PaperLootableInventory) block.getState(false);
|
|
+ }
|
|
+ // Paper end - LootTable API
|
|
}
|