@@ -67,6 +67,9 @@ public class EnchantmentTableAnimation {
6767 public static final int PLAY_PICKUP = 2 ;
6868 public static final int CLOSE_TABLE = 3 ;
6969
70+ // ClientboundTakeItemEntityPacket uses a fixed three-tick client animation.
71+ private static final int CLIENT_PICKUP_ANIMATION_TICKS = 3 ;
72+
7073 private static final Map <Block , EnchantmentTableAnimation > tables = new ConcurrentHashMap <>();
7174
7275 public static EnchantmentTableAnimation getTableAnimation (Block block , Player player ) {
@@ -88,6 +91,8 @@ public static EnchantmentTableAnimation getTableAnimation(Block block, Player pl
8891 private final Queue <Supplier <CompletableFuture <Integer >>> taskQueue ;
8992 private final AtomicBoolean enchanting ;
9093 private Optional <Item > item ;
94+ // Inventory transfer can finish while the scheduled enchant visual is still playing.
95+ private volatile PendingPickup pendingPickup ;
9196
9297 private EnchantmentTableAnimation (Block block , Player enchanter ) {
9398 this .plugin = InteractionVisualizer .plugin ;
@@ -223,13 +228,41 @@ private CompletableFuture<Integer> playEnchantAnimation(Map<Enchantment, Integer
223228 item .setGravity (false );
224229 DisplayManager .updateItem (item );
225230 item .setLocked (false );
226- future .complete (PLAY_ENCHANTMENT );
227231
228- this .enchanting .set (false );
232+ if (!playPendingPickup (future )) {
233+ this .enchanting .set (false );
234+ future .complete (PLAY_ENCHANTMENT );
235+ }
229236 }, 98 );
230237 return future ;
231238 }
232239
240+ private boolean playPendingPickup (CompletableFuture <Integer > enchantFuture ) {
241+ PendingPickup pending = pendingPickup ;
242+ pendingPickup = null ;
243+ if (pending == null ) {
244+ return false ;
245+ }
246+
247+ try {
248+ if (!pending .condition ().test (this )) {
249+ return false ;
250+ }
251+ playPickUpAnimation (pending .itemStack ()).whenComplete ((ignored , throwable ) -> {
252+ this .enchanting .set (false );
253+ if (throwable == null ) {
254+ enchantFuture .complete (PLAY_ENCHANTMENT );
255+ } else {
256+ enchantFuture .completeExceptionally (throwable );
257+ }
258+ });
259+ } catch (Throwable throwable ) {
260+ this .enchanting .set (false );
261+ enchantFuture .completeExceptionally (throwable );
262+ }
263+ return true ;
264+ }
265+
233266 private CompletableFuture <Integer > playPickUpAnimation (ItemStack itemstack ) {
234267 CompletableFuture <Integer > future = new CompletableFuture <>();
235268
@@ -238,8 +271,8 @@ private CompletableFuture<Integer> playPickUpAnimation(ItemStack itemstack) {
238271 return future ;
239272 }
240273 Item item = this .item .get ();
241- item .setLocked (true );
242274 item .setItemStack (itemstack );
275+ item .setLocked (true );
243276 if (itemstack == null || itemstack .getType ().equals (Material .AIR )) {
244277 future .complete (PLAY_PICKUP );
245278 return future ;
@@ -251,7 +284,7 @@ private CompletableFuture<Integer> playPickUpAnimation(ItemStack itemstack) {
251284 Scheduler .runTaskLater (plugin , () -> {
252285 this .item = Optional .empty ();
253286 future .complete (PLAY_PICKUP );
254- }, 8 );
287+ }, CLIENT_PICKUP_ANIMATION_TICKS );
255288 return future ;
256289 }
257290
@@ -332,9 +365,14 @@ public void queueEnchant(Map<Enchantment, Integer> enchantsToAdd, int expCost, I
332365 }
333366
334367 public void queuePickupAnimation (ItemStack itemstack , Predicate <EnchantmentTableAnimation > condition ) {
368+ ItemStack copy = itemstack == null ? null : itemstack .clone ();
369+ if (enchanting .get () && copy != null && !copy .isEmpty ()) {
370+ pendingPickup = new PendingPickup (copy , condition );
371+ return ;
372+ }
335373 taskQueue .add (() -> {
336374 if (condition .test (this )) {
337- return playPickUpAnimation (itemstack == null ? null : itemstack . clone () );
375+ return playPickUpAnimation (copy );
338376 } else {
339377 return null ;
340378 }
@@ -351,4 +389,7 @@ public void queueClose(Predicate<EnchantmentTableAnimation> condition) {
351389 });
352390 }
353391
392+ private record PendingPickup (ItemStack itemStack , Predicate <EnchantmentTableAnimation > condition ) {
393+ }
394+
354395}
0 commit comments