Mirror von
https://github.com/PaperMC/Paper.git
synchronisiert 2024-12-15 02:50:09 +01:00
105 Zeilen
8.2 KiB
Diff
105 Zeilen
8.2 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
|
Date: Mon, 12 Dec 2022 12:14:03 -0800
|
|
Subject: [PATCH] Properly track the changed item from dispense events
|
|
|
|
|
|
diff --git a/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java b/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java
|
|
index 681c38f4457fc10806c10518b16159580c0f2619..8f9b86e50717746e55232293d9e5ac05b8616aa0 100644
|
|
--- a/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java
|
|
+++ b/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java
|
|
@@ -129,10 +129,14 @@ public interface DispenseItemBehavior {
|
|
idispensebehavior.dispense(pointer, eventStack);
|
|
return stack;
|
|
}
|
|
+ // Paper start - track changed items in the dispense event
|
|
+ itemstack1 = CraftItemStack.unwrap(event.getItem()); // unwrap is safe because the stack won't be modified
|
|
+ entitytypes = ((SpawnEggItem) itemstack1.getItem()).getType(itemstack1);
|
|
+ // Paper end - track changed item from dispense event
|
|
}
|
|
|
|
try {
|
|
- entitytypes.spawn(pointer.level(), stack, (Player) null, pointer.pos().relative(enumdirection), EntitySpawnReason.DISPENSER, enumdirection != Direction.UP, false);
|
|
+ entitytypes.spawn(pointer.level(), itemstack1, (Player) null, pointer.pos().relative(enumdirection), EntitySpawnReason.DISPENSER, enumdirection != Direction.UP, false); // Paper - track changed item in dispense event
|
|
} catch (Exception exception) {
|
|
DispenseItemBehavior.LOGGER.error("Error while dispensing spawn egg from dispenser at {}", pointer.pos(), exception); // CraftBukkit - decompile error
|
|
return ItemStack.EMPTY;
|
|
@@ -186,9 +190,10 @@ public interface DispenseItemBehavior {
|
|
}
|
|
// CraftBukkit end
|
|
|
|
+ final ItemStack newStack = CraftItemStack.unwrap(event.getItem()); // Paper - use event itemstack (unwrap is fine here because the stack won't be modified)
|
|
Consumer<ArmorStand> consumer = EntityType.appendDefaultStackConfig((entityarmorstand) -> {
|
|
entityarmorstand.setYRot(enumdirection.toYRot());
|
|
- }, worldserver, stack, (Player) null);
|
|
+ }, worldserver, newStack, (Player) null); // Paper - track changed items in the dispense event
|
|
ArmorStand entityarmorstand = (ArmorStand) EntityType.ARMOR_STAND.spawn(worldserver, consumer, blockposition, EntitySpawnReason.DISPENSER, false, false);
|
|
|
|
if (entityarmorstand != null) {
|
|
@@ -237,7 +242,7 @@ public interface DispenseItemBehavior {
|
|
return stack;
|
|
}
|
|
}
|
|
- ((Saddleable) list.get(0)).equipSaddle(itemstack1, SoundSource.BLOCKS);
|
|
+ ((Saddleable) list.get(0)).equipSaddle(CraftItemStack.asNMSCopy(event.getItem()), SoundSource.BLOCKS); // Paper - track changed items in dispense event
|
|
// CraftBukkit end
|
|
this.setSuccess(true);
|
|
return stack;
|
|
@@ -330,6 +335,7 @@ public interface DispenseItemBehavior {
|
|
int y = blockposition.getY();
|
|
int z = blockposition.getZ();
|
|
BlockState iblockdata = worldserver.getBlockState(blockposition);
|
|
+ ItemStack dispensedItem = stack; // Paper - track changed item from the dispense event
|
|
// Paper start - correctly check if the bucket place will succeed
|
|
/* Taken from SolidBucketItem#emptyContents */
|
|
boolean willEmptyContentsSolidBucketItem = dispensiblecontaineritem instanceof net.minecraft.world.item.SolidBucketItem && worldserver.isInWorldBounds(blockposition) && iblockdata.isAir();
|
|
@@ -359,12 +365,15 @@ public interface DispenseItemBehavior {
|
|
}
|
|
}
|
|
|
|
- dispensiblecontaineritem = (DispensibleContainerItem) CraftItemStack.asNMSCopy(event.getItem()).getItem();
|
|
+ // Paper start - track changed item from dispense event
|
|
+ dispensedItem = CraftItemStack.unwrap(event.getItem()); // unwrap is safe here as the stack isn't mutated
|
|
+ dispensiblecontaineritem = (DispensibleContainerItem) dispensedItem.getItem();
|
|
+ // Paper end - track changed item from dispense event
|
|
}
|
|
// CraftBukkit end
|
|
|
|
if (dispensiblecontaineritem.emptyContents((Player) null, worldserver, blockposition, (BlockHitResult) null)) {
|
|
- dispensiblecontaineritem.checkExtraContent((Player) null, worldserver, stack, blockposition);
|
|
+ dispensiblecontaineritem.checkExtraContent((Player) null, worldserver, dispensedItem, blockposition); // Paper - track changed item from dispense event
|
|
return this.consumeWithRemainder(pointer, stack, new ItemStack(Items.BUCKET));
|
|
} else {
|
|
return this.defaultDispenseItemBehavior.dispense(pointer, stack);
|
|
diff --git a/src/main/java/net/minecraft/core/dispenser/ProjectileDispenseBehavior.java b/src/main/java/net/minecraft/core/dispenser/ProjectileDispenseBehavior.java
|
|
index aba0ddfc5009a11b6c5cba95a90479083643bdad..b341792b694e4d6d7ca98061976b8857d83c4233 100644
|
|
--- a/src/main/java/net/minecraft/core/dispenser/ProjectileDispenseBehavior.java
|
|
+++ b/src/main/java/net/minecraft/core/dispenser/ProjectileDispenseBehavior.java
|
|
@@ -64,7 +64,7 @@ public class ProjectileDispenseBehavior extends DefaultDispenseItemBehavior {
|
|
}
|
|
}
|
|
|
|
- Projectile iprojectile = Projectile.spawnProjectileUsingShoot(this.projectileItem.asProjectile(worldserver, iposition, stack, enumdirection), worldserver, stack, event.getVelocity().getX(), event.getVelocity().getY(), event.getVelocity().getZ(), this.dispenseConfig.power(), this.dispenseConfig.uncertainty());
|
|
+ Projectile iprojectile = Projectile.spawnProjectileUsingShoot(this.projectileItem.asProjectile(worldserver, iposition, CraftItemStack.unwrap(event.getItem()), enumdirection), worldserver, stack, event.getVelocity().getX(), event.getVelocity().getY(), event.getVelocity().getZ(), this.dispenseConfig.power(), this.dispenseConfig.uncertainty()); // Paper - track changed items in the dispense event; unwrap is safe here because all uses of the stack make their own copies
|
|
((Entity) iprojectile).projectileSource = new org.bukkit.craftbukkit.projectiles.CraftBlockProjectileSource(pointer.blockEntity());
|
|
// itemstack.shrink(1); // CraftBukkit - Handled during event processing
|
|
// CraftBukkit end
|
|
diff --git a/src/main/java/net/minecraft/core/dispenser/ShulkerBoxDispenseBehavior.java b/src/main/java/net/minecraft/core/dispenser/ShulkerBoxDispenseBehavior.java
|
|
index cc85e96035f7cb2e6493b1cc4748031171d7dbee..16b435216dc7c6a3f8c1c0f9e2323e6afb3a6cb9 100644
|
|
--- a/src/main/java/net/minecraft/core/dispenser/ShulkerBoxDispenseBehavior.java
|
|
+++ b/src/main/java/net/minecraft/core/dispenser/ShulkerBoxDispenseBehavior.java
|
|
@@ -57,7 +57,12 @@ public class ShulkerBoxDispenseBehavior extends OptionalDispenseItemBehavior {
|
|
// CraftBukkit end
|
|
|
|
try {
|
|
- this.setSuccess(((BlockItem) item).place(new DirectionalPlaceContext(pointer.level(), blockposition, enumdirection, stack, enumdirection1)).consumesAction());
|
|
+ // Paper start - track changed items in the dispense event
|
|
+ this.setSuccess(((BlockItem) item).place(new DirectionalPlaceContext(pointer.level(), blockposition, enumdirection, CraftItemStack.asNMSCopy(event.getItem()), enumdirection1)).consumesAction());
|
|
+ if (this.isSuccess()) {
|
|
+ stack.shrink(1); // vanilla shrink is in the place function above, manually handle it here
|
|
+ }
|
|
+ // Paper end - track changed items in the dispense event
|
|
} catch (Exception exception) {
|
|
ShulkerBoxDispenseBehavior.LOGGER.error("Error trying to place shulker box at {}", blockposition, exception);
|
|
}
|