From 802a6593ab820884eb35d7710a96bb230e105a75 Mon Sep 17 00:00:00 2001 From: jmp Date: Fri, 2 Oct 2020 13:54:16 -0700 Subject: [PATCH] Persistent TileEntity Lore & DisplayName --- ...tent-TileEntity-Lore-and-DisplayName.patch | 181 ++++++++++++++++++ 1 file changed, 181 insertions(+) create mode 100644 patches/server/0130-Persistent-TileEntity-Lore-and-DisplayName.patch diff --git a/patches/server/0130-Persistent-TileEntity-Lore-and-DisplayName.patch b/patches/server/0130-Persistent-TileEntity-Lore-and-DisplayName.patch new file mode 100644 index 000000000..6572cea85 --- /dev/null +++ b/patches/server/0130-Persistent-TileEntity-Lore-and-DisplayName.patch @@ -0,0 +1,181 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: jmp +Date: Wed, 30 Sep 2020 14:32:46 -0700 +Subject: [PATCH] Persistent TileEntity Lore and DisplayName + +Makes it so that when a TileEntity is placed in the world and then broken, +the dropped ItemStack retains any original custom display name/lore. + +diff --git a/src/main/java/net/minecraft/server/Block.java b/src/main/java/net/minecraft/server/Block.java +index 4aa2b38f1..f86390999 100644 +--- a/src/main/java/net/minecraft/server/Block.java ++++ b/src/main/java/net/minecraft/server/Block.java +@@ -207,6 +207,7 @@ public class Block extends BlockBase implements IMaterial { + public static void a(IBlockData iblockdata, GeneratorAccess generatoraccess, BlockPosition blockposition, @Nullable TileEntity tileentity) { + if (generatoraccess instanceof WorldServer) { + a(iblockdata, (WorldServer) generatoraccess, blockposition, tileentity).forEach((itemstack) -> { ++ itemstack = applyDisplayNameAndLoreFromTile(itemstack, tileentity); // Purpur + a((World) ((WorldServer) generatoraccess), blockposition, itemstack); + }); + iblockdata.dropNaturally((WorldServer) generatoraccess, blockposition, ItemStack.b); +@@ -217,6 +218,7 @@ public class Block extends BlockBase implements IMaterial { + public static void dropItems(IBlockData iblockdata, World world, BlockPosition blockposition, @Nullable TileEntity tileentity, Entity entity, ItemStack itemstack) { + if (world instanceof WorldServer) { + getDrops(iblockdata, (WorldServer) world, blockposition, tileentity, entity, itemstack).forEach((itemstack1) -> { ++ itemstack1 = applyDisplayNameAndLoreFromTile(itemstack1, tileentity); // Purpur + a(world, blockposition, itemstack1); + }); + iblockdata.dropNaturally((WorldServer) world, blockposition, itemstack); +@@ -224,6 +226,46 @@ public class Block extends BlockBase implements IMaterial { + + } + ++ // Purpur start ++ private static ItemStack applyDisplayNameAndLoreFromTile(ItemStack itemStack, TileEntity tile) { ++ if (itemStack.getItem() instanceof ItemBlock) { ++ if (tile != null && tile.getWorld() instanceof WorldServer && tile.getWorld().purpurConfig.persistentTileEntityDisplayNames) { ++ String name = tile.getPersistentDisplayName(); ++ NBTTagList lore = tile.getPersistentLore(); ++ if (tile instanceof INamableTileEntity) { ++ INamableTileEntity namedTile = (INamableTileEntity) tile; ++ if (namedTile.hasCustomName()) { ++ name = IChatBaseComponent.ChatSerializer.componentToJson(namedTile.getCustomName()); ++ } ++ } ++ ++ if (name != null || lore != null) { ++ NBTTagCompound display = itemStack.getSubTag("display"); ++ if (display == null) { ++ display = new NBTTagCompound(); ++ } ++ ++ if (name != null) { ++ display.set("Name", NBTTagString.create(name)); ++ } ++ if (lore != null) { ++ display.set("Lore", lore); ++ } ++ ++ NBTTagCompound tag = itemStack.getTag(); ++ if (tag == null) { ++ tag = new NBTTagCompound(); ++ } ++ tag.set("display", display); ++ ++ itemStack.setTag(tag); ++ } ++ } ++ } ++ return itemStack; ++ } ++ // Purpur end ++ + public static void dropItem(World world, BlockPosition blockposition, ItemStack itemstack) { a(world, blockposition, itemstack); } // Purpur - OBFHELPER + public static void a(World world, BlockPosition blockposition, ItemStack itemstack) { + if (!world.isClientSide && !itemstack.isEmpty() && world.getGameRules().getBoolean(GameRules.DO_TILE_DROPS)) { +diff --git a/src/main/java/net/minecraft/server/ItemBlock.java b/src/main/java/net/minecraft/server/ItemBlock.java +index bbb1de7d1..d97efe3d4 100644 +--- a/src/main/java/net/minecraft/server/ItemBlock.java ++++ b/src/main/java/net/minecraft/server/ItemBlock.java +@@ -96,7 +96,24 @@ public class ItemBlock extends Item { + } + + protected boolean a(BlockPosition blockposition, World world, @Nullable EntityHuman entityhuman, ItemStack itemstack, IBlockData iblockdata) { +- return a(world, entityhuman, blockposition, itemstack); ++ // Purpur start ++ boolean handled = a(world, entityhuman, blockposition, itemstack); ++ if (world.purpurConfig.persistentTileEntityDisplayNames && itemstack.hasTag()) { ++ NBTTagCompound display = itemstack.getSubTag("display"); ++ if (display != null) { ++ TileEntity tile = world.getTileEntity(blockposition); ++ if (tile != null) { ++ if (display.hasKeyOfType("Name", 8)) { ++ tile.setPersistentDisplayName(display.getString("Name")); ++ } ++ if (display.hasKeyOfType("Lore", 9)) { ++ tile.setPersistentLore(display.getList("Lore", 8)); ++ } ++ } ++ } ++ } ++ return handled; ++ // Purpur end + } + + @Nullable +diff --git a/src/main/java/net/minecraft/server/TileEntity.java b/src/main/java/net/minecraft/server/TileEntity.java +index d32540c88..13460df02 100644 +--- a/src/main/java/net/minecraft/server/TileEntity.java ++++ b/src/main/java/net/minecraft/server/TileEntity.java +@@ -90,9 +90,25 @@ public abstract class TileEntity implements KeyedObject { // Paper + this.persistentDataContainer.putAll(persistentDataTag); + } + // CraftBukkit end ++ // Purpur start ++ if (nbttagcompound.hasKey("Purpur.persistentDisplayName")) { ++ this.persistentDisplayName = nbttagcompound.getString("Purpur.persistentDisplayName"); ++ } ++ if (nbttagcompound.hasKey("Purpur.persistentLore")) { ++ this.persistentLore = nbttagcompound.getList("Purpur.persistentLore", 8); ++ } ++ // Purpur end + } + + public NBTTagCompound save(NBTTagCompound nbttagcompound) { ++ // Purpur start ++ if (this.persistentDisplayName != null) { ++ nbttagcompound.set("Purpur.persistentDisplayName", NBTTagString.create(this.persistentDisplayName)); ++ } ++ if (this.persistentLore != null) { ++ nbttagcompound.set("Purpur.persistentLore", this.persistentLore); ++ } ++ // Purpur end + return this.b(nbttagcompound); + } + +@@ -253,4 +269,25 @@ public abstract class TileEntity implements KeyedObject { // Paper + return null; + } + // CraftBukkit end ++ ++ // Purpur start ++ private String persistentDisplayName = null; ++ private NBTTagList persistentLore = null; ++ ++ public void setPersistentDisplayName(String json) { ++ this.persistentDisplayName = json; ++ } ++ ++ public void setPersistentLore(NBTTagList lore) { ++ this.persistentLore = lore; ++ } ++ ++ public String getPersistentDisplayName() { ++ return this.persistentDisplayName; ++ } ++ ++ public NBTTagList getPersistentLore() { ++ return this.persistentLore; ++ } ++ // Purpur end + } +diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +index 67b899667..68ae62477 100644 +--- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java ++++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +@@ -182,6 +182,7 @@ public class PurpurWorldConfig { + public boolean fixClimbingBypassingCrammingRule = false; + public boolean milkCuresBadOmen = true; + public boolean saveProjectilesToDisk = true; ++ public boolean persistentTileEntityDisplayNames = false; + public double tridentLoyaltyVoidReturnHeight = 0.0D; + public double voidDamageHeight = -64.0D; + public int raidCooldownSeconds = 0; +@@ -194,6 +195,7 @@ public class PurpurWorldConfig { + fixClimbingBypassingCrammingRule = getBoolean("gameplay-mechanics.fix-climbing-bypassing-cramming-rule", fixClimbingBypassingCrammingRule); + milkCuresBadOmen = getBoolean("gameplay-mechanics.milk-cures-bad-omen", milkCuresBadOmen); + saveProjectilesToDisk = getBoolean("gameplay-mechanics.save-projectiles-to-disk", saveProjectilesToDisk); ++ persistentTileEntityDisplayNames = getBoolean("gameplay-mechanics.persistent-tileentity-display-names-and-lore", persistentTileEntityDisplayNames); + tridentLoyaltyVoidReturnHeight = getDouble("gameplay-mechanics.trident-loyalty-void-return-height", tridentLoyaltyVoidReturnHeight); + voidDamageHeight = getDouble("gameplay-mechanics.void-damage-height", voidDamageHeight); + raidCooldownSeconds = getInt("gameplay-mechanics.raid-cooldown-seconds", raidCooldownSeconds);