From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Thu, 9 May 2019 14:27:37 -0500 Subject: [PATCH] Silk touch spawners diff --git a/src/main/java/io/papermc/paper/adventure/PaperAdventure.java b/src/main/java/io/papermc/paper/adventure/PaperAdventure.java index f63b80a1120b2bf5f77f1c1edb928309a1272f79..363f94e86e3349d9ed03b692e136307fe9fa5e28 100644 --- a/src/main/java/io/papermc/paper/adventure/PaperAdventure.java +++ b/src/main/java/io/papermc/paper/adventure/PaperAdventure.java @@ -80,6 +80,7 @@ public final class PaperAdventure { }) .build(); public static final LegacyComponentSerializer LEGACY_SECTION_UXRC = LegacyComponentSerializer.builder().flattener(FLATTENER).hexColors().useUnusualXRepeatedCharacterHexFormat().build(); + public static final LegacyComponentSerializer LEGACY_AMPERSAND = LegacyComponentSerializer.builder().character(LegacyComponentSerializer.AMPERSAND_CHAR).hexColors().build(); // Purpur public static final PlainComponentSerializer PLAIN = PlainComponentSerializer.builder().flattener(FLATTENER).build(); public static final GsonComponentSerializer GSON = GsonComponentSerializer.builder() .legacyHoverEventSerializer(NBTLegacyHoverEventSerializer.INSTANCE) diff --git a/src/main/java/net/minecraft/world/item/Items.java b/src/main/java/net/minecraft/world/item/Items.java index f68639508d7ff9a0e743b5282301e62435d53656..89d4b7e4cd4222b61b49833fceda56ffa39710fa 100644 --- a/src/main/java/net/minecraft/world/item/Items.java +++ b/src/main/java/net/minecraft/world/item/Items.java @@ -258,7 +258,7 @@ public class Items { public static final Item PURPUR_BLOCK = registerBlock(Blocks.PURPUR_BLOCK, CreativeModeTab.TAB_BUILDING_BLOCKS); public static final Item PURPUR_PILLAR = registerBlock(Blocks.PURPUR_PILLAR, CreativeModeTab.TAB_BUILDING_BLOCKS); public static final Item PURPUR_STAIRS = registerBlock(Blocks.PURPUR_STAIRS, CreativeModeTab.TAB_BUILDING_BLOCKS); - public static final Item SPAWNER = registerBlock(new BlockItem(Blocks.SPAWNER, (new Item.Properties()).rarity(Rarity.EPIC))); + public static final Item SPAWNER = registerBlock(Blocks.SPAWNER, new net.pl3x.purpur.item.SpawnerItem(Blocks.SPAWNER, new Item.Properties().rarity(Rarity.EPIC))); // Purpur public static final Item OAK_STAIRS = registerBlock(Blocks.OAK_STAIRS, CreativeModeTab.TAB_BUILDING_BLOCKS); public static final Item CHEST = registerBlock(Blocks.CHEST, CreativeModeTab.TAB_DECORATIONS); public static final Item CRAFTING_TABLE = registerBlock(Blocks.CRAFTING_TABLE, CreativeModeTab.TAB_DECORATIONS); diff --git a/src/main/java/net/minecraft/world/level/block/SpawnerBlock.java b/src/main/java/net/minecraft/world/level/block/SpawnerBlock.java index b1e04d41de80971a7a1616beb0860226ecc25045..295ae3877b955978105b756055c21e63cf3b84ab 100644 --- a/src/main/java/net/minecraft/world/level/block/SpawnerBlock.java +++ b/src/main/java/net/minecraft/world/level/block/SpawnerBlock.java @@ -2,8 +2,16 @@ package net.minecraft.world.level.block; import javax.annotation.Nullable; import net.minecraft.core.BlockPos; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.ListTag; +import net.minecraft.nbt.StringTag; +import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.enchantment.EnchantmentHelper; +import net.minecraft.world.item.enchantment.Enchantments; import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.entity.BlockEntity; @@ -13,6 +21,18 @@ import net.minecraft.world.level.block.entity.SpawnerBlockEntity; import net.minecraft.world.level.block.state.BlockBehaviour; import net.minecraft.world.level.block.state.BlockState; +// Purpur start +import io.papermc.paper.adventure.PaperAdventure; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.TextReplacementConfig; +import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; +import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; + +import java.util.List; + +import static net.kyori.adventure.text.format.TextDecoration.ITALIC; +// Purpur end + public class SpawnerBlock extends BaseEntityBlock { protected SpawnerBlock(BlockBehaviour.Properties settings) { @@ -30,6 +50,59 @@ public class SpawnerBlock extends BaseEntityBlock { return createTickerHelper(type, BlockEntityType.MOB_SPAWNER, world.isClientSide ? SpawnerBlockEntity::clientTick : SpawnerBlockEntity::serverTick); } + // Purpur start + @Override + public void playerDestroy(Level level, Player player, BlockPos pos, BlockState state, BlockEntity blockEntity, ItemStack stack) { + if (level.purpurConfig.silkTouchEnabled && player.getBukkitEntity().hasPermission("purpur.drop.spawners") && isSilkTouch(level, stack)) { + ResourceLocation type = ((SpawnerBlockEntity) blockEntity).getSpawner().getEntityId(level, pos); + if (type != null) { + final Component mobName = PaperAdventure.asAdventure(EntityType.getFromKey(type).getDescription()); + final TextReplacementConfig config = TextReplacementConfig.builder() + .matchLiteral("{mob}") + .replacement(mobName) + .build(); + + CompoundTag display = new CompoundTag(); + boolean customDisplay = false; + + String name = level.purpurConfig.silkTouchSpawnerName; + if (name != null && !name.isEmpty() && !name.equals("Spawner")) { + final Component displayName = PaperAdventure.LEGACY_AMPERSAND.deserialize(name).replaceText(config).decoration(ITALIC, false); + display.put("Name", StringTag.valueOf(GsonComponentSerializer.gson().serialize(displayName))); + customDisplay = true; + } + + List lore = level.purpurConfig.silkTouchSpawnerLore; + if (lore != null && !lore.isEmpty()) { + ListTag list = new ListTag(); + for (String line : lore) { + final Component lineComponent = PaperAdventure.LEGACY_AMPERSAND.deserialize(line).replaceText(config).decoration(ITALIC, false); + list.add(StringTag.valueOf(GsonComponentSerializer.gson().serialize(lineComponent))); + } + display.put("Lore", list); + customDisplay = true; + } + + CompoundTag tag = new CompoundTag(); + if (customDisplay) { + tag.put("display", display); + } + tag.putString("Purpur.mob_type", type.toString()); + + ItemStack item = new ItemStack(Blocks.SPAWNER.asItem()); + item.setTag(tag); + + popResource(level, pos, item); + } + } + super.playerDestroy(level, player, pos, state, blockEntity, stack); + } + + private boolean isSilkTouch(Level level, ItemStack stack) { + return stack != null && level.purpurConfig.silkTouchTools.contains(stack.getItem()) && EnchantmentHelper.getItemEnchantmentLevel(Enchantments.SILK_TOUCH, stack) >= level.purpurConfig.minimumSilkTouchSpawnerRequire; + } + // Purpur end + @Override public void spawnAfterBreak(BlockState state, ServerLevel world, BlockPos pos, ItemStack stack) { super.spawnAfterBreak(state, world, pos, stack); @@ -42,6 +115,7 @@ public class SpawnerBlock extends BaseEntityBlock { @Override public int getExpDrop(BlockState iblockdata, ServerLevel worldserver, BlockPos blockposition, ItemStack itemstack) { + if (isSilkTouch(worldserver, itemstack)) return 0; // Purpur int i = 15 + worldserver.random.nextInt(15) + worldserver.random.nextInt(15); return i; diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java index a4abc312a9c173fb6a4374c97012abc43c801b7a..48670fd7e51c39e207d95059261c09d52f309db6 100644 --- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java @@ -115,6 +115,31 @@ public class PurpurWorldConfig { playerInvulnerableWhileAcceptingResourcePack = getBoolean("gameplay-mechanics.player.invulnerable-while-accepting-resource-pack", playerInvulnerableWhileAcceptingResourcePack); } + public boolean silkTouchEnabled = false; + public String silkTouchSpawnerName = "Spawner"; + public List silkTouchSpawnerLore = new ArrayList<>(); + public List silkTouchTools = new ArrayList<>(); + public int minimumSilkTouchSpawnerRequire = 1; + private void silkTouchSettings() { + silkTouchEnabled = getBoolean("gameplay-mechanics.silk-touch.enabled", silkTouchEnabled); + silkTouchSpawnerName = getString("gameplay-mechanics.silk-touch.spawner-name", silkTouchSpawnerName); + minimumSilkTouchSpawnerRequire = getInt("gameplay-mechanics.silk-touch.minimal-level", minimumSilkTouchSpawnerRequire); + silkTouchSpawnerLore.clear(); + getList("gameplay-mechanics.silk-touch.spawner-lore", new ArrayList(){{ + add("Spawns a {mob}"); + }}).forEach(line -> silkTouchSpawnerLore.add(line.toString())); + silkTouchTools.clear(); + getList("gameplay-mechanics.silk-touch.tools", new ArrayList(){{ + add("minecraft:iron_pickaxe"); + add("minecraft:golden_pickaxe"); + add("minecraft:diamond_pickaxe"); + add("minecraft:netherite_pickaxe"); + }}).forEach(key -> { + Item item = Registry.ITEM.get(new ResourceLocation(key.toString())); + if (item != Items.AIR) silkTouchTools.add(item); + }); + } + public boolean babiesAreRidable = true; public boolean untamedTamablesAreRidable = true; public boolean useNightVisionWhenRiding = false; diff --git a/src/main/java/net/pl3x/purpur/item/SpawnerItem.java b/src/main/java/net/pl3x/purpur/item/SpawnerItem.java new file mode 100644 index 0000000000000000000000000000000000000000..728da3d75ec957ee789f9625483565e38649acd5 --- /dev/null +++ b/src/main/java/net/pl3x/purpur/item/SpawnerItem.java @@ -0,0 +1,36 @@ +package net.pl3x.purpur.item; + +import net.minecraft.core.BlockPos; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.BlockItem; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.entity.SpawnerBlockEntity; +import net.minecraft.world.level.block.state.BlockState; + +public class SpawnerItem extends BlockItem { + + public SpawnerItem(Block block, Properties settings) { + super(block, settings); + } + + @Override + protected boolean updateCustomBlockEntityTag(BlockPos pos, Level level, Player player, ItemStack stack, BlockState state) { + boolean handled = super.updateCustomBlockEntityTag(pos, level, player, stack, state); + if (level.purpurConfig.silkTouchEnabled && player.getBukkitEntity().hasPermission("purpur.place.spawners")) { + BlockEntity spawner = level.getBlockEntity(pos); + if (spawner instanceof SpawnerBlockEntity && stack.hasTag()) { + CompoundTag tag = stack.getTag(); + if (tag.contains("Purpur.mob_type")) { + EntityType.byString(tag.getString("Purpur.mob_type")).ifPresent(type -> + ((SpawnerBlockEntity) spawner).getSpawner().setEntityId(type)); + } + } + } + return handled; + } +}