prep for update

This commit is contained in:
granny
2026-03-07 14:58:41 -08:00
parent 0fbf8d2312
commit 65a7278ca8
312 changed files with 2997 additions and 814 deletions

View File

@@ -0,0 +1,78 @@
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
From: File <noreply+automated@papermc.io>
Date: Sun, 20 Apr 1997 05:37:42 -0800
Subject: [PATCH] purpur File Patches
diff --git a/net/minecraft/world/item/AxeItem.java b/net/minecraft/world/item/AxeItem.java
index 8b006edd6f766f942d691f5271a7505a75700d0c..443410efadc9b8e919a23e475ff9457b93e8f156 100644
--- a/net/minecraft/world/item/AxeItem.java
+++ b/net/minecraft/world/item/AxeItem.java
@@ -65,13 +65,15 @@ public class AxeItem extends Item {
if (playerHasBlockingItemUseIntent(context)) {
return InteractionResult.PASS;
} else {
- Optional<BlockState> optional = this.evaluateNewBlockState(level, clickedPos, player, level.getBlockState(clickedPos));
+ Optional<org.purpurmc.purpur.tool.Actionable> optional = this.evaluateActionable(level, clickedPos, player, level.getBlockState(clickedPos)); // Purpur - Tool actionable options
if (optional.isEmpty()) {
return InteractionResult.PASS;
} else {
+ org.purpurmc.purpur.tool.Actionable actionable = optional.get(); // Purpur - Tool actionable options
+ BlockState state = actionable.into().withPropertiesOf(level.getBlockState(clickedPos)); // Purpur - Tool actionable options
ItemStack itemInHand = context.getItemInHand();
// Paper start - EntityChangeBlockEvent
- if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(player, clickedPos, optional.get())) {
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(player, clickedPos, state)) { // Purpur - Tool actionable options
return InteractionResult.PASS;
}
// Paper end
@@ -79,8 +81,15 @@ public class AxeItem extends Item {
CriteriaTriggers.ITEM_USED_ON_BLOCK.trigger((ServerPlayer)player, clickedPos, itemInHand);
}
- level.setBlock(clickedPos, optional.get(), Block.UPDATE_ALL_IMMEDIATE);
- level.gameEvent(GameEvent.BLOCK_CHANGE, clickedPos, GameEvent.Context.of(player, optional.get()));
+ // Purpur start - Tool actionable options
+ level.setBlock(clickedPos, state, Block.UPDATE_ALL_IMMEDIATE);
+ actionable.drops().forEach((drop, chance) -> {
+ if (level.random.nextDouble() < chance) {
+ Block.popResourceFromFace(level, clickedPos, context.getClickedFace(), new ItemStack(drop));
+ }
+ });
+ level.gameEvent(GameEvent.BLOCK_CHANGE, clickedPos, GameEvent.Context.of(player, state));
+ // Purpur end - Tool actionable options
if (player != null) {
itemInHand.hurtAndBreak(1, player, context.getHand().asEquipmentSlot());
}
@@ -97,21 +106,23 @@ public class AxeItem extends Item {
&& !player.isSecondaryUseActive();
}
- private Optional<BlockState> evaluateNewBlockState(Level level, BlockPos pos, @Nullable Player player, BlockState state) {
- Optional<BlockState> stripped = this.getStripped(state);
+ private Optional<org.purpurmc.purpur.tool.Actionable> evaluateActionable(Level level, BlockPos pos, @Nullable Player player, BlockState state) { // Purpur - Tool actionable options
+ Optional<org.purpurmc.purpur.tool.Actionable> stripped = Optional.ofNullable(level.purpurConfig.axeStrippables.get(state.getBlock())); // Purpur - Tool actionable options
if (stripped.isPresent()) {
- level.playSound(player, pos, SoundEvents.AXE_STRIP, SoundSource.BLOCKS, 1.0F, 1.0F);
+ level.playSound(STRIPPABLES.containsKey(state.getBlock()) ? player : null, pos, SoundEvents.AXE_STRIP, SoundSource.BLOCKS, 1.0F, 1.0F); // Purpur - force sound
return stripped;
} else {
- Optional<BlockState> previous = WeatheringCopper.getPrevious(state);
+ Optional<org.purpurmc.purpur.tool.Actionable> previous = Optional.ofNullable(level.purpurConfig.axeWeatherables.get(state.getBlock())); // Purpur - Tool actionable options
if (previous.isPresent()) {
- spawnSoundAndParticle(level, pos, player, state, SoundEvents.AXE_SCRAPE, LevelEvent.PARTICLES_SCRAPE);
+ spawnSoundAndParticle(level, pos, WeatheringCopper.getPrevious(state).isPresent() ? player : null, state, SoundEvents.AXE_SCRAPE, LevelEvent.PARTICLES_SCRAPE); // Purpur - Tool actionable options - force sound
return previous;
} else {
- Optional<BlockState> optional = Optional.ofNullable(HoneycombItem.WAX_OFF_BY_BLOCK.get().get(state.getBlock()))
- .map(block -> block.withPropertiesOf(state));
+ // Purpur start - Tool actionable options
+ Optional<org.purpurmc.purpur.tool.Actionable> optional = Optional.ofNullable(level.purpurConfig.axeWaxables.get(state.getBlock()));
+ // .map(block -> block.withPropertiesOf(state));
+ // Purpur end - Tool actionable options
if (optional.isPresent()) {
- spawnSoundAndParticle(level, pos, player, state, SoundEvents.AXE_WAX_OFF, LevelEvent.PARTICLES_WAX_OFF);
+ spawnSoundAndParticle(level, pos, HoneycombItem.WAX_OFF_BY_BLOCK.get().containsKey(state.getBlock()) ? player : null, state, SoundEvents.AXE_WAX_OFF, LevelEvent.PARTICLES_WAX_OFF); // Purpur - Tool actionable options - force sound
return optional;
} else {
return Optional.empty();

View File

@@ -0,0 +1,44 @@
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
From: File <noreply+automated@papermc.io>
Date: Sun, 20 Apr 1997 05:37:42 -0800
Subject: [PATCH] purpur File Patches
diff --git a/net/minecraft/world/item/BlockItem.java b/net/minecraft/world/item/BlockItem.java
index 73ce7c82c0bd28c2e43ca40ba35c4603b21375ad..60261f504dc5669f9e2d0a2aee5dbd33c62c8893 100644
--- a/net/minecraft/world/item/BlockItem.java
+++ b/net/minecraft/world/item/BlockItem.java
@@ -143,7 +143,16 @@ public class BlockItem extends Item {
}
protected boolean updateCustomBlockEntityTag(BlockPos pos, Level level, @Nullable Player player, ItemStack stack, BlockState state) {
- return updateCustomBlockEntityTag(level, player, pos, stack);
+ // Purpur start - Persistent BlockEntity Lore and DisplayName
+ boolean handled = updateCustomBlockEntityTag(level, player, pos, stack);
+ if (level.purpurConfig.persistentTileEntityLore) {
+ BlockEntity blockEntity1 = level.getBlockEntity(pos);
+ if (blockEntity1 != null) {
+ blockEntity1.setPersistentLore(stack.getOrDefault(DataComponents.LORE, net.minecraft.world.item.component.ItemLore.EMPTY));
+ }
+ }
+ return handled;
+ // Purpur end - Persistent BlockEntity Lore and DisplayName
}
protected @Nullable BlockState getPlacementState(BlockPlaceContext context) {
@@ -204,6 +213,7 @@ public class BlockItem extends Item {
}
if (!type.onlyOpCanSetNbt() || player != null && (player.canUseGameMasterBlocks() || (player.getAbilities().instabuild && player.getBukkitEntity().hasPermission("minecraft.nbt.place")))) { // Spigot - add permission
+ if (!(level.purpurConfig.silkTouchEnabled && blockEntity instanceof net.minecraft.world.level.block.entity.SpawnerBlockEntity && player.getBukkitEntity().hasPermission("purpur.drop.spawners"))) // Purpur - Silk touch spawners
return typedEntityData.loadInto(blockEntity, level.registryAccess());
}
@@ -244,6 +254,7 @@ public class BlockItem extends Item {
public void onDestroyed(ItemEntity itemEntity) {
ItemContainerContents itemContainerContents = itemEntity.getItem().set(DataComponents.CONTAINER, ItemContainerContents.EMPTY);
if (itemContainerContents != null) {
+ if (itemEntity.level().purpurConfig.shulkerBoxItemDropContentsWhenDestroyed && this.getBlock() instanceof ShulkerBoxBlock) // Purpur - option to disable shulker box items from dropping contents when destroyed
ItemUtils.onContainerDestroyed(itemEntity, itemContainerContents.nonEmptyItemsCopy());
}
}

View File

@@ -0,0 +1,40 @@
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
From: File <noreply+automated@papermc.io>
Date: Sun, 20 Apr 1997 05:37:42 -0800
Subject: [PATCH] purpur File Patches
diff --git a/net/minecraft/world/item/BowItem.java b/net/minecraft/world/item/BowItem.java
index 616f17713c43b6b28cb58c45071f1a7a74010261..0a14a098f3aa40c8195c3a3bdf61ad6ae0fcc9d2 100644
--- a/net/minecraft/world/item/BowItem.java
+++ b/net/minecraft/world/item/BowItem.java
@@ -28,6 +28,11 @@ public class BowItem extends ProjectileWeaponItem {
return false;
} else {
ItemStack projectile = player.getProjectile(stack);
+ // Purpur start - Infinity bow settings
+ if (level.purpurConfig.infinityWorksWithoutArrows && projectile.isEmpty() && net.minecraft.world.item.enchantment.EnchantmentHelper.getItemEnchantmentLevel(net.minecraft.world.item.enchantment.Enchantments.INFINITY, stack) > 0) {
+ projectile = new ItemStack(Items.ARROW);
+ }
+ // Purpur end - Infinity bow settings
if (projectile.isEmpty()) {
return false;
} else {
@@ -38,7 +43,7 @@ public class BowItem extends ProjectileWeaponItem {
} else {
List<ItemStack> list = draw(stack, projectile, player);
if (level instanceof ServerLevel serverLevel && !list.isEmpty()) {
- this.shoot(serverLevel, player, player.getUsedItemHand(), stack, list, powerForTime * 3.0F, 1.0F, powerForTime == 1.0F, null, powerForTime); // Paper - Pass draw strength
+ this.shoot(serverLevel, player, player.getUsedItemHand(), stack, list, powerForTime * 3.0F, (float) serverLevel.purpurConfig.bowProjectileOffset, powerForTime == 1.0F, null, powerForTime); // Paper - Pass draw strength // Purpur - Projectile offset config
}
level.playSound(
@@ -89,7 +94,7 @@ public class BowItem extends ProjectileWeaponItem {
public InteractionResult use(Level level, Player player, InteractionHand hand) {
ItemStack itemInHand = player.getItemInHand(hand);
boolean flag = !player.getProjectile(itemInHand).isEmpty();
- if (!player.hasInfiniteMaterials() && !flag) {
+ if (!player.hasInfiniteMaterials() && !flag && !(level.purpurConfig.infinityWorksWithoutArrows && net.minecraft.world.item.enchantment.EnchantmentHelper.getItemEnchantmentLevel(net.minecraft.world.item.enchantment.Enchantments.INFINITY, itemInHand) > 0)) { // Purpur - Infinity bow settings
return InteractionResult.FAIL;
} else {
player.startUsingItem(hand);

View File

@@ -0,0 +1,19 @@
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
From: File <noreply+automated@papermc.io>
Date: Sun, 20 Apr 1997 05:37:42 -0800
Subject: [PATCH] purpur File Patches
diff --git a/net/minecraft/world/item/BucketItem.java b/net/minecraft/world/item/BucketItem.java
index 9d6485148393292006ed4453e0ed228b6197b239..0ffdbcd75fa57feb2ada835c0189246821d279d1 100644
--- a/net/minecraft/world/item/BucketItem.java
+++ b/net/minecraft/world/item/BucketItem.java
@@ -148,7 +148,7 @@ public class BucketItem extends Item implements DispensibleContainerItem {
// CraftBukkit end
if (!flag2) {
return hitResult != null && this.emptyContents(entity, level, hitResult.getBlockPos().relative(hitResult.getDirection()), null, direction, clicked, itemstack, hand); // CraftBukkit
- } else if (level.environmentAttributes().getValue(EnvironmentAttributes.WATER_EVAPORATES, pos) && this.content.is(FluidTags.WATER)) {
+ } else if ((level.environmentAttributes().getValue(EnvironmentAttributes.WATER_EVAPORATES, pos) || (level.isTheEnd() && !org.purpurmc.purpur.PurpurConfig.allowWaterPlacementInTheEnd)) && this.content.is(FluidTags.WATER)) { // Purpur - Add allow water in end world option
int x = pos.getX();
int y = pos.getY();
int z = pos.getZ();

View File

@@ -0,0 +1,19 @@
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
From: File <noreply+automated@papermc.io>
Date: Sun, 20 Apr 1997 05:37:42 -0800
Subject: [PATCH] purpur File Patches
diff --git a/net/minecraft/world/item/CrossbowItem.java b/net/minecraft/world/item/CrossbowItem.java
index 664e633f6d93c1569895f9cccb90e3bc8922e56d..a29ff7584371d35d9b0fff71681f672b76dea07c 100644
--- a/net/minecraft/world/item/CrossbowItem.java
+++ b/net/minecraft/world/item/CrossbowItem.java
@@ -66,7 +66,7 @@ public class CrossbowItem extends ProjectileWeaponItem {
ItemStack itemInHand = player.getItemInHand(hand);
ChargedProjectiles chargedProjectiles = itemInHand.get(DataComponents.CHARGED_PROJECTILES);
if (chargedProjectiles != null && !chargedProjectiles.isEmpty()) {
- this.performShooting(level, player, hand, itemInHand, getShootingPower(chargedProjectiles), 1.0F, null);
+ this.performShooting(level, player, hand, itemInHand, getShootingPower(chargedProjectiles), (float) level.purpurConfig.crossbowProjectileOffset, null); // Purpur - Projectile offset config
return InteractionResult.CONSUME;
} else if (!player.getProjectile(itemInHand).isEmpty()) {
this.startSoundPlayed = false;

View File

@@ -0,0 +1,21 @@
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
From: File <noreply+automated@papermc.io>
Date: Sun, 20 Apr 1997 05:37:42 -0800
Subject: [PATCH] purpur File Patches
diff --git a/net/minecraft/world/item/DyeColor.java b/net/minecraft/world/item/DyeColor.java
index 083ec53b1e46b8ad23db7e57296c222ad4c3cd4b..f2e761f253969ca01b78c7ddc7a571ecc9655432 100644
--- a/net/minecraft/world/item/DyeColor.java
+++ b/net/minecraft/world/item/DyeColor.java
@@ -124,4 +124,10 @@ public enum DyeColor implements StringRepresentable {
private static CraftingInput makeCraftColorInput(DyeColor first, DyeColor second) {
return CraftingInput.of(2, 1, List.of(new ItemStack(DyeItem.byColor(first)), new ItemStack(DyeItem.byColor(second))));
}
+
+ // Purpur start - Shulker spawn from bullet options
+ public static DyeColor random(net.minecraft.util.RandomSource random) {
+ return values()[random.nextInt(values().length)];
+ }
+ // Purpur end - Shulker spawn from bullet options
}

View File

@@ -0,0 +1,19 @@
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
From: File <noreply+automated@papermc.io>
Date: Sun, 20 Apr 1997 05:37:42 -0800
Subject: [PATCH] purpur File Patches
diff --git a/net/minecraft/world/item/EggItem.java b/net/minecraft/world/item/EggItem.java
index 848144ce792de422921242282cefb2077a56563d..654d67dfc38b872352ea1cb6314f989c464a4ce1 100644
--- a/net/minecraft/world/item/EggItem.java
+++ b/net/minecraft/world/item/EggItem.java
@@ -24,7 +24,7 @@ public class EggItem extends Item implements ProjectileItem {
public InteractionResult use(Level level, Player player, InteractionHand hand) {
ItemStack itemInHand = player.getItemInHand(hand);
// Paper start
- final Projectile.Delayed<ThrownEgg> thrownEgg = Projectile.spawnProjectileFromRotationDelayed(ThrownEgg::new, (ServerLevel) level, itemInHand, player, 0.0F, EggItem.PROJECTILE_SHOOT_POWER, 1.0F);
+ final Projectile.Delayed<ThrownEgg> thrownEgg = Projectile.spawnProjectileFromRotationDelayed(ThrownEgg::new, (ServerLevel) level, itemInHand, player, 0.0F, EggItem.PROJECTILE_SHOOT_POWER, (float) level.purpurConfig.eggProjectileOffset); // Purpur - Projectile offset config
com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) player.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemInHand), (org.bukkit.entity.Projectile) thrownEgg.projectile().getBukkitEntity());
if (event.callEvent() && thrownEgg.attemptSpawn()) {
if (event.shouldConsume()) {

View File

@@ -0,0 +1,19 @@
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
From: File <noreply+automated@papermc.io>
Date: Sun, 20 Apr 1997 05:37:42 -0800
Subject: [PATCH] purpur File Patches
diff --git a/net/minecraft/world/item/EndCrystalItem.java b/net/minecraft/world/item/EndCrystalItem.java
index 05ec512839898f96d9769bb0d00f6ba11dda0c4b..6e4a3c9c090a68bf5785a01d815c275411859c7b 100644
--- a/net/minecraft/world/item/EndCrystalItem.java
+++ b/net/minecraft/world/item/EndCrystalItem.java
@@ -24,7 +24,7 @@ public class EndCrystalItem extends Item {
Level level = context.getLevel();
BlockPos clickedPos = context.getClickedPos();
BlockState blockState = level.getBlockState(clickedPos);
- if (!blockState.is(Blocks.OBSIDIAN) && !blockState.is(Blocks.BEDROCK)) {
+ if (!level.purpurConfig.endCrystalPlaceAnywhere && !blockState.is(Blocks.OBSIDIAN) && !blockState.is(Blocks.BEDROCK)) { // Purpur - place end crystal on any block
return InteractionResult.FAIL;
} else {
BlockPos blockPos = clickedPos.above(); final BlockPos aboveBlockPos = blockPos; // Paper - OBFHELPER

View File

@@ -0,0 +1,27 @@
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
From: File <noreply+automated@papermc.io>
Date: Sun, 20 Apr 1997 05:37:42 -0800
Subject: [PATCH] purpur File Patches
diff --git a/net/minecraft/world/item/EnderpearlItem.java b/net/minecraft/world/item/EnderpearlItem.java
index 7f1bc41d2ad20f2d96397e6e2eaedc4bbe5a7ba1..647f2fb76b1e1d8ca5046348b216a8ca0fa02de9 100644
--- a/net/minecraft/world/item/EnderpearlItem.java
+++ b/net/minecraft/world/item/EnderpearlItem.java
@@ -24,7 +24,7 @@ public class EnderpearlItem extends Item {
if (level instanceof ServerLevel serverLevel) {
// CraftBukkit start
// Paper start - PlayerLaunchProjectileEvent
- final Projectile.Delayed<ThrownEnderpearl> thrownEnderpearl = Projectile.spawnProjectileFromRotationDelayed(ThrownEnderpearl::new, serverLevel, itemInHand, player, 0.0F, EnderpearlItem.PROJECTILE_SHOOT_POWER, 1.0F);
+ final Projectile.Delayed<ThrownEnderpearl> thrownEnderpearl = Projectile.spawnProjectileFromRotationDelayed(ThrownEnderpearl::new, serverLevel, itemInHand, player, 0.0F, EnderpearlItem.PROJECTILE_SHOOT_POWER, (float) serverLevel.purpurConfig.enderPearlProjectileOffset); // Purpur - Projectile offset config
com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) player.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemInHand), (org.bukkit.entity.Projectile) thrownEnderpearl.projectile().getBukkitEntity());
if (event.callEvent() && thrownEnderpearl.attemptSpawn()) {
if (event.shouldConsume()) {
@@ -44,6 +44,7 @@ public class EnderpearlItem extends Item {
0.4F / (level.getRandom().nextFloat() * 0.4F + 0.8F)
);
player.awardStat(Stats.ITEM_USED.get(this));
+ player.getCooldowns().addCooldown(itemInHand, player.getAbilities().instabuild ? level.purpurConfig.enderPearlCooldownCreative : level.purpurConfig.enderPearlCooldown); // Purpur - Configurable Ender Pearl cooldown
} else {
if (player instanceof net.minecraft.server.level.ServerPlayer serverPlayer) {
serverPlayer.deregisterEnderPearl(thrownEnderpearl.projectile());

View File

@@ -0,0 +1,41 @@
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
From: File <noreply+automated@papermc.io>
Date: Sun, 20 Apr 1997 05:37:42 -0800
Subject: [PATCH] purpur File Patches
diff --git a/net/minecraft/world/item/HoeItem.java b/net/minecraft/world/item/HoeItem.java
index d9d03bfcb1cb10aa03b35255c4237760bc836752..bf14cbcc6ed4c89ef6f15b3cb248a599cbc26e29 100644
--- a/net/minecraft/world/item/HoeItem.java
+++ b/net/minecraft/world/item/HoeItem.java
@@ -44,15 +44,25 @@ public class HoeItem extends Item {
public InteractionResult useOn(UseOnContext context) {
Level level = context.getLevel();
BlockPos clickedPos = context.getClickedPos();
- Pair<Predicate<UseOnContext>, Consumer<UseOnContext>> pair = TILLABLES.get(level.getBlockState(clickedPos).getBlock());
- if (pair == null) {
+ // Purpur start - Tool actionable options
+ Block clickedBlock = level.getBlockState(clickedPos).getBlock();
+ org.purpurmc.purpur.tool.Tillable tillable = level.purpurConfig.hoeTillables.get(clickedBlock);
+ if (tillable == null) {
return InteractionResult.PASS;
} else {
- Predicate<UseOnContext> predicate = pair.getFirst();
- Consumer<UseOnContext> consumer = pair.getSecond();
+ Predicate<UseOnContext> predicate = tillable.condition().predicate();
+ Consumer<UseOnContext> consumer = (ctx) -> {
+ level.setBlock(clickedPos, tillable.into().defaultBlockState(), 11);
+ tillable.drops().forEach((drop, chance) -> {
+ if (level.random.nextDouble() < chance) {
+ Block.popResourceFromFace(level, clickedPos, ctx.getClickedFace(), new ItemStack(drop));
+ }
+ });
+ };
+ // Purpur end - Tool actionable options
if (predicate.test(context)) {
Player player = context.getPlayer();
- level.playSound(player, clickedPos, SoundEvents.HOE_TILL, SoundSource.BLOCKS, 1.0F, 1.0F);
+ if (!TILLABLES.containsKey(clickedBlock)) level.playSound(null, clickedPos, SoundEvents.HOE_TILL, SoundSource.BLOCKS, 1.0F, 1.0F); // Purpur - Tool actionable options - force sound
if (!level.isClientSide()) {
consumer.accept(context);
if (player != null) {

View File

@@ -0,0 +1,66 @@
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
From: File <noreply+automated@papermc.io>
Date: Sun, 20 Apr 1997 05:37:42 -0800
Subject: [PATCH] purpur File Patches
diff --git a/net/minecraft/world/item/ItemStack.java b/net/minecraft/world/item/ItemStack.java
index ed06cffe8a5eba2ca4a34ade81f8185e21d7b651..e38ed1b4f9cfa104da317e80d615b38d5121ea97 100644
--- a/net/minecraft/world/item/ItemStack.java
+++ b/net/minecraft/world/item/ItemStack.java
@@ -456,6 +456,7 @@ public final class ItemStack implements DataComponentHolder {
// revert back all captured blocks
for (org.bukkit.block.BlockState blockstate : blocks) {
((org.bukkit.craftbukkit.block.CraftBlockState) blockstate).revertPlace();
+ ((org.bukkit.craftbukkit.block.CraftBlock) blockstate.getBlock()).getNMS().getBlock().forgetPlacer(); // Purpur - Store placer on Block when placed
}
SignItem.openSign = null; // SPIGOT-6758 - Reset on early return
@@ -479,6 +480,7 @@ public final class ItemStack implements DataComponentHolder {
if (!(block.getBlock() instanceof net.minecraft.world.level.block.BaseEntityBlock)) { // Containers get placed automatically
block.onPlace(serverLevel, newPos, oldBlock, true, context);
}
+ block.getBlock().forgetPlacer(); // Purpur - Store placer on Block when placed
serverLevel.notifyAndUpdatePhysics(newPos, null, oldBlock, block, serverLevel.getBlockState(newPos), updateFlags, net.minecraft.world.level.block.Block.UPDATE_LIMIT); // send null chunk as chunk.k() returns false by this point
}
@@ -599,6 +601,26 @@ public final class ItemStack implements DataComponentHolder {
return this.isDamageableItem() && this.getDamageValue() > 0;
}
+ // Purpur start - Add option to mend the most damaged equipment first
+ public float getDamagePercent() {
+ if (this.has(DataComponents.UNBREAKABLE)) {
+ return 0.0F;
+ }
+
+ final int maxDamage = this.getOrDefault(DataComponents.MAX_DAMAGE, 0);
+ if (maxDamage == 0) {
+ return 0.0F;
+ }
+
+ final int damage = this.getOrDefault(DataComponents.DAMAGE, 0);
+ if (damage == 0) {
+ return 0.0F;
+ }
+
+ return (float) damage / maxDamage;
+ }
+ // Purpur end - Add option to mend the most damaged equipment first
+
public int getDamageValue() {
return Mth.clamp(this.getOrDefault(DataComponents.DAMAGE, 0), 0, this.getMaxDamage());
}
@@ -1248,6 +1270,12 @@ public final class ItemStack implements DataComponentHolder {
return !this.getOrDefault(DataComponents.ENCHANTMENTS, ItemEnchantments.EMPTY).isEmpty();
}
+ // Purpur start - Config to allow unsafe enchants
+ public boolean hasEnchantment(Holder<Enchantment> enchantment) {
+ return this.getOrDefault(DataComponents.ENCHANTMENTS, ItemEnchantments.EMPTY).getLevel(enchantment) > 0;
+ }
+ // Purpur end - Config to allow unsafe enchants
+
public ItemEnchantments getEnchantments() {
return this.getOrDefault(DataComponents.ENCHANTMENTS, ItemEnchantments.EMPTY);
}

View File

@@ -0,0 +1,28 @@
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
From: File <noreply+automated@papermc.io>
Date: Sun, 20 Apr 1997 05:37:42 -0800
Subject: [PATCH] purpur File Patches
diff --git a/net/minecraft/world/item/Items.java b/net/minecraft/world/item/Items.java
index 3e0ae17bf7129aa62765be453edba1bdd50324ab..310e61a9bbece157d81095130ecb3131deef9288 100644
--- a/net/minecraft/world/item/Items.java
+++ b/net/minecraft/world/item/Items.java
@@ -420,7 +420,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(Blocks.SPAWNER, org.purpurmc.purpur.item.SpawnerItem::new, new Item.Properties().rarity(Rarity.EPIC)); // Purpur - Silk touch spawners
public static final Item CREAKING_HEART = registerBlock(Blocks.CREAKING_HEART);
public static final Item CHEST = registerBlock(Blocks.CHEST, properties -> properties.component(DataComponents.CONTAINER, ItemContainerContents.EMPTY));
public static final Item CRAFTING_TABLE = registerBlock(Blocks.CRAFTING_TABLE);
@@ -2169,7 +2169,7 @@ public class Items {
"sweet_berries", createBlockItemWithCustomItemName(Blocks.SWEET_BERRY_BUSH), new Item.Properties().food(Foods.SWEET_BERRIES)
);
public static final Item GLOW_BERRIES = registerItem(
- "glow_berries", createBlockItemWithCustomItemName(Blocks.CAVE_VINES), new Item.Properties().food(Foods.GLOW_BERRIES)
+ "glow_berries", settings -> new org.purpurmc.purpur.item.GlowBerryItem(Blocks.CAVE_VINES, settings.useItemDescriptionPrefix()), new Item.Properties().food(Foods.GLOW_BERRIES) // Purpur - Eating glow berries adds glow effect
);
public static final Item CAMPFIRE = registerBlock(
Blocks.CAMPFIRE, properties -> properties.component(DataComponents.CONTAINER, ItemContainerContents.EMPTY)

View File

@@ -0,0 +1,18 @@
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
From: File <noreply+automated@papermc.io>
Date: Sun, 20 Apr 1997 05:37:42 -0800
Subject: [PATCH] purpur File Patches
diff --git a/net/minecraft/world/item/MapItem.java b/net/minecraft/world/item/MapItem.java
index 8479f971afdcae0143bbec25ab258485e49722af..63c9805a2c2c8ac8fff4e322e1627880c3fabd83 100644
--- a/net/minecraft/world/item/MapItem.java
+++ b/net/minecraft/world/item/MapItem.java
@@ -192,6 +192,7 @@ public class MapItem extends Item {
public static void renderBiomePreviewMap(ServerLevel level, ItemStack stack) {
MapItemSavedData savedData = getSavedData(stack, level);
if (savedData != null) {
+ savedData.isExplorerMap = true; // Purpur - Explorer Map API
if (level.dimension() == savedData.dimension) {
int i = 1 << savedData.scale;
int i1 = savedData.centerX;

View File

@@ -0,0 +1,18 @@
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
From: File <noreply+automated@papermc.io>
Date: Sun, 20 Apr 1997 05:37:42 -0800
Subject: [PATCH] purpur File Patches
diff --git a/net/minecraft/world/item/NameTagItem.java b/net/minecraft/world/item/NameTagItem.java
index 24bf4cd320c67b852d3905c50740c8006592bd68..7ee4bd968a43123e21e65f77f30495e65146aca5 100644
--- a/net/minecraft/world/item/NameTagItem.java
+++ b/net/minecraft/world/item/NameTagItem.java
@@ -24,6 +24,7 @@ public class NameTagItem extends Item {
LivingEntity newEntity = ((org.bukkit.craftbukkit.entity.CraftLivingEntity) event.getEntity()).getHandle();
newEntity.setCustomName(event.getName() != null ? io.papermc.paper.adventure.PaperAdventure.asVanilla(event.getName()) : null);
+ if (player.level().purpurConfig.armorstandFixNametags && target instanceof net.minecraft.world.entity.decoration.ArmorStand) target.setCustomNameVisible(true); // Purpur - Set name visible when using a Name Tag on an Armor Stand
if (event.isPersistent() && newEntity instanceof Mob mob) {
// Paper end - Add PlayerNameEntityEvent
mob.setPersistenceRequired();

View File

@@ -0,0 +1,19 @@
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
From: File <noreply+automated@papermc.io>
Date: Sun, 20 Apr 1997 05:37:42 -0800
Subject: [PATCH] purpur File Patches
diff --git a/net/minecraft/world/item/ProjectileWeaponItem.java b/net/minecraft/world/item/ProjectileWeaponItem.java
index ba93379b6e85bed3eedc4869b83b3d45aa770cce..8fb0eacdf739e5559fb725571fb3a65fb6b17e8a 100644
--- a/net/minecraft/world/item/ProjectileWeaponItem.java
+++ b/net/minecraft/world/item/ProjectileWeaponItem.java
@@ -106,6 +106,8 @@ public abstract class ProjectileWeaponItem extends Item {
abstractArrow.setCritArrow(true);
}
+ abstractArrow.setActualEnchantments(weapon.getEnchantments()); // Purpur - Add an option to fix MC-3304 projectile looting
+
return abstractArrow;
}

View File

@@ -0,0 +1,25 @@
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
From: File <noreply+automated@papermc.io>
Date: Sun, 20 Apr 1997 05:37:42 -0800
Subject: [PATCH] purpur File Patches
diff --git a/net/minecraft/world/item/ShovelItem.java b/net/minecraft/world/item/ShovelItem.java
index ba0609f4d9166e66599f9d4430885ab03d53ef41..7910c96cc47985acc8b64ba376933c84c51022d4 100644
--- a/net/minecraft/world/item/ShovelItem.java
+++ b/net/minecraft/world/item/ShovelItem.java
@@ -46,9 +46,12 @@ public class ShovelItem extends Item {
BlockState blockState1 = FLATTENABLES.get(blockState.getBlock());
BlockState blockState2 = null;
Runnable afterAction = null; // Paper
+ org.purpurmc.purpur.tool.Flattenable flattenable = level.purpurConfig.shovelFlattenables.get(blockState.getBlock()); // Purpur - Tool actionable options
if (blockState1 != null && level.getBlockState(clickedPos.above()).isAir()) {
- afterAction = () -> level.playSound(player, clickedPos, SoundEvents.SHOVEL_FLATTEN, SoundSource.BLOCKS, 1.0F, 1.0F); // Paper
- blockState2 = blockState1;
+ // Purpur start - Tool actionable options
+ afterAction = () -> {if (!FLATTENABLES.containsKey(blockState.getBlock())) level.playSound(player, clickedPos, SoundEvents.SHOVEL_FLATTEN, SoundSource.BLOCKS, 1.0F, 1.0F);}; // Paper
+ blockState2 = flattenable.into().defaultBlockState();
+ // Purpur end - Tool actionable options
} else if (blockState.getBlock() instanceof CampfireBlock && blockState.getValue(CampfireBlock.LIT)) {
afterAction = () -> { // Paper
if (!level.isClientSide()) {

View File

@@ -0,0 +1,19 @@
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
From: File <noreply+automated@papermc.io>
Date: Sun, 20 Apr 1997 05:37:42 -0800
Subject: [PATCH] purpur File Patches
diff --git a/net/minecraft/world/item/SnowballItem.java b/net/minecraft/world/item/SnowballItem.java
index a5bfd497a07f2e2311db8eca5b8ba8af9f4d1080..67145fd5adc5ebb38efb978119ba1f7e4f2c563f 100644
--- a/net/minecraft/world/item/SnowballItem.java
+++ b/net/minecraft/world/item/SnowballItem.java
@@ -26,7 +26,7 @@ public class SnowballItem extends Item implements ProjectileItem {
// CraftBukkit start - moved down
if (level instanceof ServerLevel serverLevel) {
// Paper start - PlayerLaunchProjectileEvent
- final Projectile.Delayed<Snowball> snowball = Projectile.spawnProjectileFromRotationDelayed(Snowball::new, serverLevel, itemInHand, player, 0.0F, SnowballItem.PROJECTILE_SHOOT_POWER, 1.0F);
+ final Projectile.Delayed<Snowball> snowball = Projectile.spawnProjectileFromRotationDelayed(Snowball::new, serverLevel, itemInHand, player, 0.0F, SnowballItem.PROJECTILE_SHOOT_POWER, (float) serverLevel.purpurConfig.snowballProjectileOffset); // Purpur - Projectile offset config
com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) player.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemInHand), (org.bukkit.entity.Projectile) snowball.projectile().getBukkitEntity());
if (event.callEvent() && snowball.attemptSpawn()) {
player.awardStat(Stats.ITEM_USED.get(this));

View File

@@ -0,0 +1,34 @@
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
From: File <noreply+automated@papermc.io>
Date: Sun, 20 Apr 1997 05:37:42 -0800
Subject: [PATCH] purpur File Patches
diff --git a/net/minecraft/world/item/SpawnEggItem.java b/net/minecraft/world/item/SpawnEggItem.java
index 079cccadfca55cd718bf75b244901f774c818811..8ab8f00995136c81abf7855e02b186a3df9a02d9 100644
--- a/net/minecraft/world/item/SpawnEggItem.java
+++ b/net/minecraft/world/item/SpawnEggItem.java
@@ -70,6 +70,23 @@ public class SpawnEggItem extends Item {
return InteractionResult.FAIL;
} else {
if (level.paperConfig().entities.spawning.disableMobSpawnerSpawnEggTransformation) return InteractionResult.FAIL; // Paper - Allow disabling mob spawner spawn egg transformation
+ // Purpur start - PlayerSetSpawnerTypeWithEggEvent
+ if (spawner instanceof net.minecraft.world.level.block.entity.SpawnerBlockEntity) {
+ org.bukkit.block.Block bukkitBlock = level.getWorld().getBlockAt(clickedPos.getX(), clickedPos.getY(), clickedPos.getZ());
+ org.purpurmc.purpur.event.PlayerSetSpawnerTypeWithEggEvent event = new org.purpurmc.purpur.event.PlayerSetSpawnerTypeWithEggEvent((org.bukkit.entity.Player) context.getPlayer().getBukkitEntity(), bukkitBlock, (org.bukkit.block.CreatureSpawner) bukkitBlock.getState(), org.bukkit.entity.EntityType.fromName(type.getName()));
+ if (!event.callEvent()) {
+ return InteractionResult.FAIL;
+ }
+ type = EntityType.getFromBukkitType(event.getEntityType());
+ } else if (spawner instanceof net.minecraft.world.level.block.entity.TrialSpawnerBlockEntity) {
+ org.bukkit.block.Block bukkitBlock = level.getWorld().getBlockAt(clickedPos.getX(), clickedPos.getY(), clickedPos.getZ());
+ org.purpurmc.purpur.event.PlayerSetTrialSpawnerTypeWithEggEvent event = new org.purpurmc.purpur.event.PlayerSetTrialSpawnerTypeWithEggEvent((org.bukkit.entity.Player) context.getPlayer().getBukkitEntity(), bukkitBlock, (org.bukkit.block.TrialSpawner) bukkitBlock.getState(), org.bukkit.entity.EntityType.fromName(type.getName()));
+ if (!event.callEvent()) {
+ return InteractionResult.FAIL;
+ }
+ type = EntityType.getFromBukkitType(event.getEntityType());
+ }
+ // Purpur end - PlayerSetSpawnerTypeWithEggEvent
spawner.setEntityId(type, level.getRandom());
level.sendBlockUpdated(clickedPos, blockState, blockState, Block.UPDATE_ALL);
level.gameEvent(context.getPlayer(), GameEvent.BLOCK_CHANGE, clickedPos);

View File

@@ -0,0 +1,19 @@
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
From: File <noreply+automated@papermc.io>
Date: Sun, 20 Apr 1997 05:37:42 -0800
Subject: [PATCH] purpur File Patches
diff --git a/net/minecraft/world/item/ThrowablePotionItem.java b/net/minecraft/world/item/ThrowablePotionItem.java
index 2707c2e3c6e32bb7c497808dceb34690e27a567a..a9bce92803772c1d76e1c3eabe1147d4c5211440 100644
--- a/net/minecraft/world/item/ThrowablePotionItem.java
+++ b/net/minecraft/world/item/ThrowablePotionItem.java
@@ -24,7 +24,7 @@ public abstract class ThrowablePotionItem extends PotionItem implements Projecti
ItemStack itemInHand = player.getItemInHand(hand);
if (level instanceof ServerLevel serverLevel) {
// Paper start - PlayerLaunchProjectileEvent
- final Projectile.Delayed<AbstractThrownPotion> thrownPotion = Projectile.spawnProjectileFromRotationDelayed(this::createPotion, serverLevel, itemInHand, player, -20.0F, PROJECTILE_SHOOT_POWER, 1.0F);
+ final Projectile.Delayed<AbstractThrownPotion> thrownPotion = Projectile.spawnProjectileFromRotationDelayed(this::createPotion, serverLevel, itemInHand, player, -20.0F, PROJECTILE_SHOOT_POWER, (float) serverLevel.purpurConfig.throwablePotionProjectileOffset); // Purpur - Projectile offset config
com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) player.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemInHand), (org.bukkit.entity.Projectile) thrownPotion.projectile().getBukkitEntity());
if (event.callEvent() && thrownPotion.attemptSpawn()) {
if (event.shouldConsume()) {

View File

@@ -0,0 +1,27 @@
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
From: File <noreply+automated@papermc.io>
Date: Sun, 20 Apr 1997 05:37:42 -0800
Subject: [PATCH] purpur File Patches
diff --git a/net/minecraft/world/item/TridentItem.java b/net/minecraft/world/item/TridentItem.java
index d029fda2e8bac95fb75f75666a55b0c3aa3bb12d..8330421fc79e63bbcec276c659cd76cad38e36eb 100644
--- a/net/minecraft/world/item/TridentItem.java
+++ b/net/minecraft/world/item/TridentItem.java
@@ -83,7 +83,7 @@ public class TridentItem extends Item implements ProjectileItem {
if (tridentSpinAttackStrength == 0.0F) {
ItemStack itemStack = stack.copyWithCount(1); // Paper
Projectile.Delayed<ThrownTrident> tridentDelayed = Projectile.spawnProjectileFromRotationDelayed( // Paper - PlayerLaunchProjectileEvent(
- ThrownTrident::new, serverLevel, itemStack, player, 0.0F, 2.5F, 1.0F
+ ThrownTrident::new, serverLevel, itemStack, player, 0.0F, 2.5F, (float) serverLevel.purpurConfig.tridentProjectileOffset // Purpur - Projectile offset config
);
// Paper start - PlayerLaunchProjectileEvent
com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) player.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(stack), (org.bukkit.entity.Projectile) tridentDelayed.projectile().getBukkitEntity());
@@ -93,6 +93,7 @@ public class TridentItem extends Item implements ProjectileItem {
return false;
}
ThrownTrident thrownTrident = tridentDelayed.projectile(); // Paper - PlayerLaunchProjectileEvent
+ thrownTrident.setActualEnchantments(stack.getEnchantments()); // Purpur - Add an option to fix MC-3304 projectile looting
if (event.shouldConsume()) {
itemStack.hurtWithoutBreaking(1, player); // Paper - PlayerLaunchProjectileEvent - use itemStack; pickup item damage
}

View File

@@ -0,0 +1,23 @@
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
From: File <noreply+automated@papermc.io>
Date: Sun, 20 Apr 1997 05:37:42 -0800
Subject: [PATCH] purpur File Patches
diff --git a/net/minecraft/world/item/consume_effects/ClearAllStatusEffectsConsumeEffect.java b/net/minecraft/world/item/consume_effects/ClearAllStatusEffectsConsumeEffect.java
index 41e1e076a4567d3d3202cf8e426a1ebb391d85e8..2d710dd3f20cbea06c16f14a558b575b369c6ca2 100644
--- a/net/minecraft/world/item/consume_effects/ClearAllStatusEffectsConsumeEffect.java
+++ b/net/minecraft/world/item/consume_effects/ClearAllStatusEffectsConsumeEffect.java
@@ -20,6 +20,12 @@ public record ClearAllStatusEffectsConsumeEffect() implements ConsumeEffect {
@Override
// CraftBukkit start
public boolean apply(Level level, ItemStack stack, LivingEntity entity, org.bukkit.event.entity.EntityPotionEffectEvent.Cause cause) {
+ // Purpur start - Option to toggle milk curing bad omen
+ net.minecraft.world.effect.MobEffectInstance badOmen = entity.getEffect(net.minecraft.world.effect.MobEffects.BAD_OMEN);
+ if (!level.purpurConfig.milkCuresBadOmen && stack.is(net.minecraft.world.item.Items.MILK_BUCKET) && badOmen != null) {
+ return entity.removeAllEffects(cause) && entity.addEffect(badOmen);
+ }
+ // Purpur end - Option to toggle milk curing bad omen
return entity.removeAllEffects(cause);
// CraftBukkit end
}

View File

@@ -0,0 +1,30 @@
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
From: File <noreply+automated@papermc.io>
Date: Sun, 20 Apr 1997 05:37:42 -0800
Subject: [PATCH] purpur File Patches
diff --git a/net/minecraft/world/item/crafting/Ingredient.java b/net/minecraft/world/item/crafting/Ingredient.java
index da95f40503f3696c8daa8fd0e947508fe43060ba..edeb3d74b0f240914b84da6dff3b057e89617a11 100644
--- a/net/minecraft/world/item/crafting/Ingredient.java
+++ b/net/minecraft/world/item/crafting/Ingredient.java
@@ -36,6 +36,7 @@ public final class Ingredient implements StackedContents.IngredientInfo<io.paper
// CraftBukkit start
@javax.annotation.Nullable
private java.util.Set<ItemStack> itemStacks; // Paper - Improve exact choice recipe ingredients
+ public Predicate<org.bukkit.inventory.ItemStack> predicate; // Purpur - Add predicate to recipe's ExactChoice ingredient
public boolean isExact() {
return this.itemStacks != null;
@@ -88,6 +89,11 @@ public final class Ingredient implements StackedContents.IngredientInfo<io.paper
return this.itemStacks.contains(stack); // Paper - Improve exact choice recipe ingredients (hashing FTW!)
}
// CraftBukkit end
+ // Purpur start - Add predicate to recipe's ExactChoice ingredient
+ if (predicate != null) {
+ return predicate.test(stack.asBukkitCopy());
+ }
+ // Purpur end - Add predicate to recipe's ExactChoice ingredient
return stack.is(this.values);
}

View File

@@ -0,0 +1,69 @@
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
From: File <noreply+automated@papermc.io>
Date: Sun, 20 Apr 1997 05:37:42 -0800
Subject: [PATCH] purpur File Patches
diff --git a/net/minecraft/world/item/enchantment/EnchantmentHelper.java b/net/minecraft/world/item/enchantment/EnchantmentHelper.java
index b61e0e179e78f37f670ad86476b5a533e7835948..d9eed93017906785716cf747317be7737bc2a38e 100644
--- a/net/minecraft/world/item/enchantment/EnchantmentHelper.java
+++ b/net/minecraft/world/item/enchantment/EnchantmentHelper.java
@@ -616,4 +616,58 @@ public class EnchantmentHelper {
interface EnchantmentVisitor {
void accept(Holder<Enchantment> enchantment, int level);
}
+
+ // Purpur start - Enchantment convenience methods
+ public static Holder.Reference<Enchantment> getEnchantmentHolder(ResourceKey<Enchantment> enchantment) {
+ return net.minecraft.server.MinecraftServer.getServer().registryAccess().lookupOrThrow(Registries.ENCHANTMENT).getOrThrow(enchantment);
+ }
+
+ public static int getItemEnchantmentLevel(ResourceKey<Enchantment> enchantment, ItemStack stack) {
+ return getItemEnchantmentLevel(getEnchantmentHolder(enchantment), stack);
+ }
+ // Purpur end - Enchantment convenience methods
+
+ // Purpur start - Add option to mend the most damaged equipment first
+ public static Optional<EnchantedItemInUse> getMostDamagedItemWith(DataComponentType<?> componentType, LivingEntity entity) {
+ ItemStack maxStack = null;
+ EquipmentSlot maxSlot = null;
+ float maxPercent = 0.0F;
+
+ equipmentSlotLoop:
+ for (EquipmentSlot equipmentSlot : EquipmentSlot.values()) {
+ ItemStack stack = entity.getItemBySlot(equipmentSlot);
+
+ // do not even check enchantments for item with lower or equal damage percent
+ float percent = stack.getDamagePercent();
+ if (percent <= maxPercent) {
+ continue;
+ }
+
+ ItemEnchantments itemEnchantments = stack.getOrDefault(DataComponents.ENCHANTMENTS, ItemEnchantments.EMPTY);
+
+ for (Entry<Holder<Enchantment>> entry : itemEnchantments.entrySet()) {
+ Enchantment enchantment = entry.getKey().value();
+
+ net.minecraft.core.component.DataComponentMap effects = enchantment.effects();
+ if (!effects.has(componentType)) {
+ // try with another enchantment
+ continue;
+ }
+
+ if (enchantment.matchingSlot(equipmentSlot)) {
+ maxStack = stack;
+ maxSlot = equipmentSlot;
+ maxPercent = percent;
+
+ // check another slot now
+ continue equipmentSlotLoop;
+ }
+ }
+ }
+
+ return maxStack != null
+ ? Optional.of(new EnchantedItemInUse(maxStack, maxSlot, entity))
+ : Optional.empty();
+ }
+ // Purpur end - Add option to mend the most damaged equipment first
}

View File

@@ -0,0 +1,44 @@
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
From: File <noreply+automated@papermc.io>
Date: Sun, 20 Apr 1997 05:37:42 -0800
Subject: [PATCH] purpur File Patches
diff --git a/net/minecraft/world/item/enchantment/ItemEnchantments.java b/net/minecraft/world/item/enchantment/ItemEnchantments.java
index 40e94e008ddf8d7670496f3f30a3e6320a11c936..b666181af7d6663f2fce58a7d9a4c805687f5409 100644
--- a/net/minecraft/world/item/enchantment/ItemEnchantments.java
+++ b/net/minecraft/world/item/enchantment/ItemEnchantments.java
@@ -32,7 +32,7 @@ public class ItemEnchantments implements TooltipProvider {
private static final java.util.Comparator<Holder<Enchantment>> ENCHANTMENT_ORDER = java.util.Comparator.comparing(Holder::getRegisteredName);
public static final ItemEnchantments EMPTY = new ItemEnchantments(new it.unimi.dsi.fastutil.objects.Object2IntAVLTreeMap<>(ENCHANTMENT_ORDER));
// Paper end - sort enchantments
- private static final Codec<Integer> LEVEL_CODEC = Codec.intRange(1, 255);
+ private static final Codec<Integer> LEVEL_CODEC = Codec.intRange(1, (org.purpurmc.purpur.PurpurConfig.clampEnchantLevels ? 255 : 32767)); // Purpur - Add toggle for enchant level clamping
public static final Codec<ItemEnchantments> CODEC = Codec.unboundedMap(Enchantment.CODEC, LEVEL_CODEC)
.xmap(
map -> new net.minecraft.world.item.enchantment.ItemEnchantments(net.minecraft.util.Util.make(new it.unimi.dsi.fastutil.objects.Object2IntAVLTreeMap<>(ENCHANTMENT_ORDER), m -> m.putAll(map))), // Paper - sort enchantments
@@ -50,7 +50,7 @@ public class ItemEnchantments implements TooltipProvider {
for (Entry<Holder<Enchantment>> entry : enchantments.object2IntEntrySet()) {
int intValue = entry.getIntValue();
- if (intValue < 0 || intValue > 255) {
+ if (intValue < 0 || intValue > (org.purpurmc.purpur.PurpurConfig.clampEnchantLevels ? 255 : 32767)) { // Purpur - Add toggle for enchant level clamping
throw new IllegalArgumentException("Enchantment " + entry.getKey() + " has invalid level " + intValue);
}
}
@@ -133,13 +133,13 @@ public class ItemEnchantments implements TooltipProvider {
if (level <= 0) {
this.enchantments.removeInt(enchantment);
} else {
- this.enchantments.put(enchantment, Math.min(level, 255));
+ this.enchantments.put(enchantment, Math.min(level, (org.purpurmc.purpur.PurpurConfig.clampEnchantLevels ? 255 : 32767))); // Purpur - Add toggle for enchant level clamping
}
}
public void upgrade(Holder<Enchantment> enchantment, int level) {
if (level > 0) {
- this.enchantments.merge(enchantment, Math.min(level, 255), Integer::max);
+ this.enchantments.merge(enchantment, Math.min(level, (org.purpurmc.purpur.PurpurConfig.clampEnchantLevels ? 255 : 32767)), Integer::max); // Purpur - Add toggle for enchant level clamping
}
}

View File

@@ -0,0 +1,25 @@
From 56a0a83ddb1b7472dbc9762e2aca396605c62085 Mon Sep 17 00:00:00 2001
From: File <noreply+automated@papermc.io>
Date: Sun, 20 Apr 1997 05:37:42 -0800
Subject: [PATCH] purpur File Patches
diff --git a/net/minecraft/world/item/trading/MerchantOffer.java b/net/minecraft/world/item/trading/MerchantOffer.java
index 6afeb92c2e00ca5b945b7c7de9257bd741d53c3d..3e2a1b3f1098bf4f45fed76b6ca4f9a3d5add6ee 100644
--- a/net/minecraft/world/item/trading/MerchantOffer.java
+++ b/net/minecraft/world/item/trading/MerchantOffer.java
@@ -143,8 +143,13 @@ public class MerchantOffer {
}
public void updateDemand() {
+ // Purpur start - Configurable minimum demand for trades
+ this.updateDemand(0);
+ }
+ public void updateDemand(int minimumDemand) {
+ // Purpur end - Configurable minimum demand for trades
this.demand = this.demand + this.uses - (this.maxUses - this.uses);
- if (io.papermc.paper.configuration.GlobalConfiguration.get().misc.preventNegativeVillagerDemand) this.demand = Math.max(0, this.demand); // Paper - Fix MC-163962
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().misc.preventNegativeVillagerDemand) this.demand = Math.max(minimumDemand, this.demand); // Paper - Fix MC-163962 // Purpur - Configurable minimum demand for trades
}
public ItemStack assemble() {