-
-
Notifications
You must be signed in to change notification settings - Fork 479
Expand file tree
/
Copy path0020-Silk-touch-spawners.patch
More file actions
179 lines (173 loc) · 11 KB
/
Copy path0020-Silk-touch-spawners.patch
File metadata and controls
179 lines (173 loc) · 11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <blake.galbreath@gmail.com>
Date: Thu, 9 May 2019 14:27:37 -0500
Subject: [PATCH] Silk touch spawners
diff --git a/src/main/java/net/minecraft/world/item/Items.java b/src/main/java/net/minecraft/world/item/Items.java
index f692149d91b525bda6dc79d489d7496ea24037e8..7fbd4bf29bcc0795aa4b0e6d5d4bc3745bf7a1c0 100644
--- a/src/main/java/net/minecraft/world/item/Items.java
+++ b/src/main/java/net/minecraft/world/item/Items.java
@@ -316,7 +316,7 @@ public class Items {
public static final Item PURPUR_BLOCK = registerBlock(Blocks.PURPUR_BLOCK);
public static final Item PURPUR_PILLAR = registerBlock(Blocks.PURPUR_PILLAR);
public static final Item PURPUR_STAIRS = registerBlock(Blocks.PURPUR_STAIRS);
- public static final Item SPAWNER = registerBlock(Blocks.SPAWNER);
+ public static final Item SPAWNER = registerBlock(new org.purpurmc.purpur.item.SpawnerItem(Blocks.SPAWNER, new Item.Properties().rarity(Rarity.EPIC))); // Purpur
public static final Item CHEST = registerBlock(Blocks.CHEST);
public static final Item CRAFTING_TABLE = registerBlock(Blocks.CRAFTING_TABLE);
public static final Item FARMLAND = registerBlock(Blocks.FARMLAND);
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 e8b1c44da90f60cde20cda65aba2aa1e30f89d25..1ac38424a44aa2225b9bd3fa0fbbe61b7b24875c 100644
--- a/src/main/java/net/minecraft/world/level/block/SpawnerBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/SpawnerBlock.java
@@ -42,6 +42,60 @@ 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, net.minecraft.world.entity.player.Player player, BlockPos pos, BlockState state, @Nullable BlockEntity blockEntity, ItemStack stack, boolean includeDrops, boolean dropExp) {
+ if (level.purpurConfig.silkTouchEnabled && player.getBukkitEntity().hasPermission("purpur.drop.spawners") && isSilkTouch(level, stack)) {
+ java.util.Optional<net.minecraft.world.entity.EntityType<?>> type = net.minecraft.world.entity.EntityType.by(((SpawnerBlockEntity) blockEntity).getSpawner().nextSpawnData.getEntityToSpawn());
+
+ net.minecraft.world.entity.EntityType<?> entityType = type.orElse(null);
+ final net.kyori.adventure.text.Component mobName = io.papermc.paper.adventure.PaperAdventure.asAdventure(entityType == null ? Component.empty() : entityType.getDescription());
+ net.minecraft.nbt.CompoundTag display = new net.minecraft.nbt.CompoundTag();
+ net.minecraft.nbt.CompoundTag tag = new net.minecraft.nbt.CompoundTag();
+ net.minecraft.nbt.CompoundTag blockEntityTag = blockEntity.getUpdateTag();
+ blockEntityTag.remove("Delay"); // remove this tag to allow stacking duplicate spawners
+ tag.put("BlockEntityTag", blockEntityTag);
+
+ String name = level.purpurConfig.silkTouchSpawnerName;
+ if (name != null && !name.isEmpty() && !name.equals("Monster Spawner")) {
+ net.kyori.adventure.text.Component displayName = net.kyori.adventure.text.minimessage.MiniMessage.miniMessage().deserialize(name, net.kyori.adventure.text.minimessage.tag.resolver.Placeholder.component("mob", mobName));
+ if (name.startsWith("<reset>")) {
+ displayName = displayName.decoration(net.kyori.adventure.text.format.TextDecoration.ITALIC, false);
+ }
+ display.put("Name", net.minecraft.nbt.StringTag.valueOf(io.papermc.paper.adventure.PaperAdventure.asJsonString(displayName, java.util.Locale.ROOT)));
+ tag.put("display", display);
+ }
+
+ List<String> lore = level.purpurConfig.silkTouchSpawnerLore;
+ if (lore != null && !lore.isEmpty()) {
+ net.minecraft.nbt.ListTag list = new net.minecraft.nbt.ListTag();
+ for (String line : lore) {
+ net.kyori.adventure.text.Component lineComponent = net.kyori.adventure.text.minimessage.MiniMessage.miniMessage().deserialize(line, net.kyori.adventure.text.minimessage.tag.resolver.Placeholder.component("mob", mobName));
+ if (line.startsWith("<reset>")) {
+ lineComponent = lineComponent.decoration(net.kyori.adventure.text.format.TextDecoration.ITALIC, false);
+ }
+ list.add(net.minecraft.nbt.StringTag.valueOf(io.papermc.paper.adventure.PaperAdventure.asJsonString(lineComponent, java.util.Locale.ROOT)));
+ }
+ display.put("Lore", list);
+ tag.put("display", display);
+ }
+
+ ItemStack item = new ItemStack(Blocks.SPAWNER.asItem());
+ if (entityType != null) {
+ tag.putDouble("HideFlags", ItemStack.TooltipPart.ADDITIONAL.getMask()); // hides the "Interact with Spawn Egg" tooltip
+ item.setTag(tag);
+ }
+
+ popResource(level, pos, item);
+ }
+ super.playerDestroy(level, player, pos, state, blockEntity, stack, includeDrops, dropExp);
+ }
+
+ private boolean isSilkTouch(Level level, ItemStack stack) {
+ return stack != null && level.purpurConfig.silkTouchTools.contains(stack.getItem()) && net.minecraft.world.item.enchantment.EnchantmentHelper.getItemEnchantmentLevel(net.minecraft.world.item.enchantment.Enchantments.SILK_TOUCH, stack) >= level.purpurConfig.minimumSilkTouchSpawnerRequire;
+ }
+ // Purpur end
+
@Override
public void spawnAfterBreak(BlockState state, ServerLevel world, BlockPos pos, ItemStack tool, boolean dropExperience) {
super.spawnAfterBreak(state, world, pos, tool, dropExperience);
@@ -50,6 +104,7 @@ public class SpawnerBlock extends BaseEntityBlock {
@Override
public int getExpDrop(BlockState iblockdata, ServerLevel worldserver, BlockPos blockposition, ItemStack itemstack, boolean flag) {
+ if (isSilkTouch(worldserver, itemstack)) return 0; // Purpur
if (flag) {
int i = 15 + worldserver.random.nextInt(15) + worldserver.random.nextInt(15);
diff --git a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
index 70f53ccb22de2c05c9ead68f8bd29d0b69d0993f..d4bca5b5f3d10c3a04befd8c365f46433491f299 100644
--- a/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
+++ b/src/main/java/org/purpurmc/purpur/PurpurWorldConfig.java
@@ -108,6 +108,38 @@ public class PurpurWorldConfig {
idleTimeoutTargetPlayer = getBoolean("gameplay-mechanics.player.idle-timeout.mobs-target", idleTimeoutTargetPlayer);
}
+ public boolean silkTouchEnabled = false;
+ public String silkTouchSpawnerName = "<reset><white>Monster Spawner";
+ public List<String> silkTouchSpawnerLore = new ArrayList<>();
+ public List<Item> silkTouchTools = new ArrayList<>();
+ public int minimumSilkTouchSpawnerRequire = 1;
+ private void silkTouchSettings() {
+ if (PurpurConfig.version < 21) {
+ String oldName = getString("gameplay-mechanics.silk-touch.spawner-name", silkTouchSpawnerName);
+ set("gameplay-mechanics.silk-touch.spawner-name", "<reset>" + ChatColor.toMM(oldName.replace("{mob}", "<mob>")));
+ List<String> list = new ArrayList<>();
+ getList("gameplay-mechanics.silk-touch.spawner-lore", List.of("Spawns a <mob>"))
+ .forEach(line -> list.add("<reset>" + ChatColor.toMM(line.toString().replace("{mob}", "<mob>"))));
+ set("gameplay-mechanics.silk-touch.spawner-lore", list);
+ }
+ 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", List.of("Spawns a <mob>"))
+ .forEach(line -> silkTouchSpawnerLore.add(line.toString()));
+ silkTouchTools.clear();
+ getList("gameplay-mechanics.silk-touch.tools", List.of(
+ "minecraft:iron_pickaxe",
+ "minecraft:golden_pickaxe",
+ "minecraft:diamond_pickaxe",
+ "minecraft:netherite_pickaxe"
+ )).forEach(key -> {
+ Item item = BuiltInRegistries.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/org/purpurmc/purpur/item/SpawnerItem.java b/src/main/java/org/purpurmc/purpur/item/SpawnerItem.java
new file mode 100644
index 0000000000000000000000000000000000000000..d6cc7e434cb2bacc00e4cad9e1f4be7fcf5d0bee
--- /dev/null
+++ b/src/main/java/org/purpurmc/purpur/item/SpawnerItem.java
@@ -0,0 +1,38 @@
+package org.purpurmc.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, level, level.random, pos));
+ } else if (tag.contains("BlockEntityTag")) {
+ spawner.load(tag.getCompound("BlockEntityTag"));
+ }
+ }
+ }
+ return handled;
+ }
+}