Skip to content

Commit 091a022

Browse files
committed
Synchronize enchanting table pickup animation
1 parent c96e166 commit 091a022

1 file changed

Lines changed: 46 additions & 5 deletions

File tree

common/src/main/java/com/loohp/interactionvisualizer/objectholders/EnchantmentTableAnimation.java

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)