Paper/patches/server/0907-ItemStack-damage-API.patch
Emilia Kond 2d09115b3a
Use net.kyori.ansi for console logging (#9313)
Uses the new ANSIComponentSerializer introduced in Adventure 4.14.0 to
serialize components when logging them via the ComponentLogger, or when
sending messages to the console.

This replaces the old solution which uses legacy jank and custom color
conversions, with a new library that handles the conversion and config
2023-06-12 15:00:12 -07:00

71 lines
3.4 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Sun, 8 May 2022 13:35:45 -0700
Subject: [PATCH] ItemStack damage API
Adds methods notify clients about item breaks and
to simulate damage done to an itemstack and all
the logic associated with damaging them
== AT ==
public net.minecraft.world.entity.LivingEntity entityEventForEquipmentBreak(Lnet/minecraft/world/entity/EquipmentSlot;)B
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
index 351869735644c984090e1ac571b5ff118ecae9bc..56b55e9217c514fbdf44a7e2f44769ff4e8ccee1 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
@@ -996,6 +996,53 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
throw new IllegalArgumentException(entityCategory + " is an unrecognized entity category");
}
+ @Override
+ public void broadcastSlotBreak(org.bukkit.inventory.EquipmentSlot slot) {
+ this.getHandle().broadcastBreakEvent(org.bukkit.craftbukkit.CraftEquipmentSlot.getNMS(slot));
+ }
+
+ @Override
+ public void broadcastSlotBreak(org.bukkit.inventory.EquipmentSlot slot, Collection<org.bukkit.entity.Player> players) {
+ if (players.isEmpty()) {
+ return;
+ }
+ final net.minecraft.network.protocol.game.ClientboundEntityEventPacket packet = new net.minecraft.network.protocol.game.ClientboundEntityEventPacket(
+ this.getHandle(),
+ net.minecraft.world.entity.LivingEntity.entityEventForEquipmentBreak(org.bukkit.craftbukkit.CraftEquipmentSlot.getNMS(slot))
+ );
+ players.forEach(player -> ((CraftPlayer) player).getHandle().connection.send(packet));
+ }
+
+ @Override
+ public ItemStack damageItemStack(ItemStack stack, int amount) {
+ final net.minecraft.world.item.ItemStack nmsStack;
+ if (stack instanceof CraftItemStack craftItemStack) {
+ if (craftItemStack.handle == null || craftItemStack.handle.isEmpty()) {
+ return stack;
+ }
+ nmsStack = craftItemStack.handle;
+ } else {
+ nmsStack = CraftItemStack.asNMSCopy(stack);
+ stack = CraftItemStack.asCraftMirror(nmsStack); // mirror to capture changes in hurt logic & events
+ }
+ this.damageItemStack0(nmsStack, amount, null);
+ return stack;
+ }
+
+ @Override
+ public void damageItemStack(org.bukkit.inventory.EquipmentSlot slot, int amount) {
+ final net.minecraft.world.entity.EquipmentSlot nmsSlot = org.bukkit.craftbukkit.CraftEquipmentSlot.getNMS(slot);
+ this.damageItemStack0(this.getHandle().getItemBySlot(nmsSlot), amount, nmsSlot);
+ }
+
+ private void damageItemStack0(net.minecraft.world.item.ItemStack nmsStack, int amount, net.minecraft.world.entity.EquipmentSlot slot) {
+ nmsStack.hurtAndBreak(amount, this.getHandle(), livingEntity -> {
+ if (slot != null) {
+ livingEntity.broadcastBreakEvent(slot);
+ }
+ });
+ }
+
@Override
public void knockback(double strength, double directionX, double directionZ) {
Preconditions.checkArgument(strength > 0, "Knockback strength must be > 0");